Routing: forwarders, webhooks and templates

Routing holds the three things that act on mail as it arrives. Forwarders re-send a message to another address; webhooks post it to a URL as JSON; templates extract named values from a message's subject and body for a webhook or for the API. All three run on every incoming message that is not junk. Forwarders and webhooks are counted per plan: Free and Plus carry one forwarder and no webhooks, Pro five forwarders and three webhooks, Scale as many of each as you like. Templates start on Pro. Webhooks kept on a plan without them are paused, not deleted.

Forwarders

A forwarder has a name, a destination address, an on/off switch and any number of filters.

Free and Plus carry one forwarder, Pro five, Scale as many as you like. Forwarders you already have keep working if you move down a plan — you are only stopped from adding another.

  1. Open Routing → Forwarders → New forwarder.
  2. Enter the destination address. It must be outside your account: an address on one of your own domains is refused, because a forwarder sends mail outside your account. To deliver one of your own addresses into a mailbox, add it as an alias on that mailbox's page.
  3. Add filters if you want only some mail forwarded (below). A forwarder with no filters forwards everything the workspace receives.

The forwarded message is sent from the mailbox that received it, to your destination, with the subject prefixed [Forwarded] and a header block naming the original sender, recipients, subject and date above the original body. Because it is an outgoing message from your domain, it passes the same checks as any other: the domain must be verified for sending, the destination must be allowed under the domain's outbound access, and it counts toward the monthly send allowance. In reply-only mode that means the destination must be an address that has written to your domain; in practice, request outbound access before relying on a forwarder to an external address. See Sending and outbound access.

Each forwarder's page lists its log: every message it handled, when, and whether it was sent or failed, with the reason.

Filters

Forwarders and webhooks use the same filters. Every filter must match for the rule to run.

FieldOperatorsExample
SubjectContains, Equals, RegexSubject contains invoice
FromContains, Equals, RegexFrom contains @stripe.com
ToContains, Equals, RegexTo equals billing@yourdomain.com
Cc, BccContains, Equals, RegexCc contains accounts@

Regex filters use .NET regular expression syntax and are matched case-insensitively. Junk is never forwarded or posted, whatever the filters say.

Webhooks

A webhook posts a JSON document to a URL you control each time a matching message arrives. Create one under Routing → Webhooks with a name, the URL (HTTPS), optional filters and an optional template.

Pro carries three webhooks, Scale as many as you like; Free and Plus have none. Webhooks on a plan without them are kept but not called, and start being called again the moment you move up. Over the allowance — after a downgrade from Scale, say — they all keep firing; you are only stopped from adding another.

POST https://your-app.example/hooks/mail
Content-Type: application/json

{
  "webHook":  { "id": 12, "name": "Support to Slack", "url": "https://…", "template": { "id": 3, "key": "order-confirmation" } },
  "message":  {
    "id": 48211,
    "subject": "Order 1048 confirmed",
    "from": ["shop@example.com"],
    "to": ["orders@yourdomain.com"],
    "cc": [],
    "bcc": [],
    "received": "2026-09-05T07:14:02Z",
    "mailboxId": 7
  },
  "subjectParameters": { "order": "1048" },
  "bodyParameters":    { "total": "€240.00" }
}
  • The body of the message is not included. Fetch it with the REST API using the message id if you need it.
  • subjectParameters and bodyParameters are present only when the webhook has a template and the template matched; otherwise they are null.
  • Property names are camelCase.

The request is made once. A 2xx response is logged as success; anything else, or no response, is logged as failed with the status. There is no automatic retry: if your endpoint was down, fetch the message through the API. Requests are not signed; use a secret in the URL or restrict the endpoint to the request shape if you need to authenticate them.

Each webhook's page lists its log with the posted status of every message it handled.

Templates

A template describes a fragment of a subject or body with named placeholders, and pulls the values out of a real message. Templates are used by webhooks (the extracted values are posted alongside the message) and by the API's parsed message endpoints.

FieldMeaning
KeyThe template's name, unique in the workspace. Used in URLs and in the webhook payload.
SubjectOptional pattern matched against the message subject.
BodyOptional pattern matched against the message body text.

A placeholder is written {{name}}. Everything else in the pattern is matched literally. The pattern does not have to describe the whole subject or body; it is found anywhere in the text, so a greeting and a signature around it do not matter. Each placeholder takes the shortest text that lets the rest of the pattern match.

Subject pattern:  Order {{order}} confirmed
Body pattern:     Total charged: {{total}}

Message subject:  Order 1048 confirmed
Extracted:        { "order": "1048" }

Matching is capped at one second per template to protect the service from pathological patterns; a pattern that takes longer counts as not matched. Test a pattern against sample text before saving it, from the template page or with POST /templates/test in the API.

Say hello

Say hello

A question before you sign up, or something that is not working: write it here and a person answers by email.

A person answers by email, usually within a day.