The atomic webhook/alias endpoint lets you create a webhook and email alias in a single API call. Both resources are created together in a transaction — if either fails, neither is created. This is the recommended way to set up email forwarding programmatically.
Endpoint
POST https://app.emailconnect.eu/api/webhooks/alias
X-API-KEY: YOUR_API_KEY
Content-Type: application/json
Request body
| Field | Type | Required | Description |
|---|---|---|---|
domainId |
string | Yes | ID of the domain to create the alias under |
webhookUrl |
string | Yes | URL to receive webhook payloads (must be a valid URI) |
webhookName |
string | Yes | Display name for the webhook (1–100 characters) |
webhookDescription |
string | No | Optional description (max 500 characters) |
aliasType |
string | Yes | "catchall" or "specific" |
localPart |
string | Conditional | Required when aliasType is "specific". The part before the @ (1–64 characters) |
syncWithDomain |
boolean | No | Sync catch-all webhook with domain default. Default: true |
firstOrCreate |
boolean | No | Smart create/update — reuse existing alias if found. Default: false |
updateWebhookData |
boolean | No | Update webhook name/URL if alias already exists. Default: true |
generateSecret |
boolean | No | Generate webhook signing secret (all plans). Default: false |
webhookSecret |
string | No | Provide your own signing secret (all plans) |
Basic example
Node.js
const response = await fetch('https://app.emailconnect.eu/api/webhooks/alias', {
method: 'POST',
headers: {
'X-API-KEY': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
domainId: 'dom_abc123',
webhookUrl: 'https://your-app.com/webhook/emails',
webhookName: 'My email webhook',
aliasType: 'specific',
localPart: 'support'
})
});
const result = await response.json();
// result.alias.email → "support@yourdomain.com"
// result.webhook.id → "wh_xyz789"
Python
import requests
response = requests.post(
'https://app.emailconnect.eu/api/webhooks/alias',
headers={
'X-API-KEY': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'domainId': 'dom_abc123',
'webhookUrl': 'https://your-app.com/webhook/emails',
'webhookName': 'My email webhook',
'aliasType': 'specific',
'localPart': 'support'
}
)
result = response.json()
cURL
curl -X POST https://app.emailconnect.eu/api/webhooks/alias \
-H "X-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domainId": "dom_abc123",
"webhookUrl": "https://your-app.com/webhook/emails",
"webhookName": "My email webhook",
"aliasType": "specific",
"localPart": "support"
}'
Response
{
"success": true,
"webhook": {
"id": "wh_xyz789",
"name": "My email webhook",
"url": "https://your-app.com/webhook/emails",
"verified": false,
"hasSecret": false,
"verificationToken": "abc12",
"createdAt": "2026-02-03T12:00:00.000Z"
},
"alias": {
"id": "al_def456",
"email": "support@yourdomain.com",
"active": true,
"createdAt": "2026-02-03T12:00:00.000Z"
},
"action": "created",
"message": "Webhook and alias created successfully"
}
Response fields
| Field | Description |
|---|---|
action |
One of "created", "updated", "webhook_added", or "cross_domain_update" |
webhook.verified |
Whether the webhook URL has been verified |
webhook.verificationToken |
Present only if webhook is not yet verified — use to complete verification |
webhook.hasSecret |
Whether webhook signing is enabled |
webhookSecret |
Present only once when generateSecret is true — save it immediately |
Smart create/update with firstOrCreate
When firstOrCreate is true, the endpoint checks if a matching alias already exists — even across domains. This prevents duplicate aliases and simplifies integration setup.
Behavior by scenario:
| Scenario | Result | action value |
|---|---|---|
| No existing alias | Creates new webhook + alias | "created" |
| Alias exists in same domain | Updates webhook details | "updated" |
| Alias exists in different domain | Moves alias to target domain | "cross_domain_update" |
| Alias exists without webhook | Creates and links new webhook | "webhook_added" |
Example with firstOrCreate
curl -X POST https://app.emailconnect.eu/api/webhooks/alias \
-H "X-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domainId": "dom_abc123",
"webhookUrl": "https://your-app.com/webhook/emails",
"webhookName": "Updated webhook",
"aliasType": "specific",
"localPart": "support",
"firstOrCreate": true
}'
Catch-all aliases
Set aliasType to "catchall" to create a catch-all alias that receives all unmatched emails for a domain.
{
"domainId": "dom_abc123",
"webhookUrl": "https://your-app.com/webhook/emails",
"webhookName": "Catch-all webhook",
"aliasType": "catchall",
"syncWithDomain": true
}
When syncWithDomain is true (the default), the domain's default webhook is also updated to point to this URL.
Webhook signing
Add webhook signing (Standard Webhooks) to verify webhook authenticity. Available on every plan, Free included.
{
"domainId": "dom_abc123",
"webhookUrl": "https://your-app.com/webhook/emails",
"webhookName": "Signed webhook",
"aliasType": "specific",
"localPart": "secure",
"generateSecret": true
}
The response will include a webhookSecret field. Save it immediately — it will not be shown again. See Webhook signing for verification details.
Error responses
| Status | Reason |
|---|---|
| 400 | Invalid request body or missing required fields |
| 402 | Plan limit exceeded (webhook or alias count) or a paid-plan feature was requested |
| 404 | Domain not found or access denied |
| 409 | Alias already exists (when firstOrCreate is false) |
Related
- API keys and integrations — managing API keys
- Webhook signing — verifying webhook signatures
- Webhook configuration — general webhook setup