Skip to main content

Inbound email and SMS routing

Most of Orbit’s email and SMS surface is built for sending. This guide covers the other direction: what happens when a customer writes to you, and how you control where that inbound traffic goes. You will:
  1. Configure inbound parse on a domain
  2. Understand the normalized inbound payload
  3. Route inbound SMS with match rules
  4. Auto-reply with Flows
  5. Handle bounces and unsubscribes

Prerequisites

  • An API key from Settings → API Keys (a dv_live_sk_… live key — inbound routing configures real traffic).
  • For email: a domain you can point MX records at Orbit (for example, a dedicated subdomain such as inbound.your-domain.com).
  • For SMS: an inbound-capable number on your account (purchased via the Numbers API or Dashboard → Numbers).
  • A public HTTPS URL to receive webhook forwards.
Inbound route management endpoints require the owner or admin role. API keys created with the member role receive 403 on the CRUD calls below.

1. Configure inbound parse on a domain

Inbound parse takes mail addressed to a domain or address you control, matches it against a route you register, parses the message into structured fields, and forwards the result as a signed JSON POST to your webhook URL.

Point MX records

Point the receiving domain’s MX records at Orbit’s ingress (the dashboard shows the hostname when you open Email → Inbound routes → Add route). Once DNS propagates, any address at that domain (support@inbound.your-domain.com, billing@inbound.your-domain.com, …) is a candidate for a route.

Create a route

Register the destination pattern and webhook URL with POST /email/inbound-routes:
The response 201 carries — exactly once — the route’s signingSecret. Store it now; list and get responses mask secrets.
recipientPattern accepts three shapes: Recipients are matched against the SMTP envelope recipient first, then the To and Cc headers — BCC, aliased, and forwarded mail route correctly even when the To header omits your address. A duplicate pattern returns 409 CONFLICT. Routes are manageable from GET /email/inbound-routes (list) and DELETE /email/inbound-routes/:routeId.

2. The normalized inbound payload

Each matched message is POSTed to your destinationUrl as JSON, signed with the route’s secret:
  • text and html are the decoded body parts (both can be null).
  • attachments is metadata only — filename, MIME type, decoded byte size, and the inline-image Content-ID. Attachment bytes are never inlined into the JSON. Set includeRawMime: true on the route when you need the full original message.
  • headers carries every top-level header as a lowercased key map.
Verify the X-Orbit-Signature header (sha256=<hex> over the raw body, HMAC-keyed by the route’s signingSecret) before trusting a forward, as you would for any webhook. Only 2xx responses count as a successful forward — redirects are not followed — and the route’s failureCount / lastFailureAt (visible in GET /email/inbound-routes) track failures.
Every matched inbound email also opens (or threads onto) an inbox ticket in parallel with your webhook forward — the internal helpdesk surface works side by side with your developer integration. See the ticket fields in the receive step of the two-way messages guide.

3. Route inbound SMS with match rules

Inbound SMS routing is an ordered rule engine over each inbound (MO) message: POST /messages/inbound-routes registers a rule, and inbound messages are matched in ascending priority (lower number wins). When no rule matches, the message falls through to the default behaviour — the tenant-wide message.received event and inbox persistence. Rules are matched only on enabled entries. Match types: Target types:

Example: keyword → webhook

A webhook-delivered inbound message looks like:
The secret you set is used to sign the POST (X-Orbit-Signature: sha256=<hex>). Queue, inbox, and team targets produce no HTTP call — the assignment is published to the inbox layer directly. Each matched rule’s failureCount and lastFailureAt/lastMatchedAt are tracked and listed via GET /messages/inbound-routes (webhook secrets are masked in list responses). Update a rule with PATCH /messages/inbound-routes/:routeId; delete with DELETE /messages/inbound-routes/:routeId.

4. Auto-reply with Flows

For canned inbound replies, prefer the auto_reply target type on an inbound SMS rule — the decoupling keeps reply logic in a config rule instead of a network hop. For anything more orchestrated (look up an order, branch on the customer’s lifecycle stage, fan out to a channel other than the one they came in on), build a Flow that reacts to the inbound message event and sends through the channel of your choice — the Send & Receive Messages guide shows how the receive → reply loop looks at the API level, and Flows externalizes that loop into the builder. Inbound email rules do not have a reply path themselves — use an email channel Flow on the inbound event to compose the response, or open a ticket (which your agents handle from the inbox).

5. Bounces and unsubscribes

Inbound workflows end in outbound mail, so the suppressions that matter are the ones on the outbound side:
  • Unsubscribe. Every outbound email carries a one-click unsubscribe link (the List-Unsubscribe header plus the body link). A recipient click lands at a signed URL, suppression is recorded idempotently against that recipient, and an email.unsubscribed audit entry is appended. Suppressed recipients are skipped at send time. The recipient is redirected to your configured page, or shown an acknowledgement.
  • Bounce handling. Hard bounces, spam complaints, and invalid addresses are tracked per message and surface with the standard email events. Suppress addresses proactively from the opt-out lists guide, and follow send-best-practices to keep deliverability healthy.
The unsubscribe and inbound-parse surfaces are deliberately separate — inbound inbound (receiving) does not unsubscribe anyone; the outbound path does. Route bounces and unsubscribes into your suppression rules the same way you would register an inbound SMS keyword.

Next steps