> For the complete documentation index, see [llms.txt](https://docs.bird.com/api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bird.com/api/channels-api/supported-channels/programmable-whatsapp/business-scoped-user-ids.md).

# Business-Scoped User IDs

### Timeline and Breaking Changes

#### Overview

Meta is introducing Business-Scoped User IDs (BSUIDs) and Usernames to the WhatsApp Business Platform. These changes roll out in phases and include one breaking change: from end of July 2026, users who have adopted a username may no longer expose their phone number in webhooks if there has been no recent messaging interaction.

#### Rollout timeline

| Date                 | Change                                                                                                                                                                                   | Action required                                                                                                                            |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| April 2026 (TBC)     | BSUIDs begin appearing in `meta.extraInformation` on incoming message webhooks                                                                                                           | Update webhook parsing to read `whatsappbsuid` and `whatsappusername`                                                                      |
| May 2026             | APIs support sending messages to BSUIDs via `identifierKey: "whatsappbsuid"`                                                                                                             | No immediate action required — BSUID sending is additive                                                                                   |
| **End of July 2026** | **Breaking change:** Users who have adopted a username and have had no messaging interaction with your business in the last 30 days will no longer expose their phone number in webhooks | Ensure your integration handles senders identified by `whatsappusername` instead of `phonenumber`, and uses BSUID as the stable identifier |
| Later 2026           | Usernames feature becomes available to WhatsApp users broadly                                                                                                                            | Monitor adoption; more users may become phone-number-unavailable over time                                                                 |

#### Breaking change detail — end of July 2026

From end of July 2026, when a WhatsApp user has adopted a username, their phone number will only be present in webhooks if **at least one** of the following is true (evaluated per business phone number):

* You sent a message to their phone number in the last 30 days
* You received a message from their phone number in the last 30 days

If neither of these conditions is met, the sender will be identified by `whatsappusername` instead of `phonenumber`, and no phone number will appear anywhere in the webhook payload.

**What to do before end of July 2026:**

1. Read `whatsappbsuid` from `meta.extraInformation` and store BSUIDs against your contact records, alongside phone numbers where available.
2. Handle the case where `sender.contact.identifierKey` is `whatsappusername` — do not assume `phonenumber` is always present.
3. Use `whatsappbsuid` as the stable, durable identifier for a user. Phone numbers can become unavailable; BSUIDs persist (and Bird handles rotations automatically).
4. When replying to a username-identified sender, use the `whatsapp_{portfolioId}` key from `sender.contact.identifiers`, or send using `identifierKey: "whatsappbsuid"`.

> **Note:** One-tap, zero-tap, and copy code authentication templates cannot be sent to a BSUID. These always require a phone number.

***

### Sending Messages

#### Send by BSUID only

Use when you only have the user's BSUID and no phone number.

**Request:**

{% code lineNumbers="true" expandable="true" %}

```json
POST /workspaces/{workspaceId}/channels/{channelId}/messages

{
  "receiver": {
    "contacts": [
      {
        "identifierKey": "whatsappbsuid",
        "identifierValue": "US.13491208655302741918"
      }
    ]
  },
  "body": {
    "type": "text",
    "text": {
      "text": "Hello, your order has shipped!"
    }
  }
}
```

{% endcode %}

The `whatsappbsuid` identifier is resolved internally to the portfolio-scoped identifier (`whatsapp_{portfolioId}`) based on the channel configuration. No portfolio ID is needed in the request.

**Response (202 Accepted):**

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "b4c5d6e7-f8a9-0123-bcde-f01234567890",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "sender": {
    "connector": {
      "id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
      "identifierValue": "15550783881"
    }
  },
  "receiver": {
    "contacts": [
      {
        "id": "f1234567-89ab-cdef-0123-456789abcdef",
        "identifierKey": "whatsapp_987654321",
        "identifierValue": "US.13491208655302741918"
      }
    ]
  },
  "body": {
    "type": "text",
    "text": {
      "text": "Hello, your order has shipped!"
    }
  },
  "parts": [],
  "status": "accepted",
  "direction": "outgoing",
  "reason": "",
  "reference": "",
  "batchId": null,
  "lastStatusAt": "2026-04-09T10:31:00Z",
  "createdAt": "2026-04-09T10:31:00Z",
  "updatedAt": "2026-04-09T10:31:00Z"
}
```

{% endcode %}

Note that the response shows the resolved portfolio-scoped identifier key (`whatsapp_987654321`), not the generic `whatsappbsuid` submitted in the request.

#### Send by BSUID with phone number available

When the contact has both a phone number and a BSUID, you can still send by BSUID. Sending by phone number is recommended when available, as it ensures you continue to receive the user's phone number in future webhooks.

**Request:**

{% code lineNumbers="true" expandable="true" %}

```json
POST /workspaces/{workspaceId}/channels/{channelId}/messages

