Skip to main content

New user_id, parent_user_id, and username fields in the ChatArchitect API

ChatArchitect API provides additional WhatsApp user identifiers: user_id, parent_user_id, and username. They make it possible to work with users who interact with a business through a username and may not disclose their real phone number.

At the same time, ChatArchitect remains fully compatible with existing CRMs, help desks, chatbots, and other integrations that expect every WhatsApp user to have a phone number.

If a user's real phone number is unavailable, ChatArchitect automatically creates a synthetic number for that user. The phone number field therefore remains present:

  • In inbound messages.
  • In status webhooks.
  • In other related webhooks.
  • When sending outbound messages.

An integration can continue using the phone number as the primary contact identifier without changing its existing logic.

Summary

Inbound messages use these fields:

payload.sender.phone
payload.sender.user_id
payload.sender.parent_user_id
payload.sender.username

Status webhooks use:

payload.destination
payload.userId
payload.parentUserId
payload.profileUsername

To send a message, use either:

destination

or:

userId

destination accepts either a real phone number or a synthetic number created by ChatArchitect.

userId accepts either a BSUID or a Parent BSUID.

1. What user_id means

user_id is a Business-Scoped User ID, abbreviated as BSUID.

A BSUID uniquely identifies a WhatsApp user within a specific business. It is created for each business-user combination and makes it possible to interact with the user even when their real phone number is unavailable.

A BSUID is created regardless of whether the user has set a WhatsApp username.

Example BSUIDs:

US.13491208655302741918
IN.34661116580198991

The identifier starts with a two-letter ISO country code, followed by a period and a unique sequence of characters.

General format:

<ISO country code>.<unique identifier>

Example:

SK.34661116580198991

Store the BSUID exactly as received from ChatArchitect API.

Do not:

  • Change the letter case.
  • Remove the country code.
  • Remove the period.
  • Convert the value to a number.
  • Shorten the identifier.
  • Generate a BSUID yourself.

A BSUID may change, for example, if the user changes the phone number associated with WhatsApp. In this case, process the change and update the stored user data.

2. Where to find user_id in an inbound webhook

In an inbound message, the BSUID is located at:

payload.sender.user_id

Example:

{
  "version": 2,
  "type": "message",
  "payload": {
    "sender": {
      "phone": "4210012345678",
      "user_id": "SK.34661116580198991",
      "parent_user_id": "",
      "name": "Customer name",
      "username": "customer_username"
    }
  }
}

The sender object contains the phone number and additional user identifiers:

phone
user_id
parent_user_id
username

The phone field is always present.

If the user's real number is available, phone contains the real number.

If the real number is unavailable, ChatArchitect creates a synthetic number and returns it in the same phone field.

This allows legacy integrations to continue working without mandatory BSUID support.

3. ChatArchitect synthetic numbers

If a user interacts with a business through a WhatsApp username and does not disclose their real phone number, ChatArchitect automatically creates a synthetic number for that user.

General format:

+<country code>00<internal identifier>

The key indicator of a synthetic number is the two digits 00 immediately after the country code.

Example:

+42100...

Here:

+421

is the country code, and:

00

indicates that the number was created by ChatArchitect and is not the user's real phone number.

How to identify a synthetic number

First determine the country code, then inspect the first digits of the national part of the number.

If the first two digits after the country code are 00, the number is a ChatArchitect synthetic number.

Pattern:

+<country_code>00<identifier>

Parse the international country code correctly before checking the number. Do not assume the country code always contains one, two, or three digits without first parsing it.

1. Determine the international country code.
2. Separate the country code from the national part.
3. Check whether the national part starts with 00.
4. If it does, the number is a ChatArchitect synthetic number.

A synthetic number:

  • Is not the user's real phone number.
  • Is not intended for regular phone calls.
  • Must not be used for SMS.
  • Is used within ChatArchitect and connected integrations.
  • Preserves legacy data models in which a phone number is a required identifier.
  • Can be used to send messages through ChatArchitect API.

4. Sending a message to a synthetic number

To send an outbound message, use the standard parameter:

destination

It accepts:

  • A real WhatsApp phone number.
  • A ChatArchitect synthetic number.

Example:

destination=4210012345678

The integration does not need to convert a synthetic number to a BSUID. ChatArchitect resolves the associated user and sends the message to the correct WhatsApp recipient.

This lets legacy integrations continue using the same flow:

contact → phone number → send message

Even if WhatsApp does not provide the user's real number, the integration still receives a phone value that can be stored in a CRM and used as destination.

5. user_id in a billing-event webhook

In a billing webhook, the BSUID is located at:

payload.references.user_id

Example:

{
  "version": 2,
  "type": "billing-event",
  "payload": {
    "references": {
      "destination": "4210012345678",
      "user_id": "SK.1009956278697109"
    }
  }
}

In this webhook:

destination

contains the number used by the integration. It can be either a real or synthetic number.

