Skip to main content
Back to blog

Opt-Out Scope in Orbit — Why Your WhatsApp STOP Blocks SMS Too

A recipient who texts STOP on WhatsApp is suppressing the phone number, not the thread. Orbit records the revocation at scope `all`, so the same number is fenced on SMS, RCS, voice, and every other channel that can reach it. This explainer walks the scope model, why the default is deliberately over-inclusive, and the one way to hold a narrower posture.

Orbit Editorial Team

Answer first: on Orbit, a STOP keyword is keyed to the address, not the thread it arrived on. When a recipient texts STOP on WhatsApp, the platform writes one suppression entry against that phone number at scope all — the widest scope in the model — and every send gate that can reach the number honors it: SMS, RCS, voice, MMS, push, the lot. The WhatsApp conversation is one of many channels the number can reach, and the revocation covers all of them. This is deliberate: under-honoring a revocation is a TCPA violation, while over-honoring is merely conservative. The endpoint-level reference is the Opt-Out & Suppression Lists page; this post is the reasoning behind the default and the terms on which you would ever narrow it.

Scope is a property of the revocation, not the conversation

Every suppression entry on the ledger carries a channel scope. The full set is all, sms, voice, whatsapp, email, push, telegram, messenger, rcs. Scope answers one question: which send gates does this revocation fence?

Two facts about the model drive everything else:

  1. The address is the unit. A phone number is addressable on WhatsApp, SMS, RCS, voice, and MMS at once. A recipient who says "stop messaging me" on any one of those channels has expressed a preference about the recipient, not about a transport. When the revocation arrives as a keyword on a phone number, Orbit writes it at scope all — the number is fenced everywhere it can be reached, in one ledger write.
  2. Not every entry point is equally broad. Scope is chosen per entry point. The keyword STOP on a phone number, the Preference Center, and the Consent API (opt_in: false) all record scope all. An email unsubscribe — which suppresses an email address, an identifier that exists on only one channel — scopes to email. A bulk CSV import of phone numbers defaults phone rows to all and email rows to email, with a channel column to override per row.

The asymmetry is the point the "why does my WhatsApp STOP block SMS?" question actually probes: the sender expected the STOP to silence the WhatsApp thread and leave the SMS program live. The ledger disagrees, because the recipient's signal was about the phone number.

Why the default is deliberately over-inclusive

Three pressures converge on the same answer.

Revocation parity is litigated, not debated. The FCC's TCPA rulemaking codified that a revocation arriving by any reasonable means binds every channel the original consent covered. A recipient who granted you SMS consent and then says STOP on WhatsApp has revoked in a reasonable form; arguing the revocation was channel-bound is an argument you make to a plaintiff's expert, not a posture you run in production. Scope all makes parity a property of construction, not of policy documents.

Under-honoring and over-honoring are not symmetric risks. If the matcher demanded channel-scoped revocations, a real STOP would occasionally fall through — and a missed STOP is a TCPA violation at $500–$1,500 per message, uncapped at scale. If the matcher over-applies, a recipient who wanted to silence one channel gets silenced everywhere — annoying for that recipient, recoverable through a fresh opt-in, and never a regulator's exhibit. The keyword matcher is intentionally over-inclusive for the same reason: it strips zero-width and bidi characters, folds case in a pinned locale, and fallthrough-matches every language's keyword set, because the penalty gradient points one way. The consent-proof posture treats the same asymmetry on the grant side.

The recipient's mental model is "stop messaging me." Carrier practice teaches recipients that STOP ends messages, full stop — CTIA guidance describes the keyword as ending the program, and recipients do not distinguish WhatsApp-from-your-brand from SMS-from-your-brand when they exercise it. A platform that honored the revocation on one channel while keeping others live would surprise the person the keyword exists to protect.

What actually happens when the WhatsApp STOP lands

The inbound webhook for the WhatsApp Business API delivers the recipient's message. Orbit normalizes the body (NFC, invisible-character strip, locale-pinned casefold, whitespace collapse) and matches it against the carrier-mandated keyword sets plus any per-list additions you configured under Settings → Compliance → Opt-out Lists. On a match, one suppression entry is written: the sender's phone number, scope all, source user_keyword. The same write is what the voice and dialer gates read — the number stops receiving calls too, not just messages.