{
  "receiver": {
    "contacts": [
      {
        "identifierKey": "whatsappbsuid",
        "identifierValue": "US.13491208655302741918"
      }
    ]
  },
  "body": {
    "type": "text",
    "text": {
      "text": "Your return has been approved."
    }
  }
}
```

{% endcode %}

**Response (202 Accepted):**

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "a3b1c2d4-e5f6-7890-abcd-ef1234567890",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "sender": {
    "connector": {
      "id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
      "identifierValue": "15550783881"
    }
  },
  "receiver": {
    "contacts": [
      {
        "id": "f1234567-89ab-cdef-0123-456789abcdef",
        "identifierKey": "whatsapp_987654321",
        "identifierValue": "US.13491208655302741918"
      }
    ]
  },
  "body": {
    "type": "text",
    "text": {
      "text": "Your return has been approved."
    }
  },
  "parts": [],
  "status": "accepted",
  "direction": "outgoing",
  "reason": "",
  "reference": "",
  "batchId": null,
  "lastStatusAt": "2026-04-09T10:30:00Z",
  "createdAt": "2026-04-09T10:30:00Z",
  "updatedAt": "2026-04-09T10:30:00Z"
}
```

{% endcode %}

The resolved identifier key is the portfolio-scoped `whatsapp_987654321`. BSUID identifiers are not platform addresses — `platformAddress` is not populated from the BSUID value. Internally, if the contact also has a phone number, the platform worker uses it for delivery (phone takes precedence over BSUID when available).

***

### Receiving Messages

#### Incoming message — user has BSUID, phone number available

