Webhook Configuration
Configure webhooks to receive real-time notifications for email events
Webhook Configuration
Webhooks allow your application to receive real-time notifications when email events occur. Configure webhook endpoints to receive HTTP POST requests for events like email delivery, bounces, and complaints.
List Webhooks
Retrieve all configured webhook endpoints for your account.
Endpoint
GET /api/email/webhooksAuthentication
Required: Bearer token in Authorization header
Authorization: Bearer YOUR_API_KEYQuery Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: active, disabled, all |
Response (200 OK)
{
"success": true,
"data": {
"webhooks": [
{
"id": "wh_1234567890",
"url": "https://yourapp.com/webhooks/email",
"events": ["email.delivered", "email.bounced"],
"status": "active",
"secret": "whsec_...",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-20T14:22:00Z"
}
]
},
"message": "Webhooks retrieved successfully"
}Create Webhook
Register a new webhook endpoint to receive event notifications.
Endpoint
POST /api/email/webhooksAuthentication
Required: Bearer token in Authorization header
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTPS URL to receive webhook events |
events | array | Yes | Array of event types to subscribe to |
secret | string | No | Secret for signing webhook payloads |
Available Events
| Event | Description |
|---|---|
email.sent | Email successfully sent |
email.delivered | Email delivered to recipient |
email.bounced | Email bounced |
email.complaint | Spam complaint received |
email.opened | Email opened (if tracking enabled) |
email.clicked | Link clicked in email (if tracking enabled) |
email.failed | Email failed to send |
Request Example
curl -X POST https://api.yourdomain.com/api/email/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/email",
"events": ["email.delivered", "email.bounced", "email.complaint"],
"secret": "your_webhook_secret"
}'Response (201 Created)
{
"success": true,
"data": {
"id": "wh_new123456789",
"url": "https://yourapp.com/webhooks/email",
"events": ["email.delivered", "email.bounced", "email.complaint"],
"status": "active",
"secret": "whsec_...",
"createdAt": "2024-01-20T10:00:00Z"
},
"message": "Webhook created successfully"
}Update Webhook
Modify an existing webhook configuration.
Endpoint
PATCH /api/email/webhooks/:idAuthentication
Required: Bearer token in Authorization header
Path Parameters
| Parameter | Description |
|---|---|
id | The webhook ID (e.g., wh_1234567890) |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | No | Updated webhook URL |
events | array | No | Updated event subscriptions |
secret | string | No | New signing secret |
status | string | No | active or disabled |
Request Example
curl -X PATCH https://api.yourdomain.com/api/email/webhooks/wh_1234567890 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": ["email.delivered", "email.bounced", "email.opened"],
"status": "active"
}'Response (200 OK)
{
"success": true,
"data": {
"id": "wh_1234567890",
"url": "https://yourapp.com/webhooks/email",
"events": ["email.delivered", "email.bounced", "email.opened"],
"status": "active",
"updatedAt": "2024-01-20T16:00:00Z"
},
"message": "Webhook updated successfully"
}Delete Webhook
Remove a webhook endpoint permanently.
Endpoint
DELETE /api/email/webhooks/:idAuthentication
Required: Bearer token in Authorization header
Request Example
curl -X DELETE https://api.yourdomain.com/api/email/webhooks/wh_1234567890 \
-H "Authorization: Bearer YOUR_API_KEY"Response (200 OK)
{
"success": true,
"data": {
"id": "wh_1234567890",
"deletedAt": "2024-01-20T15:30:00Z"
},
"message": "Webhook deleted successfully"
}Webhook Payload Format
When events occur, a POST request is sent to your webhook URL with the following structure:
Headers
Content-Type: application/json
X-Webhook-Event: email.delivered
X-Webhook-ID: wh_1234567890
X-Webhook-Signature: sha256=...Payload Body
{
"id": "evt_1234567890",
"event": "email.delivered",
"timestamp": "2024-01-20T10:30:00Z",
"data": {
"messageId": "msg_abc123xyz",
"to": "recipient@example.com",
"from": "sender@example.com",
"subject": "Hello World",
"deliveredAt": "2024-01-20T10:30:00Z"
}
}Verifying Webhook Signatures
Webhooks are signed with your secret using HMAC-SHA256. Verify signatures to ensure payloads are authentic:
JavaScript Example
import crypto from 'crypto';
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Usage
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhook(payload, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}Python Example
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
expected = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Retry Policy
Failed webhook deliveries are retried with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 5 seconds |
| 3 | 25 seconds |
| 4 | 2 minutes |
| 5 | 10 minutes |
Webhooks that fail 5 consecutive times are automatically disabled.
Best Practices
- Use HTTPS URLs only for webhook endpoints
- Verify webhook signatures to prevent spoofing
- Respond quickly (within 5 seconds) to avoid timeouts
- Return 2xx status codes for successful processing
- Implement idempotency - handle duplicate events gracefully
- Store event IDs to prevent processing the same event twice