From that write, every send surface enforces:

  • API sends fail synchronously with HTTP 422 and RECIPIENT_OPTED_OUT — including an SMS send to the number that STOP'd on WhatsApp.
  • Campaign sends skip the recipient silently (reason: "opted_out") so the batch keeps moving; the per-recipient report is where you see it.
  • Voice and dialer traffic is fenced on the same entry — per the Note on the suppression docs page, a keyword STOP writes no separate DNC row, but the call gates read the scope-all suppression directly.
  • Inbox replies and journeys hit the same ledger — suppression is a property of the address, so no send path has its own list.

Reversal is equally direct: the recipient's START keyword, or a Consent API call with opt_in: true, revokes the suppression entry. The ledger keeps the row — marked revoked with a timestamp — because history is evidence, not clutter.

When a narrower scope is legitimate — and how to hold it

There are programs where channel-scoped suppression is the right posture. The canonical case: your WhatsApp program is a support channel, your SMS program is the marketing channel, and the recipient's "stop the marketing" intent should not kill the support thread. You hold that posture through exactly one mechanism — the bulk import `channel` column. A CSV row with phone and channel=sms writes a scope-sms entry; SMS is fenced, WhatsApp is not.

That is the only sanctioned narrowing path, and it comes with three constraints:

  • Keywords are never narrowable. Any recipient-hinted STOP on a phone number asserts scope all by construction. Your own import can be narrow; the recipient's word cannot. Per-list keyword configuration is additive to the carrier-mandated sets — you can extend, never reduce.
  • You own the parity argument. If counsel is comfortable channel-scoping revocations for your program design, the import column encodes that decision deliberately, per row. What you cannot do is let the scope default silently while assuming the narrow reading — the ledger records what you declared, and an auditor reads the declaration.
  • Email was never `all` anyway. Email addresses are scope email from every entry point, so the widening question is a phone-number question only.

Before you narrow, run the verify loop from the docs: import the scoped row, send a test SMS in sandbox and confirm the 422, then attempt the same send on WhatsApp and confirm it submits. Enforcement and scope are separate checks; both need to pass.

Reading the ledger back

Scope is visible everywhere the ledger surfaces. In the dashboard, Audience → Opt-outs shows each entry's channel scope next to the address. The export endpoint (GET /compliance/suppression-list/export) carries a channel column per row and accepts a channel filter, so an audit can answer "which addresses are fenced at all?" in one query. The consent history endpoint shows the same revocation from the grant/revoke trail side, with the entry point that wrote it — keyword, Preference Center, API, or import.

The practical audit question is not "why did the STOP block SMS?" — it is "which entry point wrote this revocation, and is the scope it declared the scope our counsel signed off on?" The ledger answers both, per row.

Frequently asked questions

A recipient STOP'd our WhatsApp program; our SMS campaign skipped them. Is that a bug?

No. The keyword revocation is keyed to the phone number and written at scope all, which the SMS gate honors. The campaign per-recipient report shows the skip with reason: "opted_out". If your program genuinely needs channel-scoped support-channel posture, suppress through the bulk import channel column — but the recipient's own keyword is never narrowable.

How does the recipient get SMS back after a WhatsApp STOP?

A fresh opt-in — the recipient texts START, or you record opt_in: true through the Consent API. The entry flips to revoked (never deleted), and the fence drops. Until that event exists, treat the address as suppressed on every channel.

Does the scope-all write also block outbound calls?

Yes. The voice and dialer gates read the same suppression ledger, so a number that opts out on any channel stops receiving calls as well as messages. The mechanism differs by entry point — a bulk CSV import of phone numbers additionally mirrors onto the DNC list, while a keyword STOP is fenced through the suppression entry itself — but the call is blocked either way.

We import a legacy suppression list. Which scope does it get?

Phone and WhatsApp rows default to scope all; email rows to scope email. Add a channel column to the CSV to override per row. Run the import with dry_run=true first and read the by_channel counter in the preview — that is the scope distribution about to be written, before you commit it.

Opt-Out Scope in Orbit — Why Your WhatsApp STOP Blocks SMS Too — Orbit by Devotel