> ## 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-outs console: read and act on the per-contact opt-out list

> Read, filter, and act on the Audience → Opt-outs console — where opt-outs come from, what each one writes (consent ledger, suppression list, STOP fence, audit log), and how to export compliance evidence for a carrier or GDPR audit.

# Opt-outs console

The **Opt-outs console** (**Audience → Opt-outs**) is the working list of every contact who has withdrawn permission to be contacted, one row per contact with a badge for each channel they have opted out of. It is the operator surface a compliance officer, a campaign manager, or a support lead opens to answer "who has opted out, on which channels, and when."

Opt-outs are a **tenant-owned control**: your organization decides whom to opt out, whom to re-opt in, and what evidence you keep. Orbit enforces the resulting records on every send gate; the consent decision belongs to your organization and your contacts.

Two sibling pages own the *configuration* side of opt-outs — this guide owns the *operator view*:

* [Custom opt-out keyword lists](/guides/opt-out-lists) — per-brand STOP/HELP/START keyword configuration attached to a messaging service.
* [Preference center](/guides/preference-center-opt-out-page) — the hosted public page a contact uses to manage their own opt-ins.

***

## 1. What an opt-out is, per channel

An opt-out is a per-contact, per-channel revoke of consent. The mechanics differ by channel, but every one converges on the same consent record that this console renders:

| Channel                                        | How the opt-out arrives                                                                | What gets flagged                                   |
| ---------------------------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------- |
| SMS                                            | A STOP keyword reply, matched by the keyword list attached to the sending service      | `sms` channel revoke                                |
| WhatsApp                                       | An opt-in revocation echoed back through the connected WABA webhook, or a STOP keyword | `whatsapp` revoke checked against template dispatch |
| Email                                          | An unsubscribe link click or a preference-center toggle                                | `email` revoke read by the email sender gate        |
| Voice                                          | A do-not-call flag from the dialer, the console, or a suppression import               | `voice` revoke read by call preflight               |
| RCS / Viber / Messenger / Instagram / Telegram | Inbound keyword or preference-center write                                             | The corresponding channel revoke                    |

The console's channel filter lists all nine channels plus **All Channels** — `sms`, `whatsapp`, `email`, `rcs`, `viber`, `voice`, `messenger`, `instagram`, `telegram` — so an opt-out recorded on any of them is visible and filterable here.

A contact can also carry a **global opt-out** flag that revokes every channel at once; the console treats that as a contact-level state rather than one more channel badge.

***

## 2. Where the list is sourced from

The console is a read-back view over the consent ledger. Five writers converge on it:

1. **Inbound keyword replies** — the STOP/HELP/START handler, using the keyword list attached to the messaging service that received the reply (see [Custom opt-out keyword lists](/guides/opt-out-lists)).
2. **Preference-center writes** — a contact toggling a channel off on the hosted public page (see [Preference center](/guides/preference-center-opt-out-page)).
3. **Consent API** — `opt_in: false` recorded per channel (see [Consent management](/compliance/consent-management)).
4. **Create opt-out** — the manual dialog on this page.
5. **Import CSV** — the bulk import on this page, e.g. when migrating a suppression file off another platform.

Because all five write to the same ledger, the console shows a single deduplicated row per contact regardless of which entry point recorded the revoke.

### What one opt-out write actually does

"Which surfaces an opt-out writes" matters when you act on the console: a revoke is not just a UI flag. Each write touches four compliance surfaces:

* **Consent ledger** — an append-only row with source, channel, and policy metadata; the console and the [Consent inspector](/guides/audience-consent-inspector) both read from it.
* **Suppression list** — the address is blocked with a channel scope (`all` or the specific channel), which every send gate reads before dispatch.
* **STOP fence** — a fast-path Redis fence set on opt-out (and cleared on a full re-opt-in) so in-flight campaign batches see the revoke before the slower database suppression propagates.
* **Audit log** — the opt-in/out event is recorded for the organization's compliance trail.

