Skip to the documentation
Knowledge base

Mail to a webhook

Hand the mail of an address straight to your own server instead of a mailbox, and copy what an address receives to up to five endpoints.

Addresses that post to a webhook

An address whose destination is webhook is not a mailbox. Each message it receives is kept exactly as it arrived for 30 days and posted to one webhook endpoint of the workspace as the event email.routed, with the text, the HTML, every attachment and the whole message behind signed links. Nothing is filed, so nothing shows in the app, a mail app or a search. It suits mail a program reads: replies to a ticket system, receipts to parse, a support form that sends its mail on.

  • In the web app, open the address, edit Delivers to on its Delivery tab, choose A webhook only and pick the endpoint. In the phone app, Where mail goes on the Delivery tab of the address screen offers the same four destinations.
  • Over REST, destination: "webhook" and webhookId on POST /domains/{id}/addresses and PATCH /domains/{id}/addresses/{addressId}, and every address reports them.
  • In the SDKs, the same fields on domains.createAddress and domains.updateAddress, written the way each language writes names.
  • Over MCP and in the assistant, the same fields on addDomainAddress and updateDomainAddress.
  • A route of the domain can do the same for a whole pattern of local parts: action: "webhook" on POST /domains/{id}/routes sends every address it catches to its endpoint, and routedBy names the route.

The limits of the address still apply before anything is posted: a receiving hold, the receiving caps and the allowed senders turn mail away exactly as they do for a mailbox, and every message counts toward the caps. Rules, out of office replies, AI labels, tasks, automations and the mailbox counts do not run, because there is no mailbox for them to act on, and the storage quota of the address does not count what is routed.

When its endpoint is switched off or deleted, the address files its mail in its own mailbox instead, so nothing is lost while it has nowhere to go. It posts again once the endpoint is switched back on, or once the address names another one. A route whose endpoint is gone or switched off takes no mail, and the next route or the catch-all decides.

Mail apps do not reach an address that posts to a webhook, since it has no mailbox to open. They reach it again once its endpoint is deleted, because its mail then lands in its mailbox, and they reach a group address that keeps a copy. Sending from the address works as before.

The email.routed event

email.routed goes only to the endpoint the address or the route names and to the taps of the address. No endpoint subscribes to it, it is not in the event list of the webhook catalogue, and its retries and replays skip the subscription and the address and domain lists of the endpoint. It has the signature, the retry policy and the dead letters of every other event, and every attempt carries content and raw whatever the endpoint asks for, read when the attempt is sent, so the delivery log keeps the event without the message.

FieldWhat it holds
routedMessageIdThe stored message, an id that starts with rtd_. It is kept 30 days after it arrived.
toThe address the message was handled as, without a plus tag: the address itself, or the address a route caught.
recipientThe address it was sent to, exactly as the sending server gave it, plus tag included, so a tag can carry a ticket number or a token.
from, fromName, subject, date, messageIdRead off the headers, as in email.received.
receivedAt, sizeWhen it arrived, and its size in bytes.
spamTrue when it carries the signs that file mail to Spam, or its sender is blocked by name. It is posted either way.
verdictsWhat the receiving server found for SPF, DKIM, DMARC, spam and viruses, each pass, fail, gray, processing_failed or disabled, and arc, the verdict for the servers that forwarded the message on its way here: pass, fail, none or temperror.
routedBy{ kind, id }: address and the address id, or route and the route id.
contentThe text, the HTML up to 512 KiB and every attachment, inline images included, each with a download link.
rawA link to the whole message as a message/rfc822 file, byte for byte as it arrived.
  • The links in content and raw work for an hour after each attempt, while the endpoint stays switched on, and until the stored message is deleted. They are /public/webhook-files/{token} and /public/webhook-raw/{token}, the same as for email.received, and need no credential.
  • A routed message is deleted 30 days after it arrived, by an hourly job, and with its domain when the domain is removed. A replay after that carries the event without content and raw.
  • A message that arrives again, after a retry of the sending server or a second attempt on our side, is stored and posted once per address.

Taps

A tap copies everything an address receives to an endpoint, without changing where the mail goes. An address takes up to five, as tapWebhookIds on the same address requests. A message filed in its mailbox reaches each tap as email.received, and a message posted to a webhook as email.routed.

  • In the web app, Copies to webhooks on the Delivery tab of the address picks up to five endpoints. In the phone app, the webhook copies are set under Where mail goes on the same tab of the address screen.
  • A tap is targeted: it reaches the endpoint whatever its subscription and its address and domain lists say. On email.received the data then carries tap: true.
  • An endpoint gets each message once. When it also subscribes to email.received, or is the endpoint the address posts to, the second copy is not sent.
  • A tap whose endpoint was deleted is ignored. A delivery report that arrives at the address is email.bounced and does not reach the taps, and neither does mail a forward-only address archives.
  • A group address reaches its taps only when it keeps a copy, since the copy is the message it files. Each member address has taps of its own.

Taps and webhook addresses send what an address receives to a server you run, so set them on addresses whose mail you mean to leave Nextmail.