Webhooks
Receive real-time notifications when email events occur.
Overview
Webhooks allow you to receive HTTP POST requests when events like email delivery, opens, clicks, and bounces occur. This enables real-time tracking and automation.
Creating a webhook
Create a webhook endpoint to receive events:
// POST /api/webhooks
{
"url": "https://yourapp.com/webhooks/sentd",
"events": ["email.delivered", "email.opened", "email.bounced"],
"description": "Production webhook"
}Available events
| Event | Description |
|---|---|
email.sent | Email was sent to the provider |
email.delivered | Email was delivered to recipient |
email.opened | Recipient opened the email |
email.clicked | Recipient clicked a link |
email.bounced | Email bounced (hard or soft) |
email.complained | Recipient marked as spam |
email.unsubscribed | Recipient unsubscribed |
Webhook payload
Each webhook request includes the event data:
{
"id": "evt_abc123",
"type": "email.delivered",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"email_id": "em_xyz789",
"to": "user@example.com",
"subject": "Welcome!",
"delivered_at": "2024-01-15T10:30:00Z"
}
}Verifying webhooks
Verify webhook signatures to ensure requests are from SENTD:
import crypto from 'crypto';
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler
app.post('/webhooks/sentd', (req, res) => {
const signature = req.headers['x-sentd-signature'];
const isValid = verifyWebhook(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook
console.log('Event:', req.body.type);
res.json({ received: true });
});Always verify webhook signatures in production to prevent spoofing attacks.
Retry policy
If your endpoint returns a non-2xx status, we'll retry with exponential backoff:
- Retry 1: After 1 minute
- Retry 2: After 5 minutes
- Retry 3: After 30 minutes
- Retry 4: After 2 hours
- Retry 5: After 24 hours (final)