Documentation
Webhooks.
Get told when a message is delivered, bounces or is marked as spam, instead of asking.
Receiving events
Add an endpoint under Webhooks in the dashboard and choose the events you want. Mailtruss sends each one to your URL as a signed POST with a JSON body. Any 2xx response within 10 seconds counts as delivered.
| Event | Sent when |
|---|---|
email.sent | Handed to the mail provider. |
email.delivered | Accepted by the recipient's mail server. |
email.bounced | Permanently rejected by the recipient's server. |
email.complained | The recipient marked it as spam. |
email.delivery_delayed | Temporarily deferred; delivery is still being retried. |
email.opened | The message was opened (needs open tracking; approximate, as some mail apps preload images). |
email.clicked | A tracked link was clicked (needs click tracking on the domain). |
email.failed | We could not send it (for example, an unverified domain). |
email.received | An email arrived at one of your receiving domains. |
Every body has the event name, the time it was created and a data object. data always holds email_id, the ID shown on the email’s page and returned when you sent it. Delivery events also list the recipients (to) and the details recorded for the event, such as a bounce’s type and the receiving server’s own words.
Verifying the signature
Anyone can post to a public URL, so check that a request is ours before you act on it. Each request carries three headers in the Standard Webhooks scheme. The same values are also sent as svix-id, svix-timestamp and svix-signature, so code written for Svix-signed webhooks works unchanged.
webhook-signatureholds one or more space-separatedv1,<signature>values. The signature is an HMAC-SHA256, in base64, of{webhook-id}.{webhook-timestamp}.{raw body}, keyed with your endpoint’s signing secret. Accept the request if any of them matches.- Reject a request whose
webhook-timestampis more than five minutes from your clock. This stops an old, captured request from being replayed. - When you rotate a secret, requests carry a signature for the old and the new secret for a while, so verification keeps working while you deploy.
verifyWebhook in the Node.js client checks the signature and the timestamp and returns the parsed event. Endpoints created before 14 November 2026 have a secret in an older format; verifyWebhook accepts both, so prefer it if you are not sure which you have.
When your endpoint is down
A response that is not 2xx, a timeout after 10 seconds, or a connection error counts as a failure. Redirects are not followed, so give the final URL. A failed delivery is tried again after 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 24 hours, each wait counted from the previous attempt. If the last retry also fails, the delivery is marked Gave up and is not tried again by itself.
Each endpoint’s page in the dashboard lists its deliveries with the response your server gave, and Replay sends one again once you have fixed the problem. An endpoint whose last three deliveries failed is marked Failing, and you get an alert in the dashboard.