> ## 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.

# The outbound pause gate and the free-channel exemption

> Two classes of outbound holds — balance-driven pauses vs account-lifecycle holds — and why a balance-driven pause bypasses $0-price channels like WhatsApp while an account-lifecycle hold blocks every channel.

# The outbound pause gate and the free-channel exemption

Every send pre-flights two flags on your organization: `outboundPaused` (soft
pause) and `outboundBlocked` (hard block). When either is set, `GET
/api/v1/billing/balance` names the cause in `outboundBlockReason`, and the send
rejects with `SENDING_PAUSED` or `SENDING_BLOCKED` (402). One question decides
what happens next: **is the hold trying to protect the wallet, or to hold the
account?** Balance-driven pauses exempt free channels; account-lifecycle holds
exempt no channel. A `null` reason fails safe and is treated as a hold.

## Two classes of holds

### Balance-driven — "your wallet can't pay for this send"

* **`wallet_empty`** — auto-pause-on-zero. The balance monitor flips
  `outbound_paused = true` as your balance approaches zero.
* **`billing_alert:<id>:<name>`** — a spend or balance threshold you set under
  Dashboard → Billing → Alerts. When the threshold trips, outbound pauses and
  the reason carries the alert's id and display name.

### Account-lifecycle — "the account may not send at all"

* **`subscription_suspended` / `parent_subscription_suspended`** — the account
  (or, under a reseller, the parent account) is suspended.
* **`dunning_failed_3x` / `dunning`** — repeated failed payments.
* **`payment_dispute_active`** — a card dispute or chargeback is open.
* **`null` / unknown reason** — an admin or fraud-console suspend writes the
  hold without a reason label. Absent a recognizable label, the gate fails
  safe and keeps blocking every channel.

## Why the distinction matters — the free-channel exemption

The BYO-credential messaging channels are \*\*$0 on the platform**: WhatsApp,
Instagram, Messenger, Telegram, LINE, Apple Business Messages, Push, and the
web widget (`web_chat`). Devotel is a Meta/channel tech-provider for them, not
a BSP — you pay the upstream provider directly, and the wallet is never debited
($0 platform price falls out of the default rate card).

A balance-driven pause therefore must not refuse a free channel. Blocking
WhatsApp at an empty wallet was a defect: the send costs the platform nothing
and you pay Meta anyway. Send-time, an exempt balance-pause on a free channel
is skipped — the bypass is logged and counted so the exemption stays
observable.

## What's exempted and what is not

* **Balance-driven pauses** (`wallet_empty`, `billing_alert:…`) — bypass for
  \$0-price channels. SMS, email, and every other paid channel reject.
* **Account-lifecycle holds** (suspension, dunning, dispute, admin/fraud
  suspend, any `null` or unknown reason) — rejected for **every** channel,
  free or paid, and that includes NULL: the gate never guesses an unknown
  cause into "probably just the balance."
* **Reseller per-subaccount spend cap** (`subaccount_spend_cap:…`) — **not
  exempted**. Right after this gate, an authoritative per-send cap re-check
  runs for reseller child accounts and does not exempt free channels; honoring
  it here (then blocking at the cap) would be one inconsistent exception. The
  cap stays enforced at its own gate for every channel.

## Recovery while the pause persists

Balance on a free channel? Your send proceeds — only the paid channel pauses:

1. **Resend on a free channel.** A `wallet_empty` or billing-alert pause with
   WhatsApp (or any \$0 channel) still goes through.
2. **Resolve or poll.** For paid channels, treat 402 as terminal, top up or
   trim your offending billing alert under Dashboard → Billing, then poll
   `GET /api/v1/billing/balance` until `outboundPaused` flips `false`. Resumed
   issued credits clear the cached flag immediately instead of waiting out the
   5-minute balance-sync tick.
3. **Fix the cause for lifecycle holds.** Suspension and dunning recover by
   updating the payment method or contacting support — not by topping up.

## Posture map — where each reason is written

| Reason                                                     | Exempt from?                                        | Written by                                     |
| ---------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------- |
| `wallet_empty`                                             | Free channels (bypasses)                            | Balance monitor when balance approaches \$0    |
| `billing_alert:<id>:<name>`                                | Free channels (bypasses)                            | Billing-alert engine when your threshold trips |
| `subscription_suspended` / `parent_subscription_suspended` | No channel                                          | Subscription resolver                          |
| `dunning_failed_3x` / `dunning`                            | No channel                                          | Payment-failure resolver                       |
| `payment_dispute_active`                                   | No channel                                          | Dispute resolver                               |
| `null` (admin/fraud suspend)                               | No channel                                          | Admin console                                  |
| `subaccount_spend_cap:<id>`                                | No channel — enforced at its own post-gate re-check | Reseller cap resolver                          |

Paid channels you're billed for (SMS, MMS, RCS, email, voice, fax, Viber)
follow the same gate — the exemption applies only to the \$0 list above.

Read the full billing pipeline on
[Billing and wallet](/concepts/billing-and-wallet), the ledger mechanics on
[Wallets, credits, and charges](/concepts/wallets-credits-and-charges), and
the person-level operations in [Billing overview](/billing/overview) and the
[Billing API reference](/api-reference/billing).