The user has not adopted a username, or has one but phone number is still available (recent interaction within 30 days). BSUID is present in `meta.extraInformation`.

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "e1f2a3b4-c5d6-7890-ef01-234567890abc",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "sender": {
    "contact": {
      "id": "f1234567-89ab-cdef-0123-456789abcdef",
      "identifierKey": "phonenumber",
      "identifierValue": "+16505551234"
    }
  },
  "receiver": {
    "connector": {
      "id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
      "identifierValue": "15550783881"
    }
  },
  "body": {
    "type": "text",
    "text": {
      "text": "Does it come in another color?"
    }
  },
  "meta": {
    "extraInformation": {
      "timestamp": "1749416383",
      "whatsappbsuid": "US.13491208655302741918",
      "whatsappusername": "realsheenanelson"
    }
  },
  "parts": [
    {
      "platformReference": "wamid.HBgLMTY1MDM4Nzk0MzkVAgASGBQzQTRBNjU5OUFFRTAzODEwMTQ0RgA"
    }
  ],
  "status": "delivered",
  "direction": "incoming",
  "reason": "",
  "reference": "",
  "batchId": null,
  "lastStatusAt": "2026-04-09T11:00:00Z",
  "createdAt": "2026-04-09T11:00:00Z",
  "updatedAt": "2026-04-09T11:00:00Z"
}
```

{% endcode %}

**Key points:**

* `whatsappbsuid` is always present once BSUIDs are enabled
* `whatsappusername` is present because the user adopted a username
* `sender` is identified by `phonenumber` since the phone is available — BSUID identifiers are NOT on `sender.contact.identifiers`, only in `meta.extraInformation`
* If the user has no username, `whatsappusername` is omitted

#### Incoming message — user has BSUID and username, phone number unavailable

The user adopted a username and there has been no messaging interaction in the last 30 days. The phone number is not included.

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "c4d5e6f7-a8b9-0123-cdef-456789012345",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "sender": {
    "contact": {
      "id": "f1234567-89ab-cdef-0123-456789abcdef",
      "identifierKey": "whatsappusername",
      "identifierValue": "realsheenanelson",
      "identifiers": [
        {
          "identifierKey": "whatsapp_987654321",
          "identifierValue": "US.13491208655302741918"
        }
      ]
    }
  },
  "receiver": {
    "connector": {
      "id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
      "identifierValue": "15550783881"
    }
  },
  "body": {
    "type": "text",
    "text": {
      "text": "Hi, I have a question about your product."
    }
  },
  "meta": {
    "extraInformation": {
      "timestamp": "1749416700",
      "whatsappbsuid": "US.13491208655302741918",
      "whatsappusername": "realsheenanelson"
    }
  },
  "parts": [
    {
      "platformReference": "wamid.HBgLMTY1MDM4Nzk0MzkVAgASGBQzQTRBNjU5OUFFRTAzODEwMTQ0RgA"
    }
  ],
  "status": "delivered",
  "direction": "incoming",
  "reason": "",
  "reference": "",
  "batchId": null,
  "lastStatusAt": "2026-04-09T11:10:00Z",
  "createdAt": "2026-04-09T11:10:00Z",
  "updatedAt": "2026-04-09T11:10:00Z"
}
```

{% endcode %}

**Key points:**

* No phone number — sender is identified by `whatsappusername`
* A username is not a dialable address — replies are routed via the BSUID
* `sender.contact.identifiers` includes the portfolio-scoped `whatsapp_{portfolioID}` — use it or the generic `whatsappbsuid` key to reply
* BSUID is also available in `meta.extraInformation["whatsappbsuid"]`

***

### Status Updates

When you send a message, its status progresses through `accepted` → `delivered`. The message resource is updated with each status change.

#### Message delivered — sent to BSUID, phone number available

The recipient has a phone number on file alongside their BSUID. The phone number appears in `phonenumber` in `meta.extraInformation`.

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "a3b1c2d4-e5f6-7890-abcd-ef1234567890",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "sender": {
    "connector": {
      "id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
      "identifierValue": "15550783881"
    }
  },
  "receiver": {
    "contacts": [
      {
        "id": "f1234567-89ab-cdef-0123-456789abcdef",
        "identifierKey": "whatsapp_987654321",
        "identifierValue": "US.13491208655302741918"
      }
    ]
  },
  "body": {
    "type": "text",
    "text": {
      "text": "Your return has been approved."
    }
  },
  "meta": {
    "extraInformation": {
      "timestamp": "1750030073",
      "phonenumber": "16505551234",
      "whatsappbsuid": "US.13491208655302741918",
      "whatsappusername": "realsheenanelson"
    }
  },
  "parts": [
    {
      "platformReference": "wamid.HBgLMTY0NjcwNDM1OTUVAgARGBI1RjQyNUE3NEYxMzAzMzQ5MkEA"
    }
  ],
  "status": "delivered",
  "direction": "outgoing",
  "reason": "",
  "reference": "",
  "batchId": null,
  "lastStatusAt": "2026-04-09T10:35:00Z",
  "createdAt": "2026-04-09T10:30:00Z",
  "updatedAt": "2026-04-09T10:35:00Z"
}
```

{% endcode %}

#### Message delivered — sent to BSUID, phone number unavailable

When the phone number is not available, `phonenumber` is absent.

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "b4c5d6e7-f8a9-0123-bcde-f01234567890",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "sender": {
    "connector": {
      "id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
      "identifierValue": "15550783881"
    }
  },
  "receiver": {
    "contacts": [
      {
        "id": "f1234567-89ab-cdef-0123-456789abcdef",
        "identifierKey": "whatsapp_987654321",
        "identifierValue": "US.13491208655302741918"
      }
    ]
  },
  "body": {
    "type": "text",
    "text": {
      "text": "Hello, your order has shipped!"
    }
  },
  "meta": {
    "extraInformation": {
      "timestamp": "1750030073",
      "whatsappbsuid": "US.13491208655302741918",
      "whatsappusername": "realsheenanelson"
    }
  },
  "parts": [
    {
      "platformReference": "wamid.HBgLMTY1MDM4Nzk0MzkVAgASGBQzQUFERjg0NDEzNDdFODU3MUMxMAA"
    }
  ],
  "status": "delivered",
  "direction": "outgoing",
  "reason": "",
  "reference": "",
  "batchId": null,
  "lastStatusAt": "2026-04-09T10:36:00Z",
  "createdAt": "2026-04-09T10:31:00Z",
  "updatedAt": "2026-04-09T10:36:00Z"
}
```

