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

# Opt-Out Entry Points by Channel

> Which messaging channels recognise an opt-out automatically, what each recognition path writes to your consent and suppression ledgers, and the step-by-step logging procedure for channels where a STOP is not parsed.

# Opt-Out Entry Points by Channel

A revocation request arrives on whichever channel your contact happens to be using. On some channels Orbit recognises and records it on its own; on others nothing parses a `STOP`, so the request only becomes a suppression entry when your team logs it. This page lists, per channel, what is recognised automatically, what each path writes, and exactly how to record revocations that arrive on channels without automatic recognition.

> [!NOTE]
>
> These are **tenant-owned** controls. The matrix below describes what the
> platform recognises today; the keyword vocabulary on the editable channels
> remains yours to seed, prune and extend per the
> [alias table](https://docs.orbit.devotel.io/compliance/opt-out-keyword-alias-table.md), and the manual
> logging procedure for the non-automated channels is your team's to run.

***

## Per-channel recognition matrix

| Channel | Auto-honoured entry | Confirmation reply | Suppression scope written | Ledger `source` |
| - | - | - | - | - |
| `sms` | The full STOP/START alias vocabulary in every shipped language, plus your custom opt-out rules | Yes, an acknowledgement is sent on your number | `all` — fences SMS, WhatsApp, RCS and Viber at once | `inbound_keyword` in consent history; `user_keyword` in the suppression export |
| `whatsapp` | The same STOP/START alias vocabulary on inbound replies to your WABA numbers, plus your `whatsapp`-scoped rules | Yes | `all` | Same as `sms` |
| `telegram` | The `/stop`, `/unsubscribe`, `/cancel` and `/start` slash commands | Yes, the bot replies directly | `telegram` — scoped to the chat, see the [Telegram scope note](https://docs.orbit.devotel.io/compliance/opt-out-keyword-alias-table.md#how-telegram-scope-differs-from-a-phone-number-stop) | `telegram_inbound` |
| `rcs` | Your `rcs`-scoped opt-out rules | Yes, plus the rule's auto-reply when one is set | `all` | `KEYWORD_RULE` when a custom rule fired |
| `viber` | Your `viber`-scoped opt-out rules | Yes, plus the rule's auto-reply when one is set | `all` | `KEYWORD_RULE` when a custom rule fired |
| `email` | One-click unsubscribe via the `List-Unsubscribe` header and the in-body link; email does not use a keyword scheme | None; the address is fenced as soon as the unsubscribe lands | `email` | The unsubscribe event, as shown in the suppression export |
| `line` | None — no inbound keyword parser on this connector | None | No row written | No entry until you log it |
| `instagram` | None — no inbound keyword parser on this connector | None | No row written | No entry until you log it |
| `messenger` | None — no inbound keyword parser on this connector | None | No row written | No entry until you log it |
| `wechat` | None — no inbound keyword parser on this connector | None | No row written | No entry until you log it |
| `kakao` | None — no inbound keyword parser on this connector | None | No row written | No entry until you log it |
| `zalo` | None — no inbound keyword parser on this connector | None | No row written | No entry until you log it |
| `apple_messages` | None — no inbound keyword parser on this connector | None | No row written | No entry until you log it |

The `scope` column is what the send gates read: an `all` entry fences the address on every channel, a single-channel entry fences only that channel, and a `telegram` entry fences your bot messages to that chat. The scope semantics are documented in [Consent Management](https://docs.orbit.devotel.io/compliance/consent-management.md); this page covers *where the revocation enters*, not what the scope means once stored.

***

## Channels without automatic recognition

On LINE, Instagram, Messenger, WeChat, Kakao, Zalo and Apple Messages, an inbound `STOP` (or any other revocation phrasing) creates **no suppression row and sends no confirmation**. Two structural reasons, the same ones that bound the Telegram slash commands:

* Those connectors hand Orbit the app's chat or user identifier, not a phone number. There is no number on the inbound event to fence.
* No keyword parser runs on those inbound paths, so even a textbook `STOP` is just a message your team receives in the unified inbox.

Because the identifier is a chat id, do not try to suppress the chat: record the revocation against the customer's phone number or email address — the address your campaigns actually target — so the fence covers every channel with scope `all`.

### Log the revocation through the Consent API

The call is the same one documented in the [Consent Management worked example](https://docs.orbit.devotel.io/compliance/consent-management.md). Set `source` to a tag your team audits against, for example `inbound_keyword` when the request arrived as a keyword in an app chat:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/compliance/consent \
  -H "Authorization: Bearer $ORBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "identifier": "+14155550101", "channels": ["sms", "voice"], "opt_in": false, "source": "inbound_keyword" }'
```

An `opt_in: false` on a phone identifier writes scope `all`, the same fence a keyword STOP writes on SMS.

### Or use the surfaces your team already works in

* **Preference Center** — record the revocation the same way a self-service subscriber would: [Preference Center](https://docs.orbit.devotel.io/compliance/preference-center.md).
* **Bulk CSV import** — for a backlog of app-chat revocations collected over a period, import them in one pass with an explicit channel or scope per row: [bulk CSV import](https://docs.orbit.devotel.io/compliance/opt-out-suppression.md#bulk-csv-import).

Whichever path you use, the entry lands in the same ledger as automated revocations and reads back identically — see [Verify every revocation landed](#verify-every-revocation-landed).

> [!TIP]
>
> Log the revocation while the conversation is still open. On the
> non-automated channels the request sits in your unified inbox as an
> ordinary message; once the thread scrolls away, nothing reminds anyone
> that consent was withdrawn. Put the logging step in your agent scripts —
> the next section shows the shape.

***

## Put the logging obligation in your agent scripts

On the non-automated channels, the first person to see a revocation is usually one of your agents in the inbox console. [Agent scripts](https://docs.orbit.devotel.io/inbox/agent-scripts.md) are the tenant-owned tool for making the logging step part of the flow instead of a matter of memory: add a step to the scripts that run on those channels instructing the agent to record the revocation before closing the conversation. A step of this shape works in any script:

```json theme={null}
{
  "step_id": "s-log-optout",
  "kind": "note",
  "title": "Revocation received",
  "body": "This channel does not auto-record opt-outs. Log the revocation now: Consent API opt_in:false against the customer's phone or email, or the Preference Center. Only confirm completion to the customer once the record exists.",
  "options": [
    { "label": "Revocation logged", "next_step_id": null }
  ]
}
```

Voice is handled on its own surface: verbal objections on live calls belong to the voice queue scripting surface, not to inbox agent scripts.

***

## Verify every revocation landed

For every revocation, automated or manually logged, close the loop with a read-back before you rely on it in a campaign:

1. **Consent history.** `GET /api/v1/compliance/consent/history?identifier=<address>&channel=<channel>` shows the newest row with `consent_state: "opted_out"` and a `revoked_at` — the no-send-after instant you present in an audit.
2. **Suppression export.** Export the ledger from [Opt-Out & Suppression Lists](https://docs.orbit.devotel.io/compliance/opt-out-suppression.md) with `status=active` and confirm the address is listed with the scope you expect (`all` for a phone-keyed revocation).
3. **Opt-outs console.** The [Opt-outs console](https://docs.orbit.devotel.io/guides/audience-opt-outs-console.md) channel filters isolate the slice per channel when you want the dashboard view instead of the export.

For the automated channels, prove the path end to end with a real inbound, the same discipline as the [keyword rules testing checklist](https://docs.orbit.devotel.io/guides/opt-out-rules-whatsapp-rcs.md#testing-non-sms-channels-end-to-end): send the keyword from a test handset or chat, confirm the confirmation reply arrives, confirm the consent history row and the scope-`all` suppression entry. For a non-automated channel, run the negative case once per connector you operate: send `STOP` from a test account, confirm that **no** suppression row appears (that absence is expected and is exactly why the manual procedure above exists), then log it through the Consent API and confirm all three read-backs.

***

## Related pages

* [Opt-Out Keyword Alias Table](https://docs.orbit.devotel.io/compliance/opt-out-keyword-alias-table.md) — the shipped STOP/START vocabulary and the Telegram slash-command reference.
* [Consent Management](https://docs.orbit.devotel.io/compliance/consent-management.md) — the consent ledger, revocation scopes, and the API worked example reused above.
* [Opt-Out & Suppression Lists](https://docs.orbit.devotel.io/compliance/opt-out-suppression.md) — the ledger these entries land in, with bulk CSV import and export.
* [Preference Center](https://docs.orbit.devotel.io/compliance/preference-center.md) — the self-service revocation surface.
* [Agent scripts](https://docs.orbit.devotel.io/inbox/agent-scripts.md) — guided flows that put the manual logging step in front of your agents.
* [Keyword opt-outs on WhatsApp, RCS & Viber](https://docs.orbit.devotel.io/guides/opt-out-rules-whatsapp-rcs.md) — per-channel rule setup for the editable channels.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.