The field:

user_id

contains the WhatsApp user's BSUID.

Note that billing events use:

user_id

not:

userId

6. What parent_user_id means

parent_user_id is a Parent BSUID.

A regular BSUID identifies a user within a specific business or business portfolio. A Parent BSUID is intended for large organizations, managed businesses, and structures that use multiple connected Business Managers or business portfolios.

A Parent BSUID makes it possible to identify the same end user across different business portfolios owned by one large organization.

In an inbound message, the field is located at:

payload.sender.parent_user_id

Example:

{
  "payload": {
    "sender": {
      "phone": "4210012345678",
      "user_id": "SK.34661116580198991",
      "parent_user_id": "SK.PARENT_IDENTIFIER",
      "username": "customer_username"
    }
  }
}

parent_user_id may be empty when a Parent BSUID is not used or is unavailable for the relevant business structure.

The integration must therefore treat it as optional.

Correct logic:

phone — always present;
user_id — the user's primary BSUID;
parent_user_id — an additional identifier for connected business portfolios;
username — the user's current WhatsApp username, when available.

7. What username means

username is the username selected by the end user in WhatsApp.

A username is optional. A user can:

  • Set a username.
  • Change it.
  • Remove it.
  • Use it to interact without disclosing their real phone number.

A username change does not mean the user has changed.

In particular, changing a username:

  • Does not necessarily change the BSUID.
  • Must not create a new contact in the CRM.
  • Must not be treated as the only persistent identifier.
  • Should update the displayed username of the existing contact.

In an inbound webhook, the username is located at:

payload.sender.username

Example:

{
  "payload": {
    "sender": {
      "phone": "4210012345678",
      "user_id": "SK.34661116580198991",
      "parent_user_id": "",
      "name": "Customer name",
      "username": "customer_username"
    }
  }
}

The username can be used:

  • As a display name for an agent.
  • To search for a contact.
  • To personalize the interface.
  • As an additional CRM field.
  • In message history.
  • To keep the user profile current.

Do not use the username as a primary key because the user can change it.

For persistent identification, use:

user_id

or the number from:

phone

In ChatArchitect, phone is always available, even when the user's real number is hidden.

8. Inbound webhook when the real number is hidden

When the user's real number is unavailable, ChatArchitect does not remove the phone field.

Instead, it contains a synthetic number:

{
  "version": 2,
  "type": "message",
  "payload": {
    "sender": {
      "phone": "4210012345678",
      "user_id": "SK.34661116580198991",
      "parent_user_id": "",
      "name": "",
      "username": "customer_username",
      "country_code": "421",
      "dial_code": "+421"
    }
  }
}

In this example:

4210012345678

is synthetic because the country code 421 is immediately followed by 00.

The integration can process the event like a regular message from a user with a real number:

  1. Find the contact by phone.
  2. If the contact does not exist, create it.
  3. Store user_id.
  4. Store parent_user_id when provided.
  5. Store or update username.
  6. Add the inbound message to the history.
  7. Use phone for subsequent outbound messages.

This keeps the required phone field available and prevents legacy integrations from breaking.

9. Fields in a status webhook

Outbound message status webhooks use these fields:

payload.destination
payload.userId
payload.parentUserId
payload.profileUsername

Field names differ from those in an inbound webhook.

Value Inbound message Status webhook
Number sender.phone destination
BSUID sender.user_id userId
Parent BSUID sender.parent_user_id parentUserId
Username sender.username profileUsername

Example:

{
  "version": 2,
  "type": "message-event",
  "payload": {
    "type": "delivered",
    "destination": "4210012345678",
    "userId": "SK.34661116580198991",
    "parentUserId": "",
    "profileUsername": "customer_username"
  }
}

The destination field is always present.

It contains:

  • The real number, when available.
  • A ChatArchitect synthetic number, when the real number is hidden.

Status webhooks can therefore be linked to outbound messages through the familiar destination field.

You can also use userId to associate the event more precisely with the WhatsApp user.

10. Sending a message through userId

In addition to sending by phone number, ChatArchitect API can send messages by BSUID.

Use this parameter:

userId

It accepts:

  • A BSUID.
  • A Parent BSUID.

Example:

userId=SK.35263896023254374

This sends a message directly to the user's business-scoped identifier.

For most existing integrations, however, it is sufficient to continue using:

destination

Because ChatArchitect provides a synthetic number, integrations are not required to switch to userId.

11. Sending both destination and userId

A single request can include both:

destination=<number>
userId=<BSUID or Parent BSUID>

When both parameters are present, this field takes priority:

destination

In other words, the number passed in destination is treated as the primary recipient.

This rule also applies to ChatArchitect synthetic numbers.

Example:

destination=4210012345678
userId=SK.34661116580198991

For a simpler integration, choose one primary addressing method:

  • Use destination if the system is built around phone numbers.
  • Use userId if the system already supports BSUID as its primary identifier.

