The MT termination model
Everything you send outbound — an SMS, a WhatsApp template, an MMS, a fax, a dialed call — is MT (mobile-terminated): traffic that ends on a handset or carrier network. The sibling pages each own one slice of that path: sender resolution names the sender, least-cost routing ranks the upstream route, unified termination routing decides the channel, and the queued-to-sent primer owns the status vocabulary. None of them answers the newcomer’s actual question: how does an outbound call or message physically leave Devotel Orbit and terminate? This page is that answer — the travel modes, the gates in order, the dispatch mechanics, the exit planes, the feedback loop, and the cost, all named once and then delegated to the owning page. Everything here is tenant-owned configuration: the flags, allowlists, carriers, and caps below are settings you carry, evaluated against your traffic only. The model is the same for every surface that generates outbound traffic —POST /api/v1/messages, campaigns, flows, journeys, the dialer, and the SMPP binds you connect.
1. Two travel modes — real-time session vs scheduled dispatch
Outbound termination travels in one of two shapes, and which one you are in decides almost everything downstream:
The mode is chosen by which surface you call, not by a routing decision: the voice call endpoints open a session; the message endpoints enqueue a dispatch. Inside one mode, the second selection problem — which exit plane carries it — is shared, and the rest of this page treats both modes through the same gates, dispatch pipeline, planes, and feedback loop.
2. The pre-dispatch gate chain, in order
Before anything terminates, the send is admitted through a chain. Every gate reports a refusal with a documented code, in this order, and the first refusal ends the attempt:- Request guards and admission — auth, rate limits, idempotency replay, and payload validation; API request guard pipeline owns the ordered table.
- Wallet pre-flight — an exhausted wallet refuses with
402 INSUFFICIENT_BALANCE; the billing gate chain owns the full chain, including the atomic check-and-decrement the send lands on afterward. - Org outbound flags — a balance-driven
SENDING_PAUSED(soft) or an account-lifecycleSENDING_BLOCKED(hard), both 402. Balance-driven pauses exempt the $0-on-platform free channels; account-lifecycle blocks exempt nothing. The pause gate and free-channel exemption owns the reason taxonomy. - Country allowlist — a resolved destination country not on your opt-in list refuses with
422 COUNTRY_NOT_ALLOWED. This list is yours: with no list set, or an unresolvable destination, the send passes. Country allowlist gate owns the model. - Recipient gates — quiet hours (recipient-local, your window), suppression and opt-out lists, duplicate-content claims, frequency caps, and throughput ceilings. Send gating and quiet hours owns the admission order and per-gate defaults. Voice to US recipients also carries the federal TCPA dialing-window guard, the one platform-owned gate with no tenant toggle; voice pre-send gate chain owns that order.
- Channel capability and template gates — the channel must support the payload (an MMS on an SMS-only sender, a WhatsApp template whose approval lapsed) and the sender must resolve. The channel capability matrix and sender resolution own those surfaces.
3. Dispatch mechanics — enqueued vs direct, the worker fleet, retry budgets
Once admitted, dispatch takes one of two paths per async processing model:- Enqueued dispatch (the default). The API inserts the row (
pending → queued) and returns202; a worker in the webhook-worker staff claims it (sending), performs the provider handoff, and stamps the wire result. Scheduledsend_atrows park asscheduledand join the same queue at fire time. Queue names and worker concurrency are declared in one central registry, so the health panel reads backlog and drain rate side by side; a persistentsendingcluster means the provider endpoint is stalling, not the queue. - Direct (in-call) dispatch. A narrow set of immediate-response paths sends inside the request and answers synchronously, with a small bounded in-call retry budget. Only when every in-call attempt fails does the call site escalate the envelope to a durable retry queue with a long schedule (the
email-retryanddlr-retryshapes), which a worker drains later.
409 DEDUCT_IN_FLIGHT back-off rather than a second charge. The async processing model page owns the producer/consumer split and failure semantics; the scheduler fleet model owns the worker staff itself.
4. The terminal-routing planes — softswitch default, BYO by policy
Termination exits the platform on one of two planes, both tenant-controlled:- The Devotel wholesale softswitch (the default). Outbound voice and SMS terminate through Devotel’s wholesale softswitch trunk — SIP/RTP for calls, SMPP binds into the SMS leg. This is the only provider involved unless you bring your own; no outbound traffic is routed anywhere outside that boundary.
- Your BYO carriers (opt-in). You connect an upstream carrier (an SMPP bind for SMS, a SIP trunk for voice), and your least-cost routing policy decides the order — rank BYO strictly by cost, by the composite quality score, or prefer-BYO-first — with the softswitch entry as the leaderboard to beat. The dry-run quote endpoint ranks routes for a destination without moving traffic, and route health and circuit breakers then meter whichever plane carries live traffic. The BYO carrier lifecycle page owns connection setup.
Whichever plane carries the send, the per-message
provider column and the route-trace timeline (GET /api/v1/messages/:id/trace) answer “which leg did this take” in one call.
5. The status feedback loop — queued to terminal disposition
Dispatch is only half the loop; the other half is the receipt stream that closes it:- Forward arc —
pending → queued → sending → sent, each transition fanning amessage.*event to your webhook subscribers.senton a receipt-capable channel is a submission acknowledgement, not a delivery claim. - Terminal disposition — a carrier DLR resolves the row to
delivered/reador to the failure codes above. On a no-DLR channel (Meta DM),sentis the provider’s best-ever answer and the row resolves to thesubmitted_no_receiptsentinel after its grace window; on a receipt-capable channel whose receipt never arrives, the row ages honestly toundelivered. Delivery lifecycle owns the per-status meanings; the queued-to-sent primer owns the whole vocabulary inline. - Two DLR planes — carrier-plane receipts arrive
throughthe provider into a status update; send-side receipts are encoded back out to you as webhook POSTs or SMPPdeliver_sm. DLR model: two planes owns the split; the send-side DLR model owns the canonical six-state vocabulary your receiver merges against.
initiated → ringing → answered → completed with its dispositions, each event a webhook on the voice lane. Your integration never polls — the row is queryable GET /api/v1/messages/:id for repair reads, but the pipeline advances and reports itself.
6. Cost surfaces for MT
Termination spend resolves on four surfaces:- Per-channel rate cards — price per SMS segment, per WhatsApp conversation, per voice minute, per fax page. Pricing and rate resolution owns the attribution chain a destination’s per-unit price walks.
- Wallet debit mechanics — the per-channel fund path of the billing gate chain: a voice hold of up to two minutes settled per-minute at hangup, per-segment SMS debits at send.
- LCR interplay — the policy that trades the softswitch trunk against your BYO carriers; the dry-run quote shows an estimated unit price for the softswitch and honest
nullcents (unknowable upstream spend) for BYO rows. - Per-hop price bounds on cascades —
max_pricerejects a pricey hop before billing andmax_total_pricetrims a waterfall’s cumulative tail, per the notify cascade cost model.
7. A worked walk — one SMS end to end
POST /api/v1/messages with {"channel":"sms","to":"+14155552671","sender":"+14155550100","body":"Hi"} walks the whole model:
- Admission and gates — the guard pipeline accepts; the wallet pre-flight passes; org flags are clear;
+1is on your allowlist (or no list is set); no suppression entry and no quiet-hours block for the recipient; the sender resolves. Refusal codes along this span:402 INSUFFICIENT_BALANCE/ 402SENDING_PAUSED|BLOCKED/422 COUNTRY_NOT_ALLOWED/ gate-specific 422s. - Enqueue and dispatch — the row inserts as
queuedand the response returns202 {"message_id":"msg_9f2"}; a send-queue worker claims it assending. - Termination — the LCR policy ranks the softswitch trunk against your BYO carriers; the winner’s SMPP bind takes the
submit_sm; status goessent. With unified termination rules enabled and anenforcematch, the channel itself may switch before the plane ranks (see unified termination routing). - Feedback — the carrier’s DLR lands:
delivered, terminal. If 30 minutes pass with no receipt, the no-DLR sweep ages the row toundelivered; a genuinely late DELIVRD still flips it back under the transition DAG merge rules. - Cost — one per-segment debit posts on the wallet under the message’s charge key, visible in usage records the same minute.
8. A worked walk — one voice call end to end
POST /api/v1/voice/calls (or a UCaaS extension dialing out to the PSTN) walks the second travel mode:
- Gates — the same chain in voice order: wallet pre-flight, outbound flags, country resolution, the federal dialing-window guard and your voice gates, per voice pre-send gate chain.
- Session open — instead of a queue row, the voice plane opens a SIP session over the softswitch and takes the up-to-two-minute wallet hold at dial;
initiatedhits your call webhooks. - Termination — SIP signaling negotiates the PSTN leg, a BYO SIP trunk wins only if your policy ranks it first, and RTP media flows for the call’s life; the row walks
ringing → answered → completed. - Settlement — at hangup the settle debits the delta above the hold at the FX rate locked at hold; an unanswered call refunds the hold in full.
- Feedback — the call recording pipeline closes the artifact loop and the voice events close the status loop, same as messages, on your subscribed endpoints.
See also
- Outbound billing gate chain — the wallet and flags span of the gate chain, in order
- Send gating and quiet hours — recipient gates and admission order
- Country allowlist gate — the opt-in country gate, and why it is yours
- Unified termination routing — the channel-switching rule engine beside gate-chain admission
- Least-cost routing — scoring softswitch vs BYO routes with the dry-run quote
- Async processing model — queue registry, worker staff, and retry budgets
- Delivery lifecycle and DLR model: two planes — the status loop and receipt planes
- Notify cascade cost model — per-hop price bounds and the cumulative waterfall cap
- Voice call lifecycle — the full session-mode state machine