> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Outbound route quality and circuit breakers

> How per-operator route health is measured for SMS/MMS delivery — the signals behind the health score, the thresholds and loopback probes you configure, and the circuit-breaker control loop that auto-suspends a degrading carrier route and fails traffic over to an alternate channel.

# Outbound route quality and circuit breakers

When delivery to a destination operator degrades, two independent meters can move. Your **sender reputation** measures how carriers and recipients treat *your* numbers and sender IDs — the sending identity. **Route quality** measures the *outbound carrier route itself*: the per-country, per-operator path your SMS and MMS terminate over, including grey-route and SIM-box tells. A healthy sender over a degrading route still loses messages; a flagged sender over a pristine route still gets filtered. The two views are complementary, and this page covers the route half.

The route-quality surface scores every destination operator you send to, alerts you when a route's health or DLR latency breaches your thresholds, and — once you opt in — a circuit breaker auto-suspends a sustained-failing route, probes its recovery, and records the channel suspended traffic should fail over to. All of it is a tenant-owned control: you set the thresholds, the probe schedule, and whether enforcement runs.

## Why route quality is a separate meter

Sender reputation tells you what recipients and carriers think of *who you are*. Route quality tells you how the *path* to the destination operator is performing. For SMS and MMS that path crosses carrier routes; the common failure modes live there, not on your sender identity:

* **Grey routes** — a carrier disposition where A2P traffic is diverted onto person-to-person pathways to undercut licensed termination. Carriers silently *sink* grey-route traffic: submissions succeed, deliveries never arrive. The tell is a collapsing delivery rate against material send volume.
* **SIM-box fraud** — an intermediary terminates your submission through SIM cards on real devices. The box **accepts** the submission (the route ACKs it) but never returns a real handset delivery receipt, so an infrequently-*accepted* route can be healthy on paper while deliveries flatline.
* **DLR latency inflation** — grey routes hop through extra intermediaries, which inflates the time from submit to delivery receipt. A degrading p95 latency often surfaces before the delivery rate moves.

These apply to SMS and MMS only. Email and WhatsApp deliver over provider APIs, not telco routes, so they carry no route-quality score and never appear here.

## How route health is scored

Each score is computed per destination operator, keyed by the MCCMNC your message records (the mobile country + network code of the handset that received it). For each operator, the scoring reads your own `messages` table over a rolling window — the same canonical status filters the dashboard's message stats use, so a route score can't drift from what you see there:

* **Delivery conversion** — *delivered ÷ terminal messages*. A sustained drop on volume is the classic grey-route tell.
* **DLR latency percentiles** — p50, p95, and p99 of *delivered time − sent time*, computed in the database with `percentile_cont` over the same window. The p95/p99 are the early-warning meter for intermediary hops.
* **Acknowledged-but-no-receipt rate** — the share of terminal SMS the route ACK'd (`submitted_no_receipt`) without ever returning a delivery receipt. This is the SIM-box "fake accept" tell.

Signals combine into a transparent **health score of 0–100** per operator (100 is a clean route) and a coarse band — healthy, degraded, poor, or critical. A route is further flagged as a grey-route / SIM-box suspect when the corroborating tells cross threshold together on a material sample. A signal with no coverage contributes nothing — a missing signal must never invent a problem, or absolve a route your other signals still flag.

You tune what the evaluation treats as a breach: the minimum health score, the p95 latency ceiling, the minimum sample volume before any alert can fire, whether a grey-route flag should alert, and the alert severity.

## The advisory endpoints

The read side is advisory by default — scores, thresholds, and probes are surfaces you query; nothing is suspended until you enable the breaker.

* **`GET /api/v1/messages/route-quality/scores`** — the scored per-operator routes for a 1–90 day window (default 7). Each row carries the health score and band, the delivery rate, the latency percentiles, the acknowledged-but-no-receipt rate, and any grey-route flag.
* **`GET /api/v1/messages/route-quality/settings`** — read your current thresholds and loopback-probe schedule.
* **`PUT /api/v1/messages/route-quality/settings`** — set the breach thresholds and the loopback-probe configuration, persisted in your organization settings.
* **`POST /api/v1/messages/route-quality/alert-check`** — evaluate the current window against your thresholds and notify on breaches.

### Loopback probes

