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
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:
Read
whatsappbsuidfrommeta.extraInformationand store BSUIDs against your contact records, alongside phone numbers where available.Handle the case where
sender.contact.identifierKeyiswhatsappusername— do not assumephonenumberis always present.Use
whatsappbsuidas the stable, durable identifier for a user. Phone numbers can become unavailable; BSUIDs persist (and Bird handles rotations automatically).When replying to a username-identified sender, use the
whatsapp_{portfolioId}key fromsender.contact.identifiers, or send usingidentifierKey: "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:
whatsappbsuidis always present once BSUIDs are enabledwhatsappusernameis present because the user adopted a usernamesenderis identified byphonenumbersince the phone is available — BSUID identifiers are NOT onsender.contact.identifiers, only inmeta.extraInformationIf the user has no username,
whatsappusernameis 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
whatsappusernameNo
platformAddresson the sender (username is not a dialable address)sender.contact.identifiersincludes the portfolio-scopedwhatsapp_{portfolioID}— use it or the genericwhatsappbsuidkey to replyBSUID 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.
Message delivered — sent to BSUID, phone number unavailable
When the phone number is not available, phonenumber is absent.
Key points:
No
phonenumbersince it's unavailablewhatsappusernameappears on delivered status if the user has adopted a usernameReceiver 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)
meta.extraInformation)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)
meta.extraInformation / metadata.extraInformation)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
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 dataThe
whatsappusernameidentifier is provisioned when the user has adopted a WhatsApp usernameUse the
whatsapp_{portfolioId}identifier key and value from the contact to send a message by BSUID, or use the genericwhatsappbsuidkey (which is resolved internally using the channel'sWA_PORTFOLIO_ID)The
{portfolioId}in the identifier key matches theWA_PORTFOLIO_IDconnection 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:
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 towhatsapp_{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:
Use
phonenumberif the contact has one.Otherwise, fall back to the first acceptable alternate identifier on the contact — either
whatsapp_{portfolioId}(BSUID) orwhatsappusername.
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
conversationIdcontinues 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
phonenumberidentifier value and want to retry against a BSUID on failure.
Which status codes signal "phone not available, try BSUID"?
400(malformed request) and422(validation failure — no matching identifier, or unsupported message type for the resolved identifier). There is no410response 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_failedwith failure code15008(Unsupported action) and source code131062. 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?

