> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ycloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Use business-scoped user IDs

> Send WhatsApp messages and calls with BSUIDs, request phone numbers, manage Meta contact book entries, and process BSUID webhook fields.

## Why BSUIDs exist

WhatsApp is rolling out optional usernames in 2026. When a user adopts a
username, WhatsApp can display the username instead of the user's phone number
and may omit the phone number from webhook payloads. Each user controls whether
to adopt a username, so businesses cannot rely on phone numbers as the only way
to identify customers. Meta therefore requires WhatsApp Business Platform
businesses and partners, as well as click-to-WhatsApp advertisers, to support
BSUIDs so they can continue processing messages from users who adopt usernames.

To support this change, Meta began adding business-scoped user IDs (BSUIDs) to
webhook payloads in early April 2026. A BSUID is a backend identifier for one
WhatsApp user within one Meta business portfolio. Meta includes it in message
webhooks whether or not the user has adopted a username, and it can be used to
message the user when their phone number is unavailable.

Usernames and BSUIDs have different lifecycles. A user can change their username
without changing their phone number or BSUID. If the user changes their phone
number, Meta generates a new BSUID. Store these identifiers separately and
update their association when you receive a phone-number-change system event.

A phone number can still appear when the business phone number has exchanged a
message or call with the user in the previous 30 days, or when Meta's contact
book contains the user. Treat phone-number and username fields as conditional,
and update parsers and identity storage to accept BSUIDs alongside any other
identifiers that are present.

This guide covers BSUID identity rules, message and call requests, Meta's
contact book, and the webhook fields your integration needs to store.