The full mechanics of the four writes are documented on the [preference center guide](/guides/preference-center-opt-out-page#4-how-updates-flow); the console inherits exactly that behavior for every entry point above.

***

## 3. Reading and filtering the list

**Search** — the search box queries phone, email, and name (debounced so it fires after you stop typing). Searching a specific identifier is the fastest way to check whether a given contact is opted out.

**Channel filter** — narrow the list to one channel (e.g. "show me everyone opted out of SMS") or reset to **All Channels**.

**Per-contact rows, per-channel badges** — each row is one contact; every opted-out channel is stamped as a badge on that row. A contact opted out of SMS and Email appears once, with two badges, rather than twice. The export (see section 4) reverses this: one export row per (contact, channel) pair, matching how most suppression importers and auditors expect the data.

**Contact profile** — clicking a contact's name opens the Customer 360 drawer so you can read their full consent history before deciding on a re-opt-in.

**Dedupe across channels** — when you import a CSV, rows that repeat the same (contact, channel) within the file are collapsed before they reach the API, and the summary toast separates *newly opted out*, *already opted out* (pre-existing revoke), *duplicate rows in file*, and *failed* counts so a re-import of the same file reads as idempotent rather than as fresh revokes.

### GDPR-delete interplay

The preference center can expose a **data-deletion toggle** to contacts. When a contact checks it, the platform records a flagged deletion request alongside the opt-out — but that flag starts a legacy GDPR-deletion workflow only, and does **not** enter the tracked DSAR pipeline. Route right-to-erasure requests through the DSAR endpoint, and see [CDP erasure propagation](/guides/cdp-erasure-propagation) for how erasure fans out. The opt-out record itself stays in the consent ledger even after contact data is erased — it is the evidence the erasure was honoured, keyed by the hashed identifier where applicable.

If a contact appears in the console with a global opt-out flag rather than channel badges, treat the toggle as contact-level: individual channel re-opt-ins only make sense once the global flag is addressed.

***

## 4. Acting on the list: add, import, and re-opt-in

### Add a single opt-out

**Create opt-out** opens a dialog with three fields: the contact (a phone number or an email address), the channel, and the reason (`Customer request`, `Regulatory compliance`, `Spam complaint`, `Bounced / invalid`, `Other`). The reason is recorded on the consent ledger row for later audit.

### Bulk import

**Import CSV** accepts a file with `contact`, `channel` (optional — defaults to `sms`), and `reason` (optional) columns. **Template** downloads a 3-row exemplar. Imports run in 500-row batches with per-row results, and the confirmation dialog shows the row count before anything is written. Header-aware mapping means a CSV exported from this console can round-trip back into it.

### Re-opt-in

The row's ⋯ menu offers **Re-opt-in for each opted-out channel** as a separate item. Re-opt-in requires recording how consent was re-acquired — a verbal confirmation, written confirmation, web form / double opt-in, support ticket, or other — plus an optional reference (ticket number, recording ID). The dialog will not confirm without a source; the source and note are written into the consent event so the re-opt-in is defensible under GDPR and TCPA.

For **SMS specifically**, the confirmation dialog warns when the contact may be under a US/CA toll-free carrier-level block: re-opting in here updates consent inside Orbit (and any connected CRM tools), but a carrier-level block is only cleared when the carrier separately removes it — until then, sends to that number stay blocked upstream.

Retry-friendly: if the list fails to load (transient error), an inline **Retry** button re-fetches it instead of forcing a browser reload.

***

## 5. Exporting and auditing opt-outs for compliance evidence

**Export** downloads the current list — as CSV for spreadsheets and downstream suppression importers, or as JSON for archiving. If a channel filter is active, the export respects it, so "export everything opted out of email" produces only email revokes.

The CSV exports one row per (contact, channel) with these columns:

| Column                          | Contents                                                                                                                                              |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                            | The contact id (`cnt_…`)                                                                                                                              |
| `phone` / `email`               | The address the revoke applies to                                                                                                                     |
| `first_name` / `last_name`      | Contact names as recorded                                                                                                                             |
| `channel`                       | The opted-out channel for this row (empty when the contact carries only the global flag)                                                              |
| `updated_at (local time, <tz>)` | The newest consent-write timestamp, rendered in your dashboard timezone with a GMT-offset annotation so a recipient on another clock knows the anchor |

The JSON export returns the full contact records including the raw per-channel preference object; useful when re-importing into another system or feeding a data warehouse for offline analysis.

### Worked example: evidence for a carrier audit

A US carrier audit asks for proof that everyone who replied STOP is suppressed. The compliance officer:

1. Opens **Audience → Opt-outs** and sets the channel filter to **SMS**.
2. Clicks **Export → Export as CSV**. The download contains one row per (contact, `sms`) pair — the exact blocker the carrier asks about — with the timestamp column annotated with the office timezone.
3. Attaches the CSV to the audit response; the `id`, `phone`, and `updated_at` columns give the carrier both the suppressing record and when the revoke was captured.
4. For the auditors asking "how is re-opt-in controlled", points to the re-opt-in flow's consent-source requirement (each re-opt-in is recorded with how consent was re-acquired).

Because exports respect the active filter and dedupe correctly, the same process works for a GDPR spot-check ("show every contact opted out today on any channel") — reset the filter to **All Channels** and export.

### The same endpoints programmatically

Operators and compliance tooling hit the same surface the console uses:

| Method   | Path                                      | Purpose                                                                   |
| -------- | ----------------------------------------- | ------------------------------------------------------------------------- |
| `GET`    | `/api/v1/contacts/optouts`                | List opted-out contacts with `search`, `channel`, and cursor pagination   |
| `POST`   | `/api/v1/contacts/optouts`                | Add one opt-out (`contact`, `channel`, `reason`)                          |
| `POST`   | `/api/v1/contacts/optouts/bulk`           | Batch import; returns `succeeded` / `skipped` / `failed` per-row outcomes |
| `POST`   | `/api/v1/contacts/optouts/export`         | Export the full list (optional `channel` filter)                          |
| `DELETE` | `/api/v1/contacts/optouts/{id}/{channel}` | Re-opt-in one channel with recorded consent source                        |

Use the dashboard when sampling or auditing by eye; use the endpoints when a compliance system needs the full ledger on a schedule. Full schema in the [Opt-Outs API reference](/api-reference/optouts).

***

## Related

* [Custom opt-out keyword lists](/guides/opt-out-lists) — keyword configuration the inbound STOP handler matches against.
* [Preference center](/guides/preference-center-opt-out-page) — the hosted public opt-in/opt-out page.
* [Opt-Out & Suppression Lists](/compliance/opt-out-suppression) — the compliance-side bulk suppression list and its enforcement screens.
* [Consent inspector](/guides/audience-consent-inspector) — per-contact ledger and a live verdict simulator.
* [Consent management](/compliance/consent-management) — the Consent API writers.
* [Opt-Outs API reference](/api-reference/optouts) — endpoint schemas.