Scores above are **passive** — they measure the traffic you already send. A **loopback probe** is active: you schedule periodic test sends to a named destination operator (an `mccmnc` value plus a friendly label, with a cadence of 5–1440 minutes) so a route you send little organic traffic to still gets measured between bursts. The probe schedule is configuration only — it is consumed by the existing softswitch send pipeline, which dispatches the probe; this surface stores it, it never sends anything itself.

## The circuit breaker: from alert to control loop

The advisory layer pages you; the circuit breaker acts. Once enabled it is a per-route state machine layered on the same threshold evaluation, moving each operator route between three states:

```text theme={null}
closed ──(N consecutive breaches)──> open ──(cooldown elapsed)──> half_open
  ^                                                            |
  └──(M consecutive clean checks)──<breach-free returns OR breach → open>
```

* **closed** — the steady state. Traffic flows normally.
* **open** — the route is auto-suspended: the breaker records it as tripped, and the operator's configured failover channel applies. A route only transitions to `open` **after your `trip_after_consecutive_breaches` consecutive failing checks** — a sustained-breach gate so a single noisy window never flaps a route offline.
* **half\_open** — a recovery probe. After `cooldown_minutes` elapse from the last trip, the breaker moves the suspended route to `half_open` and deliberately lets the next checks through. If the route stays clean for `half_open_recovery_checks` consecutive checks, it recovers to `closed`. A single breach during the probe **re-opens the circuit immediately** and starts the cooldown clock over.

The breaker configuration lives alongside the route-quality thresholds in your organization settings:

* **`enabled`** — the master switch. It defaults to **off**, so until you opt in the breaker never trips and never suspends: you get the same advisory-only behavior described above.
* **`trip_after_consecutive_breaches`** (default 3) — how many consecutive breaching checks move a route from `closed` to `open`.
* **`cooldown_minutes`** (default 30) — how long a route stays `open` before the half-open probe begins.
* **`half_open_recovery_checks`** (default 2) — how many consecutive clean checks during the probe confirm recovery.
* **`failover_channel`** — where suspended traffic diverts. Restricted to rich-messaging channels that deliver over provider APIs rather than telco carrier routes — `whatsapp`, `rcs`, `viber`, or `telegram` — so a failover can't just land on another degradable carrier route.

### The failover channel

When a route is `open`, the recorded `failover_channel` is a directive the multi-channel fallback chain consults: suspended traffic maps to the configured channel if the recipient is reachable there, per the chain described in the [cross-channel fallback concept](/concepts/cross-channel-fallback). While the circuit is `half_open`, traffic is deliberately allowed back through to test recovery — that probing state is *not* a suspension; only `open` suspends. The decision each send consults (suspended or not, and which failover channel) is exposed as a decision read alongside the state.

## Guardrail: measurement and enforcement, never a new send path

<Warning>
  The entire route-quality and circuit-breaker surface is **read-only over what you have already sent, plus configuration**. It selects no outbound route and dispatches no message itself — scoring is an aggregate over your existing `messages` rows, the thresholds and probes are settings, and the breaker is a decision over persisted breach state. The softswitch remains the **sole MT path** for outbound voice and SMS; loopback probes and failover traffic re-enter that canonical pipeline. Nothing here wires an alternate outbound provider.
</Warning>

## Tenant-owned posture

Every control on this page is owned by you, scoped per tenant: the thresholds, the probe schedule and labels, the severity, and whether the breaker enforces or only advises. No cross-tenant aggregation feeds these scores, and a route suspension applies to your tenant's traffic alone. If circuit state or config is not yet present (a brand-new tenant, a never-configured breaker), the surface degrades to an empty reading — never an error.

## See also

* [Cross-channel fallback](/concepts/cross-channel-fallback) — the channel chain the breaker's `failover_channel` records into
* [Multi-channel DLR fallback](/concepts/multi-channel-dlr-fallback) — how delivery receipts cross channels on failover
* [Numbers and lifecycle](/concepts/number-lifecycle) — the sibling suspension/reactivation flow for a sending number
* [Delivery lifecycle](/concepts/delivery-lifecycle) — the message status DAG the scorers read from
* [Glossary: Grey Route](/reference/glossary) — the grey-route signal definition, including why it is a route-health problem
* [Messaging API reference](/api-reference/endpoints/messaging) — the full endpoint surface, including route quality
* [Send gating and quiet hours](/concepts/send-gating-and-quiet-hours) — the pre-send compliance layer, a separate tenant-owned gate
