Using Webhooks
Webhooks notify your application in real time when events happen — a contact subscribes, an email is opened, a campaign is sent.
Create a webhook
curl -X POST https://api.cakemail.dev/webhooks \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/cakemail",
"events": ["Contact.Added", "Email.Opened", "Campaign.Sent"],
"rate_limit": 100,
"rate_limit_period": "hour"
}'
The response includes a webhook_id and a secret for signature verification.
Available events
| Event | Triggered when |
|---|---|
Contact.Added | A contact is added to a list |
Contact.Unsubscribed | A contact unsubscribes |
Email.Opened | A recipient opens an email |
Email.Clicked | A recipient clicks a link |
Email.Bounced | An email bounces |
Campaign.Sent | A campaign finishes sending |
Campaign.Scheduled | A campaign is scheduled |
See the API reference for the full list.
Retrieve webhook details
Fetch a webhook's configuration, including its secret and hash_function, using its ID:
curl "https://api.cakemail.dev/webhooks/{webhook_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
The response contains the webhook's URL, subscribed events, rate limit settings, secret key, and hash function used for signature verification.
Verify webhook signatures
Each webhook request includes a signature header. Verify it to ensure the request is authentic:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('base64');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Webhook payload structure
When an event fires, Cakemail sends a POST request to your endpoint. The request includes a signature header and a JSON body:
Header:
X-Cakemail-Signature: BASE64_ENCODED_HMAC_SIGNATURE
Body:
{
"event": "Email.Opened",
"timestamp": "2026-04-10T14:32:00Z",
"data": {
"email_id": "e_abc123",
"contact_id": "c_def456",
"campaign_id": "cmp_ghi789",
"list_id": "lst_jkl012",
"email_address": "recipient@example.com",
"opened_at": "2026-04-10T14:32:00Z"
}
}
The exact fields inside data vary by event type. Refer to the API reference for the schema of each event.
List your webhooks
curl "https://api.cakemail.dev/webhooks" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Archive a webhook
Webhooks can't be deleted, but they can be archived (disabled):
curl -X POST https://api.cakemail.dev/webhooks/{webhook_id}/archive \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
To re-enable, use the unarchive endpoint.
Limitations
Only Next-gen API events are supported. Legacy API events are not forwarded to webhooks.