/v1/webhooksCreate a webhook subscription.
/v1/webhooks/{id}/rotate-secretRotate the webhook signing secret.
What you should use webhooks for
Webhooks are the canonical way to ingest outcomes into your product:
- Delivery/bounce/complaint feedback loops
- Open/click tracking events (if enabled)
- Suppression automation
Don't poll
Prefer webhooks over polling transmission status. You'll get better latency and fewer edge cases.
Signing & verification
Every webhook endpoint has a signing secret. Store it securely — it's typically returned only when you create the webhook and when you rotate the secret.
To verify authenticity:
- Read the raw request body bytes
- Compute an HMAC using the signing secret
- Compare against the signature header (timing-safe compare)
If you want, I can add a ready-to-copy verification snippet for Node + Go once you confirm the signature header name your app uses.
Event payload
{
"type": "delivery",
"timestamp": "2026-02-05T12:34:56.789Z",
"message_id": "msg_01HP3GZK7E3D2C4P2J6Q1E9N2X",
"transmission_id": "tx_01HP3GZK4B8X2W1P0R9N7M6L5K",
"recipient": "user@example.com",
"provider": "gmail",
"outcome": {
"status": "delivered",
"reason": null
},
"meta": {
"tags": ["receipt"],
"tenant": "acme"
}
}Retries
Webhook delivery is retried when your endpoint returns a non-2xx response or times out.
Ack fast
Return 2xx quickly and do heavy work async (queue/job). Slow handlers cause retries and duplicate processing.
Simulate events
Webhook Event Simulator
Generate realistic payloads and a demo signature.
{
"type": "delivery",
"timestamp": "2026-02-25T19:32:32.568Z",
"message_id": "msg_01HP3GZK7E3D2C4P2J6Q1E9N2X",
"transmission_id": "tx_01HP3GZK4B8X2W1P0R9N7M6L5K",
"recipient": "user@example.com",
"provider": "gmail",
"outcome": {
"status": "delivered",
"reason": null
},
"meta": {
"tenant": "acme",
"tags": [
"receipt"
]
}
}