Skip to main content

SMS opt-out & opt-in rules

The Opt-out & opt-in rules page is where you manage the inbound SMS keywords that unsubscribe (opt-out) or re-subscribe (opt-in) a contact, and the auto-reply text each keyword sends. Open it from the SMS workspace at Messages → SMS → toolbar: Opt-out Rules, or directly at /messages/sms/opt-out-rules.

Who can open the page

The page is restricted to owner, admin, and developer roles. Billing, viewer, and supervisor roles get a “you don’t have access” screen instead of the editor. If the keyword editor is grayed out for one of your teammates, check their role in the organization settings.

What each rule configures

Each rule is a keyword plus the auto-reply it sends, in one of two groups:
  • Opt-out keywords — unsubscribe the contact (STOP, CANCEL, and so on).
  • Opt-in keywords — re-subscribe the contact (START, YES, and so on).
For each keyword you set: Editing is local until you click Save Rules. Deleting a row asks for confirmation first, and leaving the page with unsaved edits opens a discard prompt — a reload or closed tab uses the browser’s own “leave site?” guard instead.

Language labels are informational

A keyword recognized as a localized opt-out term (STOP, ALTO, STOPPER, SCHLUSS, PARAR, DUR, and the like) shows its language and the markets where it is common — as a hint, not a filter. A rule for ALTO behaves exactly like a rule for STOP and applies to every reply-capable number.

A dedicated route, not an overlay

This editor used to live inside the SMS message list — first stacked above the message-history table, then as a slide-over panel toggled from the list’s toolbar. Both shapes mounted compliance management inside the message-operations view, which made the workspace hard to read. The editor is now its own route, reached by real navigation from the SMS toolbar — the message list no longer embeds it at all. When you plan a layout change like this in your own integrations, keep the same split: message operations on one route, compliance configuration on another.

Where the rules apply

A banner at the top of the page states the scope explicitly:
  • Account-wide. The rules apply to inbound replies on every reply-capable number (a long code or short code that accepts inbound SMS) in your account. They are not tied to a messaging service, so you don’t need to attach one for them to run.
  • Per messaging service. Each service keeps its own opt-out suppression list, managed on the service — see Custom Opt-Out Keyword Lists.
  • Per number. A keyword reply is only recognized on a reply-capable number. An alphanumeric sender ID cannot receive replies, so keyword handling never triggers for those senders. The page shows which of your numbers qualify and warns when none do.
For inbound routing of non-keyword replies, see Inbound SMS routing.

Merging with the platform STOP/START set

Your rules are additive only on top of the platform-level, carrier-mandated keyword set. Deleting every STOP rule from the page still leaves STOP handled at the platform layer — TCPA and CTIA mandate it, and Orbit enforces it regardless of what a tenant configures. Your rules can widen the trigger surface (an alias such as CANCELAR, or a branded opt-in like REJOIN) but never narrow it.

Seeded defaults

On first open, the page seeds a multilingual default set — STOP / UNSUBSCRIBE / CANCEL / QUIT / END, Spanish ALTO, French STOPPER, German SCHLUSS, Portuguese PARAR, and Turkish DUR / IPTAL / RED, each with a localized auto-reply, plus opt-in pairings (START, YES, SUBSCRIBE, and localized SI / OUI / JA / SIM / EVET). Because the defaults are deterministic, a seeded ALTO row appears on every workspace until you edit and save it. Prune the rows your audience doesn’t use, or add regional aliases as new rules — but keep at least one opt-out path per language you send in. A regulator-audited opt-out word is only ever an addition to the platform set; removing your seeded copy of it does nothing either way.

Attach and test

The rules apply automatically to every reply-capable number; there is nothing to attach. To prove a rule fired:
  1. Text the keyword to one of your reply-capable numbers from a handset.
  2. The Inbox shows the inbound turn and the auto-reply in the same conversation.
  3. The contact’s profile shows the flipped consent state, with the keyword recorded in consent history; the Opt-Outs view lists the record.
  4. The Delivery log tracks your auto-reply through queued → sent → delivered.
Before you rely on a keyword in a campaign, send a real inbound and confirm the auto-reply lands and the consent state flips — the same test-then-send discipline as the Test delivery check on Sender IDs. The editor itself always shows whether keyword handling is operational: the status banner names the eligible numbers, or warns with a direct Get a number action when none qualifies.

Round trip: suppress → attempt send → opt back in

Keyword rules above cover the inbound side — a contact texts STOP and the consent flips. You can drive the same lifecycle entirely over the API: suppress a contact programmatically, watch the send-time gate reject a message to that contact, then opt the contact back in and send again. This section runs the full round trip against a test number; the Opt-Outs API reference covers each endpoint’s parameters and role gates.
Suppression and consent are tenant-owned controls — your account decides what qualifies as an opt-out, scoped to your own records. The only platform-level exception is the carrier-mandated STOP/START keyword handling described above, which no tenant setting can remove.

1. Suppress the contact

Create an opt-out row for the phone number and channel. The contact field is an E.164 phone (or an email); the platform resolves it to an existing contact row or creates a stub row scoped to your tenant.
cURL
The call is idempotent — a first-time suppress returns 201 Created, and re-applying the same opt-out returns 200 OK with already_opted_out: true. 201 Created (or 200 OK on a re-apply)
Node (via the SDK’s generic request() escape hatch):
Python:

2. Attempt a send — the gate rejects it

Now send an SMS to the suppressed number. The compliance gate in the send path checks the channel’s opt-out flag before the message is queued, so the request never launches downstream:
cURL
422 Unprocessable Entity
Branch on error.code === "RECIPIENT_OPTED_OUT" in your sender code and treat it as authoritative — retrying while the flag is set returns the same 422. Log meta.request_id on every rejection; it is how support correlates a rejection with the server-side trace. A quota consumed by a rejected send is refunded automatically, and campaign sends skip the suppressed recipient instead of rejecting (the batch keeps the other recipients moving) while still recording the skip on the message row — see the Message Status Lifecycle reference.

3. Remove the suppression and send again

Delete the opt-out row for the contact id and channel — this is the re-opt-in:
cURL
200 OK — returns the updated contact row, and writes a contact.opted_in audit entry with the channel. Re-POST the exact same message body from step 2. The gate now passes and the send queues: 202 Accepted
Follow the row from queued → sent → delivered against its id; the status transitions are enumerated in the Message Status Lifecycle page.
DELETE clears the suppression within Orbit only — the contact’s channel_preferences and your suppression list. A US/CA carrier can hold its own opt-out block independently of Orbit’s records; if a re-opted-in contact still can’t be reached on SMS, resolve that block through your toll-free verification / carrier support channel, not through this API.

Brand-specific opt-outs

If a sender needs branded keyword copy or a region-scoped suppression list, attach a custom opt-out list to its messaging service instead of editing the global rules. For a hosted contact-facing page where recipients manage their own subscriptions, use the Preference center. The per-contact suppression API exercised above manages the consent state those lists and pages read.