POST /v1/wa/messages endpoint, changing only the value of the recipient field.
What a BSUID is
BSUID stands for Business-Scoped User ID. It is an identifier Meta generates to represent a WhatsApp user without exposing their phone number. It exists because of WhatsApp’s username rollout, planned for 2026. When a user chooses to chat by username, or opts to keep their number hidden, your business stops receiving the phone number and receives a BSUID instead. This identifier lets you continue the conversation normally, except the real phone number is never revealed. A BSUID is scoped to a business portfolio. The same user shows up with a different BSUID for each portfolio, so a BSUID is only valid inside the portfolio that received it (see Limitations and errors).The BSUID is exclusive to the official channel (WABA). On the unofficial channel (QR code), the analogous identifier is the LID, which flows through the normal JID path. A BSUID sent to an unofficial instance is rejected with the
waba_bsuid_requires_waba error.Format
A BSUID has two forms:
Format rules:
- The prefix is the ISO 3166 alpha-2 country code (two letters, such as
US,BR,PT). - Then comes a dot (
.). - Parent BSUIDs insert the
ENTsegment (also followed by a dot) between the country code and the identifier. - The final identifier is up to 128 alphanumeric characters and is opaque: treat it as a meaningless string and never alter it.
How to send
Sending is identical to a regular WABA message. You use the samePOST /v1/wa/messages endpoint and the same request signature. The only difference is that the recipient field takes the BSUID instead of a phone number. Zapster detects the BSUID format automatically and builds the Meta Cloud API payload with the correct field.
Before you start, you need a connected WABA instance. In every example, replace YOUR_API_TOKEN with your API token and YOUR_INSTANCE_ID with the WABA instance ID. The example BSUID (US.13491208655302741918) stands for the recipient; use the real BSUID that arrived in your webhook.
As with any free WABA message, text, media, and buttons are only delivered inside the 24-hour conversation window. Outside the window, use an approved template (see further below). The full breakdown is in Sending WhatsApp messages with WABA.
Plain text
Media (image, video, or document)
Send the media by public URL or base64 in themedia field. The type is detected automatically from the file.
Interactive buttons
The WABA button rules also apply to BSUID: up to 3reply buttons, or exactly 1 url button, without mixing the two types. The full matrix is in Messages with buttons.
Template (outside the 24h window)
Templates work with BSUID, with one important exception: one-tap, zero-tap, and copy-code authentication templates are not supported for BSUID and are rejected by Meta with error131062 (see Limitations and errors). Utility and marketing templates, and authentication templates with a text code, work normally.
The template object is a mirror of Meta’s format. Details of components, positional variables, and named variables are in Sending WhatsApp messages with WABA.
Where the BSUID comes from
You do not invent a BSUID: it arrives through incoming webhooks. Zapster normalizes every webhook before delivering it, so you never deal with Meta’s raw fields. The contact always arrives in the same shape, withid, phone_number, and bsuid.
In a message.received event, the customer’s contact comes in sender (and, in one-to-one conversations, also in recipient, which mirrors sender). The id field is the primary identifier and follows a simple rule: phone number when it exists, BSUID when it does not.
- Phone number visible:
phone_numbercarries the number andbsuidcarries the BSUID (Meta sends both).idpoints tophone_number. - Phone number hidden (a privacy-conscious user):
phone_numberisnull,bsuidcarries the BSUID, andidtakes the BSUID value.
message.received in both scenarios. In both, the contact’s id is the value you use in recipient to reply within the 24-hour window:
Visible phone number (phone + BSUID)
Visible phone number (phone + BSUID)
phone_number and bsuid are both filled in, and id points to phone_number.message.sent, message.delivered, message.read), the customer’s contact comes in recipient in the same shape, so the BSUID appears in recipient.bsuid (and in recipient.id when the phone number is hidden).
The practical flow is: the customer messages your number, you receive the webhook, you read the contact’s id (which is already the BSUID when the phone number is hidden), you store that value, and you use it in the recipient of POST /v1/wa/messages to reply within the 24-hour window. See Available events for the webhook catalog.
Limitations and errors
When the payload uses a feature the Cloud API does not support with BSUID, Zapster rejects the request right away with a400 error, without silently dropping anything.
On top of that, remember the per-portfolio scope:
- A BSUID is scoped to a business portfolio. A BSUID received in one portfolio does not work in another. If you try to send to a BSUID from an instance tied to a different portfolio, Meta rejects the send. Always reply using the same instance (same portfolio) that received that BSUID.
Best practices
- Accept and normalize the prefix casing. The country code and the
ENTsegment are structural and canonically uppercase (US,US.ENT.). Zapster normalizes a BSUID typed asus.ent.<id>to the form Meta emits, so a lowercase value inrecipientalso works. - Never alter the identifier. The part after the prefix is opaque and may be case-sensitive. Preserve it byte for byte: no uppercasing, no trimming of zeros, no transformation of any kind.
- Store the canonical BSUID for correlation. Save the BSUID in its canonical form (uppercase prefix, intact identifier) to match the value that arrives in webhooks and keep the contact’s history consistent. Keep in mind that when the user changes their number, Meta generates a new BSUID for them, so treat the BSUID as the contact’s identifier within that portfolio, not as something permanent.
Next steps
- Sending WhatsApp messages with WABA for the full guide on text, media, buttons, and templates
- WABA vs unofficial to understand the difference between BSUID (official) and LID (unofficial)
- Available events to receive the BSUID in incoming webhooks