Updated on October 28, 2026
Usernames are unique, optional names that people and businesses can adopt on WhatsApp; once a customer turns theirs on, their phone number may stop showing up in your WhatsApp Business API webhooks. To keep integrations able to tell who wrote in, Meta introduced the BSUID (business-scoped user ID), a user identifier that is only valid inside your business portfolio. It has appeared in webhooks since April 2026, and since July 2026 the API accepts it as a message recipient.
What WhatsApp usernames are
According to Meta’s BSUID documentation, a username is a name a user can set so it appears in the app instead of their phone number. Each person has at most one, can change it from time to time, and changing it does not affect their phone number or BSUID. Adopting a username is optional for both people and businesses.
On the business side there is the business username. It does not hide the business phone number (Meta is explicit that business usernames are not a privacy feature), and each username maps to a single business phone number. Format rules:
- English letters, digits, periods and underscores only;
- 3 to 35 characters, with at least one letter;
- cannot start or end with a period or contain two consecutive periods;
- cannot start with
www.or end with a domain suffix such as.com; - case-insensitive, but periods and underscores count:
mystore,my.storeandmy_storeare different names.
Since June 29, 2026, businesses can reserve and adopt a username through Meta Business Suite, WhatsApp Manager, the WhatsApp Business app or the API. In the October 23, 2026 update, Meta added a limit: each business phone number can change its username up to 2 times in a rolling 14-day period (10 times for reserved usernames). Beyond that, the API returns error 130429.
What a BSUID is
A BSUID identifies a WhatsApp user for one specific business. Per the documentation, it is:
- generated automatically, whether or not the user has a username;
- made of the ISO 3166 alpha-2 country code, a period and up to 128 alphanumeric characters, e.g.
US.13491208655302741918; - unique per user + business portfolio pair (formerly Business Manager);
- regenerated when the user changes their phone number.
Scope is what trips people up: a BSUID only works with business phone numbers in the same portfolio. In a SaaS, the BSUID received on customer A’s number cannot be used to send from customer B’s number.
Businesses with several portfolios can ask Meta for a parent BSUID, valid across all enrolled portfolios. It has ENT after the country code (US.ENT.11815799212886844830) and arrives in the parent_user_id field. Enrollment depends on eligibility checked by your Meta point of contact.
Meta states that BSUID support is mandatory for partners, directly integrated businesses and click-to-WhatsApp advertisers, because no one controls when a customer will turn on a username.
Want to try it while you read? Create a Vectalk account and send your first message through the official API. Create free account →
New webhook fields
The BSUID shows up in every webhook that would normally carry the phone number. Documented fields:
| Webhook | Field | Contains |
|---|---|---|
| Incoming message | contacts[].user_id | User’s BSUID |
| Incoming message | contacts[].profile.username | Username, only if the user has one |
| Incoming message | messages[].from | Phone number (may be omitted) |
| Incoming message | messages[].from_user_id | BSUID |
| Status | statuses[].recipient_id | Phone number (may be omitted) |
| Status | statuses[].recipient_user_id | BSUID, always included (except failed sent to a phone number) |
| Any, if enabled | parent_user_id, from_parent_user_id, recipient_parent_user_id | Parent BSUID |
An incoming message webhook from someone who turned on a username and whom you haven’t talked to in the last 30 days can arrive like this, with no phone number:
{
"contacts": [
{
"profile": { "name": "Pablo M.", "username": "pablomorales" },
"user_id": "BR.13491208655302741918"
}
],
"messages": [
{
"from_user_id": "BR.13491208655302741918",
"id": "wamid.HBgL...",
"timestamp": "1761650000",
"type": "text",
"text": { "body": "Hi, has my order arrived?" }
}
]
}
user_preferences, group and calling webhooks also gained these fields. A new business_username_updates webhook tells you when your business username status changes (context: "revoked" when Meta revokes it).
When the phone number is still included
Even with a username on, the user’s number stays in the payload if at least one of these is true:
- you messaged or called that number in the last 30 days;
- you received a message or call from that number in the last 30 days;
- the user is in your contact book.
The first two conditions are evaluated per business phone number, not per portfolio. If the customer talks to your sales number, the webhook on your support number may arrive without a phone number.
Number changes and BSUID changes
When a user changes numbers, the BSUID is regenerated and you get a system message on the messages field with system.type set to user_changed_number, carrying user_id, previous_user_id and wa_id when the number can be shared. If it can’t, the type is user_changed_user_id and only the identifiers change. Just subscribe to messages (user_id_update is not a subscribable field). For the general event format, see WhatsApp API message status webhooks and the WhatsApp API glossary.
How to send a message to a BSUID
Since July 2026, POST /<PHONE_NUMBER_ID>/messages accepts a recipient field with the BSUID instead of to:
curl -X POST 'https://graph.facebook.com/<API_VERSION>/<PHONE_NUMBER_ID>/messages' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"recipient": "BR.13491208655302741918",
"type": "text",
"text": { "body": "Your order is out for delivery." }
}'
Rules worth remembering:
- Use the full value. Country code, period and every character. Any change makes the request fail.
tobeatsrecipient. If you send both, Meta uses the phone number.- Exception: authentication. One-tap, zero-tap and copy code authentication templates require the phone number. Sending them to a BSUID returns error
131062. - Portfolio scope. A BSUID from another portfolio won’t work.
The Marketing Messages API has supported sending to BSUIDs since May 5, 2026, but Meta warns that delivery optimization doesn’t run on those sends and recommends using the phone number when you have it.
Asking the customer for their number
If a contact only has a BSUID and you need the number (for invoicing, billing or OTP), Meta created the REQUEST_CONTACT_INFO button. It can go in utility and marketing templates or be sent as an interactive message. When the user taps it, the number is shared in the chat and a contacts webhook arrives with origin: "contact_request". The button label can’t be customized.
The contact book Meta keeps for you
The contact book is hosted by Meta and needs no integration. Once the feature launches, every interaction (message or call, sent or received) between a portfolio number and a user stores that user’s phone number and BSUID. From then on, webhooks for that user include the phone number even if they turn on a username.
Things to keep in mind:
- it isn’t retroactive: conversations from before the launch aren’t captured;
- the scope is the business portfolio;
- data is kept until you disable the feature (Meta Business Suite > Business settings > Business info) or deactivate the account; disabling deletes everything, and re-enabling doesn’t restore it;
- via the API,
GET /<PHONE_NUMBER_ID>/contact_booktells you whether a number is stored for a BSUID (presentfield) without ever returning the number, and aDELETEremoves the entry.
Impact on CRMs keyed on phone numbers
Most integrations use wa_id or from as the contact’s primary key. With usernames, messages may arrive without a phone number, and the BSUID changes when the customer changes numbers.
A model that holds up:
- Create an identities table, not a column. Each contact can have a phone number, one BSUID per portfolio and a parent BSUID.
- Look up by BSUID first, then by phone. If both match different contacts, merge them.
- Store the phone + BSUID pair whenever they arrive together. That’s how you recognize the customer when they later show up with only a BSUID.
- Handle
user_changed_numberanduser_changed_user_idby updating the BSUID fromprevious_user_id. - Reply from the same business number when possible, because of the 30-day per-number rule.
- Test before production. The App Dashboard has a Test button on the messages webhook with scenarios for users with and without usernames.
async function resolveContact(value) {
const c = value.contacts?.[0] ?? {};
const msg = value.messages?.[0] ?? {};
const bsuid = c.user_id ?? msg.from_user_id;
const phone = msg.from ?? c.wa_id; // may be empty
let contact = bsuid ? await db.contactByBsuid(bsuid) : null;
if (!contact && phone) contact = await db.contactByPhone(phone);
if (!contact) contact = await db.createContact();
await db.link(contact.id, { bsuid, phone, username: c.profile?.username });
return contact;
}
If your funnel depends on ads, the same care applies to attribution: see how to track Click-to-WhatsApp ads. Parallel account changes, like the new WABA structure, also affect IDs your CRM stores.
Timeline confirmed in Meta’s documentation
| Date | What happened |
|---|---|
| Early April 2026 | BSUIDs start appearing in webhooks |
| May 5, 2026 | /marketing_messages accepts BSUID recipients |
| June 29, 2026 | Businesses can reserve and adopt a business username |
| July 2026 | Cloud API accepts BSUID recipients; REQUEST_CONTACT_INFO button available |
| August 24, 2026 | Contact book lookup (GET .../contact_book) |
| October 23, 2026 | Username change limit (2 every 14 days) and error 130429 |
| 2026 | WhatsApp rolls usernames out to users gradually |
Meta has not published a single date for all users to have usernames; the page only mentions a gradual rollout in 2026. We track upcoming changes in WhatsApp API changes in 2026.
How it works with Vectalk
Vectalk is a proxy for the official WhatsApp Cloud API: webhooks you register with POST /api/webhooks receive the same payload Meta sends, so user_id, from_user_id, username and system messages arrive untouched. What has to change lives in your code, in the contact model above. The event reference is in the webhooks documentation, and you can sign up at apps.vectalk.com.br/register.
Frequently asked questions
Will customers who turn on a username disappear from my CRM?
Not if your integration already reads the BSUID. It arrives in every webhook, with or without a username. What may be missing is the phone number, when there was no conversation on that number in the last 30 days and the customer isn’t in the contact book.
Can I send a marketing template to a BSUID?
Yes. Sending to a BSUID supports every message type except one-tap, zero-tap and copy code authentication templates. On the Marketing Messages API, BSUID sends don’t get delivery optimization.
Does the BSUID ever change?
It changes when the user changes their phone number. Changing a username doesn’t change the BSUID. The change arrives as a system message on the messages webhook.
Does a username hide my business phone number?
No. Meta says business usernames don’t hide the business number and aren’t meant as a privacy feature.
Does one BSUID work for all my SaaS customers?
No. It’s limited to the business portfolio where it was generated. Each customer will have its own BSUIDs for the same users.
Official sources consulted on October 28, 2026: Business-scoped user IDs (updated October 23, 2026), WhatsApp Business Platform changelog, Send marketing messages (Marketing Messages API).
Try the official WhatsApp API today
Create your account, generate a token and send your first message with the quick-start guide. Same payloads and webhooks as Meta's Cloud API.
