# Preferences

A preference is a statement about what a person wants, recorded against their handle on one channel. On WhatsApp the handle is a phone number in E.164 format. It is a separate record from a [suppression](/docs/guides/whatsapp/opt-outs/suppressions), and both are checked before a send.

Preferences reach your workspace three ways: WhatsApp reports one, a recipient types a keyword, or you record one yourself. What you can do about each depends on who stated it.

## What a preference carries

A statement is either `revoked`, an opt-out, or `granted`, consent.

It also carries a coverage, which decides how much traffic it stops. `non_transactional` covers marketing and other non-essential messages while transactional messages such as receipts and verification codes keep flowing. `all` covers every message. The **Preferences** tab shows these in its **Covers** column as **Non-transactional** and **All messages**.

A statement can narrow to one sender with `sender_scope`, which on WhatsApp identifies the business account. Without it, the statement covers the channel across your workspace, including accounts you connect later.

A person can hold several rows on one channel, such as a channel-wide opt-out next to a sender-scoped one. The most restrictive statement decides whether a message goes out.

## Preferences Bird records for you

When Bird receives a Meta event saying a recipient has stopped marketing messages, it records a recipient-origin preference for that WhatsApp Business Account. The preference covers non-transactional messages. It does not create an all-message suppression, and it does not opt the person out of every account in your workspace.

A recipient can state the same thing by replying `STOP`. That preference is scoped to the business account they messaged, like the one above. It covers all messages, because a typed `STOP` is broader than WhatsApp's marketing opt-out. See [keyword rules](/docs/guides/whatsapp/opt-outs/keyword-rules) for what Bird recognizes and how to change the reply.

A later resume event updates that account's preference. Suppressions and other applicable preferences still apply, so a resume event on its own does not prove that a send is eligible.

## Preferences you record

Open the [**Suppressions**](https://bird.com/dashboard/w/whatsapp/suppressions) page and switch to the **Preferences** tab. Recording one there with **Every business account in the workspace** stops the address receiving WhatsApp messages from every account you hold, including accounts you connect later.

![A list of subscribers who opted in or out, with the coverage of each statement](/images/docs/dashboard-whatsapp-preferences.png)

The **Record opt-out** dialog on that tab records all-message coverage.

![A dialog for recording an opt-out, with the workspace-wide scope selected](/images/docs/dashboard-whatsapp-preference-new.png)

To record one that stops marketing alone, use the workspace-wide **Contacts** > **Preferences** page, whose dialog offers **Marketing messages** as well as **All messages**.

## Reading preferences from code

`GET /v1/preferences` returns the workspace's recorded preferences, most recently created first. Pass `channel=whatsapp` to narrow to this channel, and `handle` with it to look up everything on record for one number before messaging them:

**TypeScript**

```typescript
for await (const preference of bird.preferences.list({
  channel: "whatsapp",
  handle: "+15550001234",
})) {
  console.log(preference.status, preference.coverage, preference.sender_scope);
}
```

Examples: [TypeScript](/docs/guides/whatsapp/opt-outs/preferences.ts.md) · [Python](/docs/guides/whatsapp/opt-outs/preferences.py.md) · [Go](/docs/guides/whatsapp/opt-outs/preferences.go.md) · [PHP](/docs/guides/whatsapp/opt-outs/preferences.php.md) · [CLI](/docs/guides/whatsapp/opt-outs/preferences.cli.md) · [cURL](/docs/guides/whatsapp/opt-outs/preferences.curl.md)

`handle` requires `channel`, since the same handle can exist on more than one channel.

## Recording a preference from code

`POST /v1/preferences` records one statement. Writing is an upsert keyed on the channel, handle, and sender scope, so a new statement replaces the key's current one:

**TypeScript**

```typescript
const result = await bird.preferences.create({
  channel: "whatsapp",
  handle: "+15550001234",
  status: "revoked",
  coverage: "non_transactional",
});
console.log(result.applied, result.preference?.id);
```

Examples: [TypeScript](/docs/guides/whatsapp/opt-outs/preferences.ts.md) · [Python](/docs/guides/whatsapp/opt-outs/preferences.py.md) · [Go](/docs/guides/whatsapp/opt-outs/preferences.go.md) · [PHP](/docs/guides/whatsapp/opt-outs/preferences.php.md) · [CLI](/docs/guides/whatsapp/opt-outs/preferences.cli.md) · [cURL](/docs/guides/whatsapp/opt-outs/preferences.curl.md)

Statements are ordered by when they were made rather than when they arrive. The API refuses a statement dated earlier than the key's current one and returns `applied: false` with the statement that survived. The refusal stays on the key's history.

A `201` means the key had no record and this statement created one. A `200` returns the key's surviving record, whether this statement replaced it, repeated it, or was refused.

## What you can reverse

One you recorded, you can remove from the **Preferences** tab or with `DELETE /v1/preferences/{preference_id}` once the recipient asks you to resume sending.

A statement the person made themselves is theirs to reverse. An unsubscribe or a stop keyword ends when they opt back in, and a delete returns `422`. To resume messaging with their consent, record a `granted` statement carrying `consented_at`, the moment they consented. The grant applies when that moment is later than the opt-out it reverses, so it records the change of mind rather than erasing the original statement.

A delete is ordered like any other statement, using the time it is received. If the record carries a statement made after that moment, the delete is refused and returned with `applied: false` alongside the surviving record.

## When a delivery error arrives first

A provider delivery error can report a stop before Bird has recorded a matching event. Preserve the recipient's choice and investigate the preference and event history rather than treating a missing local record as permission to send.

## Next steps

- [Suppressions](/docs/guides/whatsapp/opt-outs/suppressions): the addresses your workspace blocks directly.
- [Keyword rules](/docs/guides/whatsapp/opt-outs/keyword-rules): the words that record a preference on your numbers.
- [WhatsApp events](/docs/guides/whatsapp/events): the `whatsapp.rejected` payload a blocked send produces.

## Related resources

- [Connecting WhatsApp to Bird: from buying a number to a live channel](/learn/whatsapp/connecting-whatsapp-to-bird) (video)
- [What is the 24-hour customer service window on WhatsApp?](/explained/whatsapp/what-is-the-24-hour-customer-service-window) (answer)
- [WhatsApp message builder](/tools/whatsapp-message-builder) (tool)
- [WhatsApp](/whatsapp-api) (product)

[Get an implementation brief](/learn/workspace?topic=whatsapp)
