Configure your LCR policy (Devotel-first vs BYO-first)
The least-cost-routing (LCR) policy is your per-organization preference for ordering outbound SMS routes: Devotel’s wholesale trunk first, or your own connected (BYO) carriers first. This guide walks the whole workflow — attach a BYO carrier, read the current policy, preview the ranked route order without saving anything, and commit the change. The model behind the scoring lives on the LCR concept page; this page is the task.When this applies
Configure an LCR policy when all three of these are true:- You send SMS in volume, so route order moves real money or real delivery rates.
- You have your own upstream carrier relationship(s) — an SMPP account you can hand Orbit as a BYO carrier — or you’re about to attach one.
- You want to steer the route order (cheapest BYO first, BYO-before-Devotel, or an explicit order) instead of the out-of-the-box default.
Decision table
Four fields make a policy. Every field is optional on a write; omitted fields fall back to the defaults shown.
The safe starting point — and the platform default — is
trafficType: "quality" with preferByo: false. Devotel’s trunk leads, and your BYO carriers follow in quality order; a degraded BYO bind never outranks the healthy trunk on price alone. Flip to "cost" only when per-message margin on your own carrier contract genuinely outweighs delivery quality for your destinations, and verify that with the preview before saving.
Read the current policy
data envelope:
404.
Write the policy
PUT upserts the policy idempotently — re-sending the same body is a no-op — and writes an audit entry (lcr_policy.updated) with the effective values, so a route-order change is always attributable to a user and a timestamp.
candidateOrder with the reserved devotel id plus your BYO carrier ids (the id values returned when you register the carriers — see Attach a BYO carrier):
trafficType: "cheapest"), a non-boolean preferByo, or a 422-inducing shape fails with a 422 and changes nothing.
Preview before you commit
You don’t have to save a policy to see what it would rank. The dry-run quote takes a destination, an optional message quantity, and optionally a policy body; with nopolicy it evaluates your saved policy, and with one it evaluates the request-scoped body so nothing commits.
- The Devotel entry carries a real
estimatedUnitCentsandestimatedTotalCentsoff the same pricing ladder the ledger settles;priceSourcenames where the price came from (rate_card, an override, or the default lane). - A BYO entry always shows
nullcents, because what you pay your own upstream for that destination isn’t computable here — a fabricated0would mislead the comparison. ThecompositeScoreis the BYO entry’s competitive figure instead: cost × delivery quality × bind health × sticky bonus, multiplied (see How routes are scored). winnerId/winnerKindmarks the route the live gate would pick under the evaluated policy, and every candidate carries its integerrankand a plain-languagereasonyou can show in a console.
Attach a BYO carrier
Your BYO carrier is the upstream account Orbit binds to over SMPP. Register it once, keep it healthy, and the LCR candidates update on their own.- Register the carrier with
POST /api/v1/messaging/smpp/carriers— the bind coordinates (remoteHost,remotePort,remoteSystemId,remotePassword,bindType), a memorablelabel, ascope("all", or"by_country_mcc"withscopeFilter.mccsto limit it to specific destination operator lists), and apriority. Worked requests, in cURL and SDK form, live in the SMPP API reference; the bind lifecycle is covered in Connect via SMPP. - Give it a cost figure.
priorityis a monotonically decreasing cost score:0maps to a full 1.0 cost score, the default100to 0.5, and300to 0.25 — set it intentionally; a cost-mode policy ranks on exactly this number. - Keep the bind healthy. A failed SMPP bind nearly removes the carrier from contention; an unbound one is demoted over a bound peer; and a bind that hasn’t been heard from for a while takes a smaller, partial hit. The dashboard renders the breakdown under Developer → SMPP → Route scores, and
GET /api/v1/messaging/smpp/carriers/route-scoresreads the same composite over the API.
"by_country_mcc" carrier only enters the candidate set when the destination resolves to one of the MCCs in scopeFilter.mccs.
Cut over
Change a live policy the way you change any route-shaping config — stage, check, then flip:- Stage explicitly. Set the candidate list you intend (
candidateOrder), not a nakedpreferByoflip where the BYO family rank surprises you. Preview it withPOST /messaging/lcr/quoteand confirm thewinnerIdon a handful of your real destinations. - Save.
PUT /messaging/lcr/policywith the staged body. - Watch failover. Rank order isn’t the whole story — a lead route that degrades hands traffic to the next ranked route. Track that with Outbound route quality and circuit breakers and the runbook at Configure route-quality thresholds. If the cutover hurts delivery, flip
preferByoback tofalse(or restore your savedcandidateOrder) — a one-call rollback.
See also
- Least-cost routing (LCR) policy — the scoring model this page configures
- How routing picks a sender — and where a reply lands — where LCR sits in the outbound chain
- Messaging credentials API — the API-reference surface for the credentials these carriers run on
- Connect via SMPP — the BYO carrier bind lifecycle
- SMPP API reference — carrier register/list/delete with worked requests
- Configure route-quality thresholds — monitor the failover path after you cut over