Sign inGet started

Business-scoped user IDs

A business-scoped user ID (BSUID) is Meta's identifier for a WhatsApp user, scoped to one business portfolio. It arrives on inbound messages whether or not the contact uses a WhatsApp username, and it addresses a contact whose phone number you do not have.
Bird surfaces it as bsuid on a message's from and to, accepts it as the to of a send, and filters the message list by it. Meta's business-scoped user IDs reference is the source for the rollout itself and for what other Meta surfaces do with the identifier.

Why a contact arrives without a phone number

WhatsApp is rolling out usernames. A user who adopts one shows their username instead of their phone number in the app, and Meta then withholds the number from the payloads a business receives. The BSUID is the identity that is always there, which is why an inbound message can carry one and no phone_number at all.
Meta still includes the phone number when you already have a relationship with the contact: when that specific business phone number has messaged or called them, or received a message or call from them, in the last 30 days, or when they are in your Meta contact book. The 30-day condition is evaluated per business phone number, so a contact who wrote to one of your numbers can still arrive without a phone number on another.
A message from a WhatsApp user also carries the profile they publish, in username and display_name on from. Both are absent when the contact has not adopted a username or the message carries no profile, and neither can be used to address a message.

What a BSUID looks like

Esempio di codice
{
  "from": {
    "bsuid": "US.13491208655302741918",
    "username": "alexr",
    "display_name": "Alex Rivera"
  }
}
An ISO 3166 alpha-2 country code, a period, then up to 128 alphanumeric characters. A parent BSUID, which a managed business can be enrolled for so one identifier works across a set of portfolios, inserts ENT after the country: US.ENT.11815799212886844830. Bird accepts both forms as a recipient.
Three properties decide how you store and use one:
  • Pass the whole value, unchanged. Meta rejects a modified BSUID, so no part of it is optional: the country code, the period, and every character of the identifier travel together. Bird validates the shape before accepting a send, and the country code has to be uppercase and a real ISO 3166 alpha-2 code; a lowercase or unknown prefix is refused rather than corrected. The 128-character bound applies to the identifier after the country code, and after the ENT. segment on a parent BSUID.
  • It is scoped to a business portfolio. Any business phone number in the same portfolio can message that BSUID; a number in a different portfolio cannot, and the send fails.
  • It is not permanent. Meta documents that a contact's BSUID is regenerated when they change their phone number, so it identifies a conversation partner rather than serving as a durable customer key of your own.

How a conversation usually goes

A contact you have not spoken to before reaches you by BSUID, and the exchange that gets you their number runs in three steps:
  1. The contact messages you. The inbound message carries from.bsuid, and from.phone_number may be absent. That message opens the customer service window, so you can reply free-form for the next 24 hours.
  2. You ask for the number. Send a contact info request, a single button that asks the contact to share the number their WhatsApp account uses. The same ask rides on a template through its request_contact_info button, which reaches a contact whose window has closed.
  3. The contact taps the button. Their number arrives as an inbound contact card with origin set to contact_request and the number in phone_numbers. From then on the relationship satisfies Meta's own condition, so the contact's phone number is populated on the messages that follow as well.
A contact can decline. Dismissing the share sheet produces no message and no webhook, so a flow that needs a number has to time out on its own rather than wait for a decline to arrive, and it has to keep working for a contact who never shares one.

Sending to a BSUID

to takes a BSUID wherever it takes a phone number:
Esempio di codice
{
  "to": "US.13491208655302741918",
  "from": "+13124495648",
  "text": { "body": "Your order shipped." }
}
Four things differ from a send addressed by phone number:
  • from has to sit in the portfolio the BSUID is scoped to. That is the same portfolio requirement Meta applies, and a mismatch fails at WhatsApp rather than at accept.
  • One-time-passcode templates need a phone number. A Bird-managed template in the authentication category, or one carrying a one-time-passcode button, is refused at accept with a 422 E15014 WhatsAppRecipientNotSupportedForTemplate. A template your workspace authored is not checked at accept: Meta requires a phone number for one-tap, zero-tap, and copy-code authentication templates, so such a send is accepted and then fails.
  • A value that is neither a phone number nor a well-formed BSUID is refused at accept, with a 422 E15001 WhatsAppInvalidRecipient.
  • Price is keyed on the BSUID's country prefix. A phone number supplies the country a message is priced against, and for a BSUID send the two-letter prefix supplies it instead.
Everything else about the send is unchanged: the customer service window still gates free-form content, and the 202 still means accepted rather than delivered.
Address a contact on the identity they wrote to you with. Bird records an open window under each identity the inbound message carried, and a send finds the window under the identity it is addressed to. A contact who reached you by BSUID alone leaves no phone-keyed window behind, so a free-form send to a phone number you hold from elsewhere can be refused with a 422 E15044 WhatsAppServiceWindowClosed while Meta still considers the conversation open. Replying to the from of their message avoids the mismatch.

Reading and filtering by BSUID

Every read carries whatever identities the message holds:
  • On a message, from and to each carry a phone_number, a bsuid, or both. An inbound message names the contact on from; an outbound one names them on to.
  • On a webhook, the same addresses ride on the event payload. See WhatsApp events for the envelope.
  • On the message list, to and from each accept a BSUID as well as a phone number, and each matches one end of the message. The bsuid filter matches the contact in either direction. The older phone_number filter is deprecated: to and from replace it and match both kinds of identity.
Store both identities against your own contact record, and key the record on your own identifier rather than on either of Meta's. A contact can arrive with a BSUID only, gain a phone number once they share it, and get a new BSUID if they change numbers.

Next steps