Event types
Three further types —
message.delivered, message.bounced and message.complained — are accepted on subscriptions but never fire on the current deployment. They need asynchronous feedback from the mail transport that is not available today. They are accepted so that client code stays portable; do not build logic that waits for them.Webhooks
Response
event_types is required and must be non-empty. Omitting inbox_ids subscribes to every inbox the key can see — and a scoped key’s webhook is narrowed to that key’s scope automatically, whatever the request asked for.
Delivery headers
Verifying the signature
Compute the HMAC over the raw request body, before any JSON parsing. Re-serializing the parsed object will not reproduce the same bytes.Express
===.
The payload
message.received payloads also carry matched_by — which threading layer resolved the message — and auto_reply, flagging vacation responders. Check auto_reply before letting an agent answer.
Retries
A delivery is successful on any2xx. Anything else is retried:
Six attempts in total, then the delivery is marked
failed. Each attempt times out after 30 seconds.
Managing webhooks
PATCH { "enabled": false } pauses a webhook without losing its configuration or secret.
WebSocket
For an agent process that stays up, a socket avoids needing a public HTTPS endpoint at all.{"type":"subscribed", ...} and then streams {"type":"event", ...} frames in the same shape webhooks receive. {"type":"ping"} gets {"type":"pong"} for keepalive.
A per-inbox endpoint exists too, if you want one socket per agent:
The socket delivers events while you are connected. It does not replay what you missed while disconnected — for that, read
GET /v0/inboxes/{inbox_id}/events on reconnect, or use a webhook, which retries.Choosing between them
For anything you would be unhappy to silently miss, use a webhook. The retry queue is the difference.