{% endcode %}

**Key points:**

* No `phonenumber` since it's unavailable
* `whatsappusername` appears on delivered status if the user has adopted a username
* Receiver shows the resolved portfolio-scoped identifier key (`whatsapp_987654321`)

***

### Message Interactions

Read receipts and reactions are represented as message interactions, not status changes. These carry BSUID data in `metadata.extraInformation`.

When the interaction relates to a message you sent, the `receiver.contacts` entry mirrors the receiver contact of that original message — for a message sent by BSUID this is the portfolio-scoped `whatsapp_{portfolioId}` identifier, even when the read receipt itself carried a phone number (the phone number is still available in `metadata.extraInformation`).

#### Read interaction — phone number available

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "d5e6f7a8-b9c0-1234-5678-90abcdef0123",
  "messageId": "a3b1c2d4-e5f6-7890-abcd-ef1234567890",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "platformId": "whatsapp",
  "type": "read",
  "messageReference": "wamid.HBgLMTY0NjcwNDM1OTUVAgARGBI1RjQyNUE3NEYxMzAzMzQ5MkEA",
  "messagePartsCount": 1,
  "context": null,
  "receiver": {
    "contacts": [
      {
        "id": "f1234567-89ab-cdef-0123-456789abcdef",
        "identifierKey": "whatsapp_987654321",
        "identifierValue": "US.13491208655302741918"
      }
    ]
  },
  "metadata": {
    "extraInformation": {
      "timestamp": "1750030200",
      "whatsappbsuid": "US.13491208655302741918",
      "whatsappusername": "realsheenanelson",
      "phonenumber": "16505551234"
    }
  },
  "createdAt": "2026-04-09T10:40:00Z"
}
```

{% endcode %}

#### Read interaction — phone number unavailable

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "e6f7a8b9-c0d1-2345-6789-0abcdef01234",
  "messageId": "b4c5d6e7-f8a9-0123-bcde-f01234567890",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "platformId": "whatsapp",
  "type": "read",
  "messageReference": "wamid.HBgLMTY1MDM4Nzk0MzkVAgASGBQzQUFERjg0NDEzNDdFODU3MUMxMAA",
  "messagePartsCount": 1,
  "context": null,
  "receiver": {
    "contacts": [
      {
        "id": "f1234567-89ab-cdef-0123-456789abcdef",
        "identifierKey": "whatsappusername",
        "identifierValue": "realsheenanelson",
        "identifiers": [
          {
            "identifierKey": "whatsapp_987654321",
            "identifierValue": "US.13491208655302741918"
          }
        ]
      }
    ]
  },
  "metadata": {
    "extraInformation": {
      "timestamp": "1750030300",
      "whatsappbsuid": "US.13491208655302741918",
      "whatsappusername": "realsheenanelson"
    }
  },
  "createdAt": "2026-04-09T10:42:00Z"
}
```

{% endcode %}

