Atomic webhook and alias endpoint
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/v1/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 |
autoVerify |
boolean | No | Attempt automatic verification. Default: false |
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 HMAC signing secret (Advanced plan required). Default: false |
webhookSecret |
string | No | Provide your own signing secret (Advanced plan required) |
Basic example
Node.js
const response = await fetch('https://app.emailconnect.eu/api/v1/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/v1/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/v1/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 HMAC 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/v1/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 HMAC-SHA256 signing to verify webhook authenticity. Requires an Advanced or Enterprise plan.
{
"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.
Auto-verification
Webhooks from trusted integration sources (n8n, Zapier, Make) can be automatically verified when autoVerify is true. For other webhook URLs, you will receive a verificationToken in the response to complete manual verification.
Error responses
| Status | Reason |
|---|---|
| 400 | Invalid request body or missing required fields |
| 402 | Plan limit exceeded (webhook or alias count) or Advanced feature required |
| 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