Skip to main content

Outbound fax workflow

The Fax channel page covers the channel’s request fields, error codes, and limits. This guide is the send-side walkthrough: from a document URL to a delivered fax, including how billing, receipts, and retries behave along the way. The receive side is covered separately in Inbound fax routing. You will:
  1. Understand how the channel terminates
  2. Understand the on-success-charge model
  3. Send a fax
  4. Consume delivery receipts and handle failures
  5. Choose the right document format and quality

Prerequisites

  • A fax-capable number on your account (see Buy numbers). The from field on every send must be one of your numbers.
  • An API key from Settings → API Keys (a dv_live_sk_… live key).
  • A publicly reachable HTTPS URL for the document you are sending. The carrier fetches it directly — Orbit does not re-host it — so the URL must resolve from the public internet, and http:// is rejected at send time.
  • A public HTTPS endpoint if you want per-send delivery callbacks (status_callback). Without one, outcome events reach your tenant-wide event bus subscribers anyway.

1. How outbound fax terminates

Outreach channels on Orbit are terminated deliberately. Voice calls and SMS exit only via the Devotel wholesale softswitch. Fax (T.38/G.711) and MMS are the two named exceptions: fax transmissions terminate on Telnyx Programmable Fax. When you send a fax, Orbit dispatches your document to the Telnyx fax connection resolved for your org — a tenant-assigned connection if you attached one in tenant settings, otherwise the platform default. That split matters operationally in two places:
  • Billing is on Telnyx carrier confirmations (section 2), not on the softswitch call detail records your voice traffic generates.
  • Failure diagnostics come from the carrier’s own vocabulary — busy, no answer, no fax tone, poor line quality — and Orbit passes them through unchanged (section 4).
If your org needs a dedicated Telnyx Fax application (compliance, data residency), set the tenant’s fax_connection_id in tenant settings; all subsequent sends resolve that connection before the platform default.

2. The on-success-charge model

A fax is only billed when the carrier confirms successful transmission. If the attempt fails — busy, no answer, no fax tone, poor line quality, handshake rejection, or an internal error before dispatch — your wallet is not charged for it. The mechanics:
  1. AcceptedPOST /api/v1/messages/fax validates and records the message. Nothing is billed at this point.
  2. Transmitting — the carrier runs the T.38 handshake and transmits pages. Still nothing billed.
  3. Carrier verdict — when the carrier confirms the transmission succeeded, the charge is applied and the message moves to delivered. Any path ending in failed is free.
A side effect worth knowing: the balance ledger for a fax settles asynchronously. The send response shows no charge yet; the wallet deduction appears when the carrier’s success confirmation lands, alongside the delivered event. The per-send idempotency key (orbit-fax:<message-id>) dedups at the carrier, so a client retry or a queue-worker re-dispatch of the same message record can never double-bill you.

3. Send a fax

Sending goes through the unified Messaging API at POST /api/v1/messages/fax:
The response:
The returned data.id is the Orbit message ID you correlate on — webhook events carry the same message_id, so no provider-side mapping is needed. The provider fax ID attaches asynchronously as external_id and is readable via GET /api/v1/fax/:id. Validation errors surface at send time, not after: an invalid E.164 to returns 422 INVALID_PHONE_NUMBER, a missing from or media_url returns 422 MISSING_REQUIRED_FIELD, and an orphaned status_callback_secret (set with no status_callback URL) returns 422 VALIDATION_ERROR. The full field table and error catalogue are on the Fax channel page.
status_callback is a per-send override. When you set it, delivery events for this message POST to that URL instead of only the tenant event bus. Pair it with status_callback_secret — the secret signs every callback to the URL, and Webhook security shows the verification recipe.

4. Delivery receipts and failure handling

An outbound fax moves queuedsendingsentdelivered (or failed). Each transition emits a channel-agnostic event — message.delivered or message.failed with channel: "fax" (there is no separate fax.* event stream). The event payload carries message_id, status, state_class, and is_terminal. Subscribe per the events catalogue. Two terminal-read differences from SMS semantics:
  • sent is non-terminal for fax. The carrier has completed transmission to the end station, but the receiving fax machine may still be confirming the final pages. Treat sent as “carrier-completed” and wait for delivered before telling a customer “they have it.”
  • failed is single-attempt. Orbit never retries a fax that has reached failed; re-sending is your call. The queue worker only re-dispatches a message that is still queued (e.g. a transient provider 408), and the carrier idempotency key prevents any duplicate transmission from that re-dispatch.

Failure-handling recipe

Match error_code on message.failed events — the values are the carrier’s own diagnostics, passed through unchanged:
Whichever consumer you build:
  • Verify the X-Orbit-Signature header and reject deliveries older than five minutes (Webhook security).
  • Return 2xx quickly; only 2xx counts as delivered, and retries continue for anything else.
  • Deduplicate on the event data.id — delivery is at-least-once.
If webhooks are unavailable, poll GET /api/v1/fax/:id/status (cached about 10 seconds) — note it returns 404 until the transmission has been dispatched, so poll GET /api/v1/fax/:id for the record first if you just got the send response.

5. PDF vs TIFF and picking a quality

The carrier accepts PDF or TIFF, single file, up to 50 MB. Multi-page documents are supported with no separate page-count cap.
  • PDF is the right default for everything business-generated: contracts, invoices, forms, letterheads. Text stays crisp at every resolution and file sizes are small.
  • TIFF is for faxes composed of scanned image pages — a scanned wet-signature or a photographed document. If your source is a scan, TIFF avoids a lossy image-through-PDF round trip, but a generated PDF still beats TIFF on size and handshaking stability.
The quality field trades resolution against handshake length: Practical rule: start at high, and on a poor_line_quality failure re-send at normal — the workflow in section 4 already encodes that fallback.

Next steps