Skip to main content

Inbound fax routing

The Fax channel page covers outbound fax and shows the webhook payloads that arrive when a fax lands on one of your numbers. This guide covers the other half of inbound: how the receive path works end to end, and how routing per DID decides where a received fax goes — your webhook endpoint, email recipients, and the shared inbox. You will:
  1. Publish an inbound address and pick up the event
  2. Follow the delivery lifecycle
  3. Route per DID to email and the inbox
  4. Secure your webhook consumer
  5. Plan for the failure modes that matter
  6. Wire a contact-to-flow-to-email-archive pattern

Prerequisites

  • A fax-capable number on your account (see Buy numbers — inbound fax works with the same inventory).
  • An API key from Settings → API Keys (a dv_live_sk_… live key) for the routing calls below.
  • A public HTTPS endpoint if you want your own webhook consumer in addition to email/inbox routing.

1. Publish an inbound address

Point the carrier-side fax application webhook at Orbit’s inbound endpoint: POST https://api.orbit.devotel.io/webhooks/inbound/fax. For the platform connection Orbit does this for you; for a dedicated (per-tenant) carrier connection, set the URL in the carrier portal. From then on, any fax sent to the DID arrives as a fax.received event with the sender’s number, the receiving DID, and a media URL for the PDF:
The event is deduplicated on the carrier’s fax_id, so a carrier-side replay does not create a second message record. Make sure the carrier connection you send from is fax-capable — a voice-only connection never fires fax.received, and that misconfiguration is invisible to Orbit.

2. The delivery lifecycle

Every inbound fax passes through the same pipeline, whether or not you configure routing:
  1. Verify. The carrier’s signature is checked before anything else. A rejected signature returns 401 and the fax is counted but never stored.
  2. Persist. The fax is stored as a message record with the sender, recipient, and media URL. A 404 from the carrier’s fax application (no fax-capable connection bound) drops the fax at this step.
  3. Route. Routing is per DID. If the receiving DID has routing enabled, the PDF is fetched once (a bounded download with a short timeout) and fanned out to the configured destinations. If the PDF cannot be fetched, email recipients get the download link instead of an attachment.
  4. Acknowledge. The pipeline never errors on a routing failure — worst case is a link-only email or a skipped inbox ticket, logged and visible in your delivery result. The fax record is already safe by that point.
Numbers without routing configured keep the default behaviour: store as a message record plus your tenant events, and nothing else.

3. Route per DID to email and the inbox

Per-DID routing lives on the number’s detail view (Dashboard → Numbers → [your number]), and the same config is available over the API:
NUM_ID is the number’s UUID — the same id you see on the number detail page. Read back the current config with GET /api/v1/numbers/NUM_ID/fax-routing; an unconfigured number returns the disabled defaults. Invalid shapes (a bad email address, more than 20 recipients) are rejected with 422 at write time rather than silently no-oping when a fax arrives.

4. Secure your webhook consumer

Beyond the per-DID email/inbox routing, received faxes also reach your own webhook endpoints through the tenant-wide event bus (the same mechanism as outbound status events). Whichever consumer you build:
  • Verify the X-Orbit-Signature header and reject deliveries older than five minutes — the full verification recipe with code samples is in Webhook security.
  • Return 2xx quickly; only 2xx counts as delivered, and retries continue for anything else.
  • Use the event data.id to deduplicate on at-least-once delivery.
Subscribe to events per the events catalogue and inspect retries and failures in Inspecting deliveries.

5. Failure modes

For outbound fax, a rejected attempt surfaces on message.failed with the carrier’s own error_code / error_message passed through — busy, no answer, no fax tone, poor line quality (see Common errors on the channel page). For inbound routing, the failure modes that actually matter:
  • Invalid recipients at write time are rejected with 422 — fix the config before a fax arrives.
  • PDF fetch failed — the email goes out with the download link instead of an attachment. Delivery is still counted.
  • A recipient email send failed — the remaining recipients still get the fax; the failure is logged.
  • No destinations configured — the fax is still stored as a message record; routing is a no-op.
  • Untrusted signature on the inbound event — rejected before any processing; fix the carrier public key or any proxy stripping the signature headers.

6. Example wiring: flow to email archive

A common pattern: received faxes open an inbox ticket for triage, and a Flow reacts to the inbound event — match the sender to a contact, branch (for example, a known supplier versus an unknown fax number), and forward to the right team email. Enable inbox routing on the DID as above, then let the Flow handle classification that a static recipient list cannot. For a pure archive (no human triage), skip the inbox flag and set forward_emails to a mail archive address plus an archive_path label like legal/incoming — that is the entire setup.

Next steps