# API keys and integrations

> Create and manage API keys for powerful integrations with automation platforms

Source: https://emailconnect.eu/help/api-keys-integrations/

EmailConnect's REST API enables powerful integrations with automation platforms, custom applications, and third-party services. Here's how to create and manage API keys for seamless connectivity.

## Creating API keys

### Access API settings
1. Navigate to [Settings > API Keys](https://app.emailconnect.eu/settings/api-keys)
2. Click "Create new API key"

### Configure key permissions

Scopes are strings in the form `resource:action`. A key carries a list of them, and every request is checked against the scope the endpoint requires.

**Full access (default)**
- Scope: `*`
- Access to every API endpoint
- Suitable for trusted applications
- Account, sign-in, API key management, subscriptions, payments and invoices are not part of the API: they need you to be signed in to the dashboard, and refuse every API key, full access included

**Individual scopes**

| Scope | What it allows |
|-------|----------------|
| `domains:read` | Read domain information |
| `domains:write` | Create, verify, and delete domains |
| `domains:config` | Update domain configuration (`allowAttachments`, `includeEnvelopeData` only) |
| `domains:status` | Check domain verification status |
| `domains:*` | All of the above |
| `aliases:read` | Read alias information |
| `aliases:write` | Create, update, and delete aliases |
| `aliases:*` | All of the above |
| `webhooks:read` | Read webhook information |
| `webhooks:write` | Create, update, and delete webhooks |
| `webhooks:*` | All of the above |
| `metrics:read` | Read usage metrics and statistics |
| `logs:read` | Read email processing logs |
| `logs:retry` | Retry or replay a webhook delivery |
| `emails:delete` | Delete an email record and its attachments (**Business+**) |
| `billing:read` | Read plan, billing info, usage, and limits |
| `billing:update` | Buy credits and manage auto-reload |
| `billing:*` | All of the above |
| `settings:read` | Read account settings |
| `settings:update` | Update account settings, test S3 connections |
| `settings:*` | All of the above |
| `storage:read` | Read storage connection configurations |
| `storage:write` | Create, update, delete, and test storage connections |
| `storage:*` | All of the above |

A `resource:*` wildcard covers every action on that resource. There is no `emails:*`, no `metrics:*` and no `logs:*` wildcard — list those scopes individually.

**Preset bundles**

| Preset | Scopes |
|--------|--------|
| Full access | `*` |
| Read-only | `domains:read`, `domains:status`, `aliases:read`, `webhooks:read`, `metrics:read`, `logs:read`, `billing:read`, `settings:read`, `storage:read` |
| API user | `domains:read`, `domains:status`, `domains:config`, `aliases:*`, `webhooks:*` |
| Monitoring | `metrics:read`, `logs:read`, `billing:read` |

### Generate and save
1. Choose key name (e.g., "Zapier Integration")
2. Select permissions
3. Click "Generate key"
4. **Important**: Save the key immediately - it won't be shown again

## API documentation

Access comprehensive API documentation at [emailconnect.eu/docs](https://emailconnect.eu/docs):
- Interactive API explorer
- Request/response examples
- Authentication details
- Rate limits and quotas

## Popular integrations

### Zapier
Connect EmailConnect to 5,000+ apps:
1. Create API key with full scope
2. Add EmailConnect as a Zapier app
3. Use API key for authentication
4. Build zaps to process emails

**Example Zapier workflows:**
- Email → EmailConnect → Google Sheets
- Email → EmailConnect → Slack notification
- Email → EmailConnect → CRM update

### Make (formerly Integromat)
Visual automation platform:
1. Create API key in EmailConnect
2. Add HTTP module in Make
3. Configure with EmailConnect API endpoints
4. Process emails in complex workflows

**Example Make scenarios:**
- Parse invoices and update accounting software
- Extract leads from emails to CRM
- Trigger multi-step approval workflows

### N8n (self-hosted automation)
Open-source workflow automation:
1. Install official EmailConnect n8n node
2. Create API key with required scopes
3. Configure node with your API key
4. Build automation workflows

**n8n advantages:**
- Native EmailConnect integration
- Self-hosted for data privacy
- Complex workflow capabilities
- Cost-effective for high volume

## Common API operations

Authenticate every request with the `X-API-KEY` header.

### List domains
```bash
curl https://app.emailconnect.eu/api/domains \
  -H "X-API-KEY: your-api-key-here"
```
Scope: `domains:read`

### Create a webhook

Create the webhook **first** — an alias must point at an existing webhook.

```bash
curl -X POST https://app.emailconnect.eu/api/webhooks \
  -H "X-API-KEY: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support intake",
    "url": "https://your-app.com/webhook",
    "description": "Support ticket intake",
    "generateSecret": true,
    "customHeaders": {
      "X-Custom-Header": "value"
    }
  }'
```

Required fields: `name`, `url`. Everything else is optional. `generateSecret: true` returns a `webhookSecret` in the response — it is shown only once. Custom headers go in `customHeaders` (an object of string values, max 10) and require a paid plan.

Scope: `webhooks:write`

### Create an alias

```bash
curl -X POST https://app.emailconnect.eu/api/aliases \
  -H "X-API-KEY: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "localPart": "support",
    "domainId": "dom_123",
    "webhookId": "wh_456"
  }'
```

Required fields: **`localPart`**, **`domainId`**, **`webhookId`** — all three. `localPart` is the part before the `@` (use `"*"` for a catch-all); the domain supplies the rest of the address. Optional fields include `active`, `allowAttachments`, `includeEnvelope`, `includeHtml`, `includeText`, `includeLinks`, `includeMarkdown`, `includeReplyParsing`, `attachmentHandling` (`inline` or `storage`), `s3Folder` and `storageConnectionId`.

Scope: `aliases:write`

### Get email logs
```bash
curl "https://app.emailconnect.eu/api/v1/logs?aliasId=alias_456&status=FAILED&limit=50&offset=0" \
  -H "X-API-KEY: your-api-key-here"
```

Filters: `domainId`, `aliasId`, `status` (`PENDING`, `DELIVERED`, `FAILED`, `RETRYING`, `EXPIRED`, `REJECTED`), `since`, `until`, `testWebhooksOnly`, `limit` (1-100, default 50), `offset`.

- `status=REJECTED` lists mail that was blocked by an alias rule or spam score, and deliveries your endpoint answered with 413.
- `since` and `until` take an ISO 8601 instant and filter on when the log entry was created: `since` is inclusive, `until` is exclusive. Percent-encode a `+` in a timezone offset (`%2B`). A `since` later than `until` is answered with 400.

```bash
curl "https://app.emailconnect.eu/api/v1/logs?since=2026-10-12T00:00:00Z&until=2026-10-13T00:00:00Z" \
  -H "X-API-KEY: your-api-key-here"
```

Scope: `logs:read`

### Get one email
```bash
curl "https://app.emailconnect.eu/api/v1/emails/msg_cmbw6hopl002uru1qqyx7b18a" \
  -H "X-API-KEY: your-api-key-here"
```

Returns the log entry for a single email: delivery status, number of attempts, the last error, the HTTP status your endpoint returned, and the stored webhook payload. Answers 404 when the email does not exist, is not yours, or has already been deleted.

Scope: `logs:read`

### Identifying an email in the API

Wherever a path contains `{messageId}` (get, retry, delete), two forms are accepted:

- **`msg_…`** — the value of the `webhook-id` header on the delivery, also sent as `id` in the body. This is the preferred form: we assign it, and it names exactly one email.
- **The email's Message-ID** (`envelope.messageId`), with or without the angle brackets. Percent-encode it, since it contains characters such as `@`, `<` and `>`.

### Get usage metrics
```bash
curl https://app.emailconnect.eu/api/v1/metrics \
  -H "X-API-KEY: your-api-key-here"
```

Returns counts and rates for the account: `domains`, `verified_domains`, `emails_processed_24h`, `success_rate`, `monthly_usage`, `monthly_limit`, `total_available_emails`, `purchased_credits`, `webhooks`, `non_test_webhooks`, `aliases`.

Scope: `metrics:read`

### Retry or replay a webhook delivery
```bash
curl -X POST "https://app.emailconnect.eu/api/v1/logs/{messageId}/retry" \
  -H "X-API-KEY: your-api-key-here"
```

Retries a failed or expired delivery, or replays one that already succeeded. Available on all plans, with a 30-second cooldown per message. The replayed delivery carries the same `webhook-id` as the original. While a delivery of the message is still in progress (its first one, or an earlier retry), the call answers 409.

Scope: `logs:retry`

### Delete an email (Business+)
```bash
curl -X DELETE "https://app.emailconnect.eu/api/v1/emails/{messageId}" \
  -H "X-API-KEY: your-api-key-here"
```

Permanently removes the email record and all its attachments (database rows and stored objects). `{messageId}` takes either form described under [Identifying an email in the API](#identifying-an-email-in-the-api); in a webhook handler the `webhook-id` header is the one to pass. This is a retention control: it lets you shrink the storage window to seconds once your webhook has succeeded. **Business plan or higher**, and the key needs the `emails:delete` scope.

## Security best practices

### Key rotation
- Rotate keys every 90 days
- Use different keys per integration
- Revoke unused keys immediately

### Scope limitation
- Use minimum required permissions
- Create separate keys for read vs write
- Audit key usage regularly

### Environment separation
- Development: limited scope, test domains only
- Production: a dedicated key per service, scoped to what that service actually calls
- CI/CD: a separate key you can revoke on its own

API keys do not expire and do not carry IP restrictions — revoking a key in [Settings > API Keys](https://app.emailconnect.eu/settings/api-keys) is how you retire one.

### Storage guidelines
- Never commit keys to version control
- Use environment variables
- Encrypt keys in configuration files
- Use secret management services

## Rate limits

Requests made with an API key are limited per account, per hour, across all of the account's keys:

| Plan | Requests per hour |
|---|---|
| Free | 100 |
| Maker | 1,000 |
| Business | 5,000 |
| Platform | 10,000 |

Short bursts are fine within the hour. Sending a test webhook or verifying one counts separately: 30 per 15 minutes per account.

### Rate limit headers

All API responses include rate limit headers: `x-ratelimit-limit`, `x-ratelimit-remaining` and `x-ratelimit-reset`. Read the limit from `x-ratelimit-limit` rather than assuming a number.

When you exceed your limit, the response returns HTTP 429 with a `retry-after` header indicating how many seconds to wait.

## Integration examples

### Python
```python
import requests

API_KEY = "your-api-key-here"
BASE_URL = "https://app.emailconnect.eu/api"

headers = {
    "X-API-KEY": API_KEY,
    "Content-Type": "application/json"
}

# List all domains
response = requests.get(f"{BASE_URL}/domains", headers=headers)
domains = response.json()
```

### Node.js
```javascript
const axios = require('axios');

const API_KEY = 'your-api-key-here';
const BASE_URL = 'https://app.emailconnect.eu/api';

const client = axios.create({
  baseURL: BASE_URL,
  headers: {
    'X-API-KEY': API_KEY,
    'Content-Type': 'application/json'
  }
});

// Create an alias (localPart, domainId and webhookId are all required)
async function createAlias(localPart, domainId, webhookId) {
  const response = await client.post('/aliases', {
    localPart,
    domainId,
    webhookId
  });
  return response.data;
}
```

### cURL
```bash
# Get account usage metrics
curl -X GET https://app.emailconnect.eu/api/v1/metrics \
  -H "X-API-KEY: your-api-key-here"
```

## Troubleshooting

### Authentication errors
- Verify API key is correct
- Check key hasn't been revoked
- Ensure X-API-KEY header is included

### Permission denied
- A 403 means the key is missing the scope the endpoint requires — check the scope table above and recreate the key with the right scopes (scopes cannot be edited after creation)
- Verify resource ownership
- Confirm account limits and plan (e.g. `DELETE /api/v1/emails/{messageId}` also requires Business+)

### Rate limiting
- Implement exponential backoff
- Cache responses when possible
- Use webhooks instead of polling

## Advanced usage

### Webhook signature verification
Verify that webhook requests are genuinely from EmailConnect using Standard Webhooks signatures. See the [Webhook signing](https://emailconnect.eu/help/webhook-signing/) guide for full implementation details and code examples in multiple languages.

### Updating an alias

Update an existing alias with **PUT** (not PATCH) — send only the fields you want to change:

```bash
curl -X PUT https://app.emailconnect.eu/api/aliases/{aliasId} \
  -H "X-API-KEY: your-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "active": false,
    "webhookId": "wh_789"
  }'
```

Updatable fields: `email`, `webhookId`, `active`, `allowAttachments`, `includeEnvelope`, `includeHtml`, `includeText`, `includeLinks`, `includeMarkdown`, `includeReplyParsing`, `attachmentHandling`, `s3Folder`, `storageConnectionId`. At least one must be present.

Scope: `aliases:write`

### Pagination

Log listings page with `limit` and `offset` (not `page`):

```bash
curl "https://app.emailconnect.eu/api/v1/logs?limit=100&offset=100" \
  -H "X-API-KEY: your-api-key-here"
```

`limit` is capped at 100. The response includes `total` and `hasMore` so you know when to stop.

The API provides powerful programmatic access to all EmailConnect features, enabling seamless integration with your existing tools and workflows.