#### Reaction interaction

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "f7a8b9c0-d1e2-3456-7890-abcdef012345",
  "messageId": "a3b1c2d4-e5f6-7890-abcd-ef1234567890",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "platformId": "whatsapp",
  "type": "reaction",
  "messageReference": "wamid.HBgLMTY0NjcwNDM1OTUVAgARGBI1RjQyNUE3NEYxMzAzMzQ5MkEA",
  "messagePartsCount": 1,
  "context": null,
  "receiver": {
    "contacts": [
      {
        "id": "f1234567-89ab-cdef-0123-456789abcdef",
        "identifierKey": "whatsapp_987654321",
        "identifierValue": "US.13491208655302741918"
      }
    ]
  },
  "metadata": {
    "reaction": {
      "emoji": "👍",
      "action": "react"
    },
    "extraInformation": {
      "timestamp": "1750030400",
      "whatsappbsuid": "US.13491208655302741918",
      "whatsappusername": "realsheenanelson",
      "phonenumber": "16505551234"
    }
  },
  "createdAt": "2026-04-09T10:45:00Z"
}
```

{% endcode %}

#### Delete interaction

When a user deletes a message, a `delete-request` interaction is emitted.

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "a8b9c0d1-e2f3-4567-890a-bcdef0123456",
  "messageId": "e1f2a3b4-c5d6-7890-ef01-234567890abc",
  "channelId": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "platformId": "whatsapp",
  "type": "delete-request",
  "messageReference": "wamid.HBgLMTY1MDM4Nzk0MzkVAgASGBQzQTRBNjU5OUFFRTAzODEwMTQ0RgA",
  "messagePartsCount": 1,
  "context": null,
  "receiver": {
    "contacts": [
      {
        "id": "f1234567-89ab-cdef-0123-456789abcdef",
        "identifierKey": "phonenumber",
        "identifierValue": "+16505551234"
      }
    ]
  },
  "metadata": {
    "extraInformation": {
      "timestamp": "1750030500",
      "whatsappbsuid": "US.13491208655302741918",
      "whatsappusername": "realsheenanelson",
      "phonenumber": "16505551234"
    }
  },
  "createdAt": "2026-04-09T10:50:00Z"
}
```

{% endcode %}

***

### Extra Information Field Reference

#### Incoming messages (`meta.extraInformation`)

| Key                | Description                    | When present                     |
| ------------------ | ------------------------------ | -------------------------------- |
| `whatsappbsuid`    | Sender's BSUID                 | Always (once BSUIDs are enabled) |
| `whatsappusername` | Sender's username (lowercased) | Only if user adopted a username  |

#### Status updates and interactions (`meta.extraInformation` / `metadata.extraInformation`)

| Key                | Description                  | When present                           |
| ------------------ | ---------------------------- | -------------------------------------- |
| `whatsappbsuid`    | User's BSUID                 | On delivered/read status contacts      |
| `whatsappusername` | User's username (lowercased) | On delivered/read if user has username |
| `phonenumber`      | Recipient's phone number     | When phone number is available         |

***

### Identifier Keys Summary

| Identifier Key           | Value Format                                       | Use Case                                                                                                               |
| ------------------------ | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `phonenumber`            | E.164 format (e.g. `+16505551234`)                 | Send/receive by phone number                                                                                           |
| `whatsappbsuid`          | Country code + ID (e.g. `US.13491208655302741918`) | Send by BSUID (resolved to `whatsapp_{portfolioId}` internally). Not present in webhooks                               |
| `whatsapp_{portfolioId}` | Country code + ID (e.g. `US.13491208655302741918`) | Portfolio-scoped BSUID as seen in responses, webhooks, and `sender.contact.identifiers` for `whatsappusername` senders |
| `whatsappusername`       | Lowercased username (e.g. `realsheenanelson`)      | Sender identification when phone unavailable                                                                           |

***

### Channel Data — Portfolio ID

The WhatsApp Business Portfolio ID is available as a connection parameter on the channel. When you fetch a channel via the API, the `WA_PORTFOLIO_ID` connection parameter is included in the response:

{% code lineNumbers="true" expandable="true" %}

