Webhooks
Receive real-time notifications about email delivery events.
Setting Up Webhooks
- Go to your Webhooks dashboard
- Click "Add Webhook"
- Enter your endpoint URL (must be HTTPS)
- Select which events to receive
- Save and note your signing secret
Webhook Payload
Webhooks are sent as POST requests with JSON body:
{
"id": "evt_abc123",
"type": "email.delivered",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"emailId": "clx1abc123def456",
"from": "sender@yourdomain.com",
"to": "recipient@example.com",
"subject": "Hello!",
"deliveredAt": "2024-01-15T10:30:00Z"
}
}Verifying Webhooks
Each webhook includes a signature header for verification:
X-GetMailer-Signature: sha256=abc123...import crypto from 'crypto';
function verifyWebhook(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler
app.post('/webhooks/getmailer', (req, res) => {
const signature = req.headers['x-getmailer-signature'];
const isValid = verifyWebhook(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the webhook
const { type, data } = req.body;
// ...
res.status(200).send('OK');
});Responding to Webhooks
- Return a
2xxstatus within 30 seconds - We retry failed webhooks up to 5 times with exponential backoff
- After 5 failures, the webhook is marked as failed
- You can check delivery status in your dashboard
Retry Schedule
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 24 hours |
Best Practices
- Always verify signatures to ensure requests are from GetMailer
- Respond quickly - do heavy processing asynchronously
- Handle duplicates - webhooks may be sent more than once
- Use HTTPS - we only send webhooks to secure endpoints