Integrations
Webhooks
Send feedbackA webhook reverses the usual direction: instead of your application asking NevTan Mail whether anything has happened, NevTan Mail posts to a URL you own as soon as it does. It is the difference between checking for new mail every minute and being told the moment it lands.
How webhooks work
- You give us a URL and say which event it is interested in.
- We post JSON to it each time that event happens, describing what happened.
- Your endpoint answers 2xx to confirm it has the message. Anything else is treated as a failure and retried.
- Subscriptions are managed through the Mail API, so you will need an API key first.
Events you can subscribe to
| Event | Fires when | Delivers |
|---|---|---|
email.received | A message arrives in a mailbox your key can see. | Email object |
email.sent | A message is sent from that mailbox, however it was sent. | Email object |
mailbox.created | A new mailbox is created on the domain. | Mailbox object |
Both object shapes are set out in full in the Mail API reference.
Requirements for your URL
A subscription is refused unless the URL meets all of these:
- It must use HTTPS. Plain
http://is rejected, because deliveries can contain the full text of your mail. - It must be reachable from the public internet. Addresses on a private network, loopback addresses and hostnames that do not resolve are all refused.
- It should answer quickly. Acknowledge the delivery first and do the real work afterwards, rather than holding the request open.
- It should tolerate a repeat. A delivery can arrive more than once if your acknowledgement is lost in transit, so make handling the same message twice harmless.
Testing from your own machine
A URL on localhost cannot receive deliveries, because we have to be able to reach it. While developing, put a tunnelling service in front of your machine so it has a public HTTPS address, and point the subscription at that.
Subscribe a URL
Post the event name and your URL to /hooks:
curl -X POST https://nevtanemailapi.nevtan.com:5008/api/v1/hooks \
-H "Authorization: Bearer nvt_live_xxxxxxxx…" \
-H "Content-Type: application/json" \
-d '{
"event": "email.received",
"target_url": "https://example.com/hooks/nevtan"
}'The response confirms the subscription:
{
"id": 17,
"event": "email.received",
"target_url": "https://example.com/hooks/nevtan",
"created_at": "2026-10-24T09:14:22",
"last_delivered_at": null
}- Keep the
id— it is how you remove the subscription later. last_delivered_atstays null until the first delivery succeeds, which makes it a quick way to confirm your endpoint is working.- Call
GET /hooksat any time to see everything currently subscribed on the account. - Up to 50 subscriptions per account.
What arrives at your URL
Each delivery is a POST whose body is the object for that event — the same shape the Mail API returns. Alongside it come these headers:
| Header | What it carries |
|---|---|
X-NevTan-Event | The event name, so one endpoint can serve several subscriptions. |
X-NevTan-Delivery | An identifier for this delivery. It stays the same across retries, which is what lets you recognise a repeat. |
X-NevTan-Timestamp | When the delivery was sent. |
X-NevTan-Signature | A signature over the timestamp and body, for confirming the delivery came from NevTan Mail. |
Check the delivery is one you expect
Signature checking is not something you can set up yourself yet, so until it is, treat your webhook URL as the secret: give it a long, unguessable path, and have it accept only the events you actually subscribed to. Never act on a delivery by fetching a URL it contains.
Retries and failures
- Any 2xx response means delivered. We stop there and record the time.
- Anything else is retried — up to 12 attempts, waiting longer each time, from about a minute at first up to six hours between the last tries. A delivery survives a few hours of downtime at your end.
- After 12 attempts it is given up on, and that delivery is not sent again.
- Answer 410 Gone to unsubscribe. If your endpoint returns 410, the subscription is removed automatically — the tidy way to retire a URL you no longer own.
A missing message is not always a missing webhook
If deliveries stop, check the key behind the subscription first. Revoking an API key turns off every webhook created with it, which is easy to overlook when the two were set up weeks apart.
Remove a subscription
- Delete it through the API —
DELETE /hooks/{id}, using the id from when you subscribed or fromGET /hooks. - Answer 410 Gone from the endpoint, and it is removed for you.
- Revoke the API key that created it, which stops every subscription made with that key at once.
Removing a subscription stops deliveries straight away. It has no effect on the mail itself — messages carry on arriving and sending exactly as before.
