For the complete documentation index, see llms.txt. This page is also available as Markdown.

Business-Scoped User IDs

WhatsApp Business-Scoped User IDs (BSUIDs) — API Examples

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 June 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 June 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 June 2026

From end of June 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 June 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:

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):

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:

Response (202 Accepted):

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.

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.

Key points:

  • No phone number — sender is identified by whatsappusername

  • No platformAddress on the sender (username is not a dialable address)

  • 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 accepteddelivered. 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.

Message delivered — sent to BSUID, phone number unavailable

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

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.

Read interaction — phone number available

Read interaction — phone number unavailable

Reaction interaction

Delete interaction

When a user deletes a message, a deleteRequest interaction is emitted.


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:

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:

Response (200 OK):

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:

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").

Last updated

Was this helpful?