BYO SMPP carrier lifecycle
Outbound SMS in Orbit splits two ways: the Devotel wholesale trunk, which is the built-in termination path every tenant already has, and your own upstream carriers: SMPP gateways (or HTTP carrier APIs) that you operate outside Orbit and attach to your account. The SMPP edge model describes the relay and the least-cost routing policy ranks the candidates. This page covers the carrier itself from attach to detach: how it connects, how its health is measured, and how that health changes where your traffic goes. Everything a BYO carrier does stays tenant-owned: the row lives in your tenant schema, the credentials you give it never leave your account, and only your traffic ever crosses the connector.Attach
Attaching a carrier is a row write plus one reconciliation pass:POST /api/v1/messaging/smpp/carrierscreates the carrier with the bind profile your upstream gave you:remoteHost/remotePort/remoteSystemId/remotePassword, plus how you want it treated:scope(allorby_country_mccwith an MCC list),priority(your own cost rank; lower wins), andstatus. The password is encrypted at rest and never returned in full again; reads only expose aremotePasswordSetboolean.- Validation at the boundary — the create hooks reject a host that points at localhost, a private range, or a cloud metadata endpoint, before anything tries to reach it on your behalf.
statusstarts asinactive. Stage the credentials, compare a dry-run quote, and flip toactivewhen you want the route to go live. Settingactiveis the moment the next reconciliation pass provisions the SMPP connector and its routing rule on the platform edge; there is no separate “enable” call.- Failed or pending binds stay off the selection race (see health below), so a carrier you just attached never hijacks traffic on its first tick.
Health: probe, reconciler, and what a failing bind means
The platform measures a BYO carrier two ways, continuously and on demand:- Continuously (the reconciler). Every ~30-second pass reads your active carriers, asks the edge what the connector’s session looks like, and stamps the result back onto the row as
bindStatusandlastSeenAt. The state your dashboard and reads show (BOUND,UNBOUND,BIND_FAILED:<reason>) is a projection of the last pass, never hand-set by the API. A connector that silently dropped its session shows up as a failed bind on the next pass and is nudged restarted so the bind cycle re-establishes. - On demand (
POST /api/v1/messaging/smpp/carriers/:id/test). A synchronous check that the row is well-formed and its stored credential decrypts. It reads the reconciler-stampedbindStatusback rather than blocking on a live dial, and it is rate-limited so a stuck upstream can’t be hammered.
submit_sm handed to a BIND_FAILED / UNBOUND connector drops silently with no app-side error; the bind-state stamp is the only signal your outbound SMS has gone dark short of the slow delivery-rate reconciliation. Correspondingly, route scoring (next section) removes a failed-bind carrier from contention almost immediately, so a broken bind demotes the route instead of letting it keep accepting traffic it can’t deliver.
Where the carrier feeds routing
Carrier health isn’t just a badge on a read; three separate consumers use it:- LCR scoring (
[concepts/least-cost-routing]) multiplies four axes:costScorefrom yourpriority,deliveryQuality(smoothed delivered/terminal over a window),bindHealth(the value above: failed bind ≈ 0.05, unbound ≈ 0.4, stale bound hit slightly, unknown treated neutral), and a smallstickyBonusfor the incumbent. A failed bind nearly removes the carrier from contention; a missing health signal never punishes it. - Route-quality and circuit breakers ([concepts/outbound-route-quality-and-circuit-breakers]) meter the route operationally over your own messages (delivery conversion, DLR latency, acknowledged-but-no-receipt) and, once you opt in, trip a breaker that suspends a sustained-failing route and records the failover channel. A flapping bind both loses its sticky bonus (the LCR failover moment) and, once the degradation becomes a sustained signal, feeds the trip gate.
- Dry-run preview.
POST /api/v1/messaging/smpp/carriers/route-quote(and the policy-awarePOST /api/v1/messaging/lcr/quote) runs the same engine the live gate does, so a preview cannot disagree with a live send.
Detach
DELETE /api/v1/messaging/smpp/carriers/:id soft-deletes: the row stays for your audit trail but status goes to inactive (the same shape a PATCH /api/v1/messaging/smpp/carriers/:id with { "status": "inactive" } achieves non-destructively). The next reconciliation pass removes the SMPP connector and its routing rule from the edge, and the carrier disappears from candidate sets. Two properties matter at the edge:
- In
candidateOrderit does not error. A stale id in your saved policy’s explicitcandidateOrderis dropped at evaluation time; the remaining candidates fold back into scorer order, and the route picks the next-best entrant. A misconfigured (or now-missing) candidate order degrades, it never rejects a send. - In-flight traffic already handed to the carrier finishes on the old route. New sends stop selecting it only after the pass completes, so a detach made during a burst can let a few in-flight messages drain.
Credentials and capacity
Attach is per-tenant isolation like the rest of your account: the row lives in your tenant schema, and no other tenant sees or uses your connector. Two cost/capacity points to plan around:- Cost is not computable. The quote preview prices the Devotel wholesale row off the pricing ladder; a BYO candidate returns
nullfor cents because your upstream spend lives outside Orbit. A fabricated0would mislead the preview. Yourpriorityis the preference rank you give the scorer, not an Orbit price. - Throughput and scope are yours. Two active carriers matching a destination resolve by
priority, and a carrier scopedby_country_mccnever drags cross-region traffic it can’t serve. Setprioritybefore you enable, and scope to the MCC list if the upstream only covers a region.
Example: attach → probe → dry-run quote with preferByo: true
GET /api/v1/messaging/smpp/carriers/route-scores — a read-only snapshot of the exact axis scores the gateway used for your active carriers.
See also
- Least-cost routing (LCR) policy — how the winner is ranked and how
candidateOrderandpreferByosteer it - SMPP edge model — the relay, the per-credential Jasmin user model, and the reconciler contract
- Outbound route quality and circuit breakers — operational metering and the trip gate a degrading route feeds
- Sender resolution — the step LCR runs after