```json
GET /workspaces/{workspaceId}/channels/{channelId}

{
  "id": "c1d2e3f4-a5b6-7890-cdef-123456789012",
  "platformId": "whatsapp",
  "connectionParams": [
    {
      "key": "WABA_ID",
      "value": "123456789",
      "visibility": "public",
      "displayName": "Whatsapp Business account ID"
    },
    {
      "key": "PHONE_NUMBER",
      "value": "15550783881",
      "visibility": "public",
      "displayName": "Phone number"
    },
    {
      "key": "WA_PORTFOLIO_ID",
      "value": "987654321",
      "visibility": "internal"
    }
  ]
}
```

{% endcode %}

The `WA_PORTFOLIO_ID` value is the Business Portfolio ID used to scope BSUID identifiers. It corresponds to the `{portfolioId}` in `whatsapp_{portfolioId}` identifier keys. This parameter is set automatically when the channel is connected and the WABA's owner business info is retrieved from Meta.

***

### Fetching WhatsApp Identifiers from a Contact

WhatsApp identifiers (BSUID, username, phone number) are stored on contacts and can be retrieved via the Contacts API. This is useful when you need to look up a contact's available WhatsApp identifiers before sending a message.

**Request:**

```json
GET /workspaces/{workspaceId}/contacts/{contactId}/identifiers
```

**Response (200 OK):**

{% code lineNumbers="true" expandable="true" %}

```json
{
  "results": [
    {
      "contactId": "f1234567-89ab-cdef-0123-456789abcdef",
      "key": "phonenumber",
      "value": "+16505551234",
      "createdAt": "2026-03-01T12:00:00Z"
    },
    {
      "contactId": "f1234567-89ab-cdef-0123-456789abcdef",
      "key": "whatsapp_987654321",
      "value": "US.13491208655302741918",
      "createdAt": "2026-04-09T11:00:00Z"
    },
    {
      "contactId": "f1234567-89ab-cdef-0123-456789abcdef",
      "key": "whatsappusername",
      "value": "realsheenanelson",
      "createdAt": "2026-04-09T11:00:00Z"
    }
  ]
}
```

{% endcode %}

**Key points:**

* The portfolio-scoped BSUID identifier (`whatsapp_{portfolioId}`) is provisioned automatically when Bird processes incoming messages or status updates containing BSUID data
* The `whatsappusername` identifier is provisioned when the user has adopted a WhatsApp username
* Use the `whatsapp_{portfolioId}` identifier key and value from the contact to send a message by BSUID, or use the generic `whatsappbsuid` key (which is resolved internally using the channel's `WA_PORTFOLIO_ID`)
* The `{portfolioId}` in the identifier key matches the `WA_PORTFOLIO_ID` connection parameter on the channel

***

### Error Handling

#### BSUID recipient not supported for authentication templates

Sending authentication templates (one-tap, zero-tap, copy code) to a BSUID recipient is not supported. If you send one of these to a `whatsappbsuid` or `whatsapp_{portfolioId}` identifier, the message will fail with `sending_failed` status:

{% code lineNumbers="true" expandable="true" %}

```json
{
  "id": "b4c5d6e7-f8a9-0123-bcde-f01234567890",
  "status": "sending_failed",
  "reason": "...",
  "failure": {
    "code": 15008,
    "description": "Unsupported action",
    "source": {
      "name": "whatsapp",
      "code": "131062"
    }
  }
}
```

{% endcode %}

| Field                 | Value                        |
| --------------------- | ---------------------------- |
| `failure.code`        | `15008` (Unsupported action) |
| `failure.description` | `Unsupported action`         |
| `failure.source.name` | `whatsapp`                   |
| `failure.source.code` | `131062`                     |

To avoid this, check the contact's identifiers and use `phonenumber` when sending authentication templates.

***

### Notes

* **Authentication templates:** One-tap, zero-tap, and copy code authentication templates cannot be sent to a BSUID. These require a phone number.
* **Phone number recommendation:** When both phone number and BSUID are available, sending by phone number is recommended to ensure continued phone number availability in webhooks.
* **Identifier resolution:** When you submit `whatsappbsuid`, it is resolved to `whatsapp_{portfolioId}` based on the channel configuration. Responses and webhooks will show the resolved portfolio-scoped key.
* **BSUID rotation:** When a user's BSUID changes, Bird automatically updates contact identifiers. No manual action is required.

***

### FAQs

#### Identifiers and adoption

**How do end users obtain a BSUID? Do they need to opt in?**

* Usernames — and the BSUID that comes with them — are an optional WhatsApp feature that users adopt themselves inside the WhatsApp app. There is no business-side consent step. Once a user has adopted a username, their BSUID is delivered to you automatically on the next inbound message or status webhook for that contact.

**Can I bulk-resolve BSUIDs for my existing phone-number database?**

* No. Neither Meta nor Bird exposes a lookup endpoint that resolves a phone number to a BSUID. BSUIDs are only delivered to you via traffic — inbound message webhooks and status update webhooks. There is no historical backfill: contacts that never interact again will not gain a BSUID.

**Will Bird retroactively populate BSUIDs for contacts I interacted with before BSUID was enabled?**

* No. Enrichment is gradual and traffic-driven. BSUIDs are attached to a contact only after Bird receives them on an inbound message or status webhook.

#### Conversations API

**Is BSUID supported in the Conversations API?**

* Yes. The Conversations API operates at the contact level, not the identifier level, so you do not need to pass `identifierKey: "whatsappbsuid"` explicitly. When you send a message in a conversation, Conversations resolves the contact participant's identifiers and routes via the best available one for the WhatsApp channel.
* The resolution rule for WhatsApp channels is:
  1. Use `phonenumber` if the contact has one.
  2. Otherwise, fall back to the first acceptable alternate identifier on the contact — either `whatsapp_{portfolioId}` (BSUID) or `whatsappusername`.
* If the contact has no phone number but does have a BSUID or username, the message is still routed through to Channels for delivery. You do not need to implement client-side fallback logic. This alternate-identifier fallback applies only to WhatsApp channels.

**Can the same conversation continue if a contact later becomes reachable only via BSUID**

* Yes. Conversations are tied to contact ID + conversation ID, not to a specific identifier. If a contact previously had a phone number and later becomes reachable only via BSUID (for example, because they adopted a WhatsApp username and Meta stopped including their phone number in webhooks after 30 days without phone-based interaction):
  * The same `conversationId` continues to work.
  * No new conversation needs to be created.
  * When an agent replies, Conversations re-resolves the contact's current identifiers on every send and routes via the best available one.
  * Bird updates the contact record automatically as inbound messages and status webhooks carry BSUID data.

#### Sending

**Will the recipient's BSUID appear in my send-message response when I send by phone number?**

* No. The send response only contains the identifier used for delivery. The BSUID will arrive on the next inbound message or status webhook for that contact.

**Do I need to implement phone → BSUID fallback in my own code?**

* If you are using the Conversations API, no — it handles fallback automatically (see above). If you are using the Channels API and addressing a contact by ID, Channels routes via the best available identifier. You only need to handle fallback explicitly if you are sending directly to a `phonenumber` identifier value and want to retry against a BSUID on failure.

**Which status codes signal "phone not available, try BSUID"?**

* `400` (malformed request) and `422` (validation failure — no matching identifier, or unsupported message type for the resolved identifier). There is no `410` response in this flow.

**What happens if Meta rejects a BSUID-targeted send (for example, an authentication template)?**

* The rejection comes back asynchronously as a status update on the message. The status becomes `sending_failed` with failure code `15008` (Unsupported action) and source code `131062`. See Error Handling for the inline reference.

#### Authentication / OTP templates

**How do I send Authentication or OTP templates to a user who only has a BSUID?**

* You can't — Meta does not allow one-tap, zero-tap, or copy-code authentication templates over BSUID; they require a phone number. The recommended pattern is to collect the phone number explicitly during your OTP or 2FA setup flow (for example, "Enter your phone number to set up 2FA").