12. BSUID validation

A BSUID is validated when a message is sent.

The API may immediately return an error if the supplied value is:

  • An unknown BSUID.
  • A malformed BSUID.
  • A BSUID that does not belong to the business.
  • A corrupted or truncated value.

Store BSUIDs without transformation.

For example, do not store only the numeric part:

34661116580198991

Store the complete value:

SK.34661116580198991

Unlike a BSUID, a synthetic number is used through the standard destination parameter, and ChatArchitect resolves the number to the user.

13. Limitations of sending by BSUID

Not all WhatsApp message types necessarily support sending by BSUID.

For an unsupported message type, the API may return this error:

131062
Business-scoped User ID recipients are not supported for this message

In particular, authentication templates require a real phone number and do not support sending only by BSUID.

A ChatArchitect synthetic number does not turn a hidden user number into a real phone number. It is an internal addressing identifier and cannot be used where Meta requires the end user's real phone number.

For authentication templates, obtain the user's real phone number first.

14. Request Contact Info and obtaining the real number

If a user voluntarily shares their number through the Request Contact Info feature, the webhook contains both the user identifiers and the shared contact.

The sender object still contains:

payload.sender.phone
payload.sender.user_id
payload.sender.parent_user_id
payload.sender.username

The real number shared by the user is inside the contact payload:

payload.payload.contacts[].phones[].phone
payload.payload.contacts[].phones[].wa_id

Example:

{
  "payload": {
    "sender": {
      "phone": "4210012345678",
      "user_id": "SK.34661116580198991",
      "parent_user_id": "",
      "username": "customer_username",
      "country_code": "421",
      "dial_code": "+421"
    },
    "payload": {
      "contacts": [
        {
          "phones": [
            {
              "phone": "+421900123456",
              "wa_id": "421900123456"
            }
          ]
        }
      ]
    }
  }
}

In this scenario:

sender.phone

may contain the ChatArchitect synthetic number created earlier, while:

contacts[].phones[].phone

contains the real number voluntarily shared by the user.

The integration can link:

  • The synthetic number.
  • The BSUID.
  • The username.
  • The real number.

This allows the contact record to be updated without creating a duplicate user.

15. How to store the new fields in a CRM or database

phone
is_synthetic_phone
user_id
parent_user_id
username
real_phone

Where:

phone

is the primary number used by the integration. It is always present and can be real or synthetic.

is_synthetic_phone

indicates that the number starts with 00 immediately after the country code.

user_id

is the user's BSUID.

parent_user_id

is the Parent BSUID, when available.

username

is the current WhatsApp username.

real_phone

is the user's real number, if it was initially available or voluntarily shared later.

Example:

{
  "phone": "4210012345678",
  "is_synthetic_phone": true,
  "user_id": "SK.34661116580198991",
  "parent_user_id": null,
  "username": "customer_username",
  "real_phone": null
}

After obtaining the real number:

{
  "phone": "4210012345678",
  "is_synthetic_phone": true,
  "user_id": "SK.34661116580198991",
  "parent_user_id": null,
  "username": "customer_username",
  "real_phone": "421900123456"
}

The exact storage model can vary, but do not create a new user only because a username appears or changes.

For new integrations, use this order:

  1. Look up the user by user_id.
  2. If the user is not found, look them up by phone.
  3. Also consider parent_user_id.
  4. Do not use username as the only persistent identifier.
  5. When a real number becomes available, link it to the existing BSUID and synthetic number.

Legacy integrations can keep their current logic:

  1. Look up the user by phone.
  2. Create a contact by phone if it does not exist.
  3. Send messages through destination.
  4. Gradually add storage for user_id, parent_user_id, and username.

Synthetic numbers make this upgrade possible without urgently redesigning the existing integration.

17. Field summary

Field Location Purpose
phone payload.sender.phone Real or synthetic number; always present
destination payload.destination Number in a status webhook and parameter for sending
user_id payload.sender.user_id BSUID in an inbound message
userId payload.userId or API parameter BSUID in a status webhook and outbound request
parent_user_id payload.sender.parent_user_id Parent BSUID in an inbound message
parentUserId payload.parentUserId Parent BSUID in a status webhook
username payload.sender.username WhatsApp username in an inbound message
profileUsername payload.profileUsername WhatsApp username in a status webhook
references.user_id payload.references.user_id BSUID in a billing event

Key point for existing integrations

ChatArchitect preserves the existing model in which a phone number is required.

Even when WhatsApp does not provide the user's real phone number:

  • sender.phone is still present.
  • destination is present in status webhooks.
  • Messages can be sent through destination.
  • Contacts can be stored in a CRM by number.
  • A synthetic number can be identified by 00 immediately after the country code.
  • BSUID, Parent BSUID, and username are also available.

This supports the new WhatsApp username and BSUID features without breaking compatibility with legacy CRMs, help desks, chatbots, and custom integrations.