![WhatsApp user username example](https://files.readme.io/c54a96e597abe46e0f10e95d3844aa9dfdc5f9b2f5d99f27a9fa535c342c190c-image.png)

## Understand the identifiers

| Identifier | Scope | Example | When to use it |
| - | - | - | - |
| Phone number | A WhatsApp account | `+16315551111` | Use it when the phone number is available and the operation requires one. |
| BSUID | One Meta business portfolio and one WhatsApp user | `US.13491208655302741918` | Use it from any business phone number in the same portfolio. |
| Parent BSUID | A set of linked Meta business portfolios and one WhatsApp user | `US.ENT.11815799212886844830` | Use it only after Meta enables parent BSUIDs for the linked portfolios. |

Meta generates regular BSUIDs automatically. Each BSUID starts with the user's
ISO 3166 alpha-2 two-letter country code, followed by a period and up to 128
alphanumeric characters. Preserve the complete value. Do not remove or change
the country prefix, period, or identifier characters.

BSUIDs have these lifecycle rules:

* A BSUID is unique to one business portfolio and user pair.
* A user's BSUID changes when the user changes their phone number.
* A parent BSUID works across the linked portfolios for which Meta enabled it.
* A business phone number cannot use a regular BSUID scoped to another
  portfolio.

<Warning>
  One-tap, zero-tap, and copy-code authentication templates require a phone
  number. Do not send these template types with only a BSUID.
</Warning>

To link portfolios and use parent BSUIDs, ask your Meta point of contact to
check your eligibility. You can continue using regular BSUIDs within their
original portfolios after Meta enables parent BSUIDs.

![Business-scoped user ID example](https://files.readme.io/c5d4091ce670e159e8d0e82cca1f053a08419c2c3df42b50631e5e163bd88f16-image.png)

## Before you begin

* Store your YCloud API key in `YCLOUD_API_KEY`.
* Use a WhatsApp business phone number owned by the same portfolio as the
  regular BSUID.
* Subscribe your webhook endpoint to the WhatsApp events your integration uses.
* Treat every new BSUID, parent BSUID, phone number, and username field as
  optional when deserializing webhooks.
* Store the regular BSUID and parent BSUID independently when both are present.

## Send a message with a BSUID

Both WhatsApp message endpoints accept `recipient`:

| Endpoint | Behavior |
| - | - |
| `POST /whatsapp/messages/sendDirectly` | Submits the message synchronously to the WhatsApp Business API. |
| `POST /whatsapp/messages` | Queues the message for asynchronous submission. |

Set `recipient` to either a regular BSUID or a parent BSUID. Omit `to` when you
want YCloud to address the user by BSUID.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  https://api.ycloud.com/v2/whatsapp/messages/sendDirectly \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "recipient": "US.13491208655302741918",
    "type": "text",
    "text": {
      "body": "Hello from YCloud!"
    }
  }'
```

Use the same request body with `POST /whatsapp/messages` to enqueue the message.

| Input | Result |
| - | - |
| Only `to` | YCloud sends to the phone number. |
| Only `recipient` | YCloud sends to the BSUID or parent BSUID. |
| Both `to` and `recipient` | YCloud uses `to` and ignores `recipient`. |
| Neither field | YCloud rejects the request. |

## Request a user's phone number

Use a request-contact-info message when your workflow needs a phone number that
was not included in a webhook. The user decides whether to share it.

### Use a template button

Add a `REQUEST_CONTACT_INFO` button to a utility or marketing template. The
button text is fixed as `Share Contact Info`, and the button does not accept
send-time parameters.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "buttons",
  "buttons": [
    {
      "type": "REQUEST_CONTACT_INFO",
      "text": "Share Contact Info"
    }
  ]
}
```

Create and approve the template before sending it. See
[Request phone number template](/en/api-reference/guides/examples/api-examples/whatsapp-template-creation-examples#request-phone-number-template)
for a complete template request.

### Use an interactive message

Send an interactive `request_contact_info` message when you do not need a
template:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  https://api.ycloud.com/v2/whatsapp/messages/sendDirectly \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "recipient": "US.13491208655302741918",
    "type": "interactive",
    "interactive": {
      "type": "request_contact_info",
      "body": {
        "text": "Please share your phone number."
      },
      "action": {
        "name": "request_contact_info"
      }
    }
  }'
```

### Handle the contact response

When the user shares contact information, YCloud sends a
`whatsapp.inbound_message.received` event whose message `type` is `contacts`.
For a response to your request, `contacts[].origin` is `contact_request`.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "whatsapp.inbound_message.received",
  "whatsappInboundMessage": {
    "fromUserId": "US.13491208655302741918",
    "type": "contacts",
    "contacts": [
      {
        "origin": "contact_request",
        "phones": [
          {
            "phone": "+16315551111",
            "wa_id": "16315551111"
          }
        ]
      }
    ]
  }
}
```

Validate the event signature, acknowledge it with a `2xx` response, and process
the phone number asynchronously. A contact shared directly from WhatsApp can
also include a vCard.

![Request contact information button](https://files.readme.io/25f756fa17526a20962fb5984ea8ed13a460bbf4cc241976de79a16ea4e16f1e-image.png)

## Understand Meta's contact book

Meta's contact book stores the association between a user's phone number and
BSUID. With the feature enabled, sending or receiving a message or call using
the user's phone number records both identifiers. Meta can then include that
association in webhooks even after the user adopts a username.

Contact books belong to individual business portfolios. Linked portfolios do
not share or synchronize their entries: record the association independently
in each portfolio.

Meta retains entries until you disable the feature or deactivate your account.
You can disable it in **Meta Business Suite > Business settings > Business
info**. Disabling the feature deletes the stored entries and stops recording
new ones. Re-enabling it starts collecting new entries; it does not restore
the deleted data.

![Meta contact book settings](https://files.readme.io/c1465b831ff80153963ef8dac686f92dfbdc2758a8ae93a113c692c5f404b148-image.png)

### Contact requests and Local Storage

When a user shares their phone number through a request-contact-info button,
Meta adds the phone number to the contact book if the feature is enabled.
For businesses using Local Storage, Meta extracts the phone number from the
shared vCard and stores it in the contact book on Meta data centers. Other
vCard data is not retained beyond the standard retention period.

Meta removed the earlier requirement to send a separate message to capture
this association. See the [official BSUID documentation](https://developers.facebook.com/documentation/business-messaging/whatsapp/business-scoped-user-ids#contact-book)
for the current Local Storage behavior.

### Delete a Meta contact book entry

Delete a Meta contact book entry for a regular BSUID through one WhatsApp
business phone number with:

`DELETE /whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/contactBook/{bsuid}`

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request DELETE \
  "https://api.ycloud.com/v2/whatsapp/phoneNumbers/WABA_ID/%2B16315551111/contactBook/US.13491208655302741918" \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Accept: application/json"
```

Use a standard BSUID for this operation. Parent BSUIDs containing `.ENT.` are
not supported. URL-encode the leading `+` in the phone number as `%2B` when you
construct the path manually.

An HTTP `200` response always contains `success: true`. A `deleted` value of
`true` means Meta deleted a matching entry. A value of `false` means Meta
processed the request but found no matching entry.

Deleting the entry does not delete YCloud contacts, messages, or BSUID business
records. After deletion, webhook events for business phone numbers in the same
Meta business portfolio no longer include the user's phone number and BSUID
together. Meta's 30-day cache can still supply both identifiers, and a later
interaction can create the contact book entry again.

## Start a call with a BSUID

`POST /whatsapp/calls/connect` also accepts `recipient`. The same target rules
apply: provide `to` or `recipient`, and `to` takes precedence when both are
present.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  https://api.ycloud.com/v2/whatsapp/calls/connect \
  --header "X-API-Key: $YCLOUD_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "from": "+16315551111",
    "recipient": "US.13491208655302741918",
    "sdpType": "offer",
    "sdp": "SDP_OFFER"
  }'
```

For the complete calling lifecycle, see
[Manage WhatsApp calls](/en/api-reference/guides/whatsapp-platform/manage-whatsapp-calls).

## Process BSUID webhook fields

The following fields are additions to existing event payloads. Keep the event's
top-level object when defining your data model.

| Event | Optional fields to store |
| - | - |
| `whatsapp.message.updated` | `whatsappMessage.recipientUserId`, `whatsappMessage.parentRecipientUserId`, `whatsappMessage.customerProfile.name`, `whatsappMessage.customerProfile.username` |
| `whatsapp.inbound_message.received` | `whatsappInboundMessage.fromUserId`, `whatsappInboundMessage.fromParentUserId`, `whatsappInboundMessage.customerProfile.username` |
| `whatsapp.user.preferences` | `whatsappUserPreference.userId`, `whatsappUserPreference.parentUserId` |
| `whatsapp.call.connect` | `callingConnect.toUserId`, `callingConnect.toParentUserId`, `callingConnect.fromUserId`, `callingConnect.fromParentUserId` |
| `whatsapp.call.terminate` | `callingTerminate.toUserId`, `callingTerminate.toParentUserId`, `callingTerminate.fromUserId`, `callingTerminate.fromParentUserId` |
| `whatsapp.call.status.updated` | `callingStatusUpdated.recipientUserId`, `callingStatusUpdated.parentRecipientUserId` |
| `whatsapp.group.participants_update` | `whatsappGroup.recipientUserId`, `whatsappGroup.parentRecipientUserId`, `whatsappGroup.customerProfile.username`, and the `recipientUserId` and `parentRecipientUserId` fields in `whatsappGroup.addedParticipants[]`, `whatsappGroup.removedParticipants[]`, and `whatsappGroup.failedParticipants[]` |
| `whatsapp.smb.history` | `whatsappInboundMessage.fromUserId`, `whatsappInboundMessage.fromParentUserId`, `whatsappInboundMessage.customerProfile.username`, `whatsappMessage.toUserId`, `whatsappMessage.toParentUserId` |
| `whatsapp.smb.app.state.sync` | `whatsappSmbAppStateSync.stateSync[].contact.userId`, `whatsappSmbAppStateSync.stateSync[].contact.parentUserId`, `whatsappSmbAppStateSync.stateSync[].contact.username` |
| `whatsapp.smb.message.echoes` | `whatsappMessage.toUserId`, `whatsappMessage.toParentUserId`, `whatsappMessage.customerProfile.username` |

Apply these omission rules:

* A parent BSUID field is absent when parent BSUIDs are not enabled.
* A sent message or call target field can be absent when you addressed the user
  by phone number.
* `customerProfile` appears on `sent`, `delivered`, and `read` message updates,
  but not on `failed` updates.
* `customerProfile.username` is absent when the user has not enabled usernames.
  It is also absent from `sent` status updates.
* A phone number can be absent even when the corresponding BSUID is present.

### Handle a user changing phone numbers

When an inbound message has `type: system` and
`system.type: user_changed_number`, replace the old identity mapping with the
new values. The `system` object's BSUID field names remain in Meta's snake\_case
format.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "system",
  "system": {
    "type": "user_changed_number",
    "wa_id": "16315552222",
    "user_id": "US.13491208655302741919",
    "parent_user_id": "US.ENT.11815799212886844831"
  }
}
```

Treat `parent_user_id` as optional. Keep the old and new values long enough to
reconcile existing conversations and idempotently update your identity store.

## Business usernames

A business username helps customers find your business in WhatsApp. It does
not hide your business phone number. Each phone number can have one username,
and a username cannot be shared by two WhatsApp phone numbers.

A consumer username can change without changing the user's BSUID. Keep the
username as profile information rather than using it as your identity key.

See [Claim a business username](/en/documentation/channels/whatsapp-accounts-management/phone-number-management/claim-a-business-username)
for the 3–35 character format rules and the claiming and review process.

![Business username example](https://files.readme.io/6e95c9da234529464ce05185f1771b12f3afe2c8c9dca9d0d37675f5b9a7950a-image.png)

### Reserved usernames

You can claim an eligible username reserved by Meta or choose another username
for your brand. Use WhatsApp Manager, Meta Business Suite, or the username API.
Approval does not by itself mean that a username is active for customers.

If the reserved username belongs to your Facebook Page or Instagram account,
link your business phone number to that Page or account before claiming it.
You can link it while claiming the username in Meta Business Suite or WhatsApp
Manager, or [add the phone number to the Page or account](https://www.facebook.com/business/help/4631406400243963).
You need full control or basic partial access with `manage_phone` permission.

### Chat window display priority

WhatsApp displays business identity in this order:

1. The name saved in the customer's contacts.
2. The verified business name or Official Business Account name.
3. The business username.
4. The phone number.

Your business phone number remains visible in the business profile.

## Migration checklist

1. Add every BSUID-related webhook field to your deserialization model as an
   optional field.
2. Store regular and parent BSUIDs separately from phone numbers and usernames.
3. Index customer identity by portfolio and BSUID. Do not treat a BSUID as a
   globally portable identifier.
4. Route message and call requests through either `to` or `recipient`, and test
   the `to` precedence rule.
5. Test username-only users, missing phone numbers, phone-number changes, missing
   parent BSUIDs, duplicate webhooks, and contact book re-creation.

<CardGroup cols={2}>
  <Card title="Message status examples" icon="message-check" href="/en/api-reference/guides/examples/webhook-examples/whatsapp-message-updated-webhook-examples">
    Inspect sent, delivered, read, and failed message payloads.
  </Card>

  <Card title="Inbound message examples" icon="inbox" href="/en/api-reference/guides/examples/webhook-examples/whatsapp-inbound-message-webhook-examples">
    Inspect contacts, system updates, and other inbound payloads.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.