Skip to content

Support WhatsApp Business-Scoped User IDs (BSUID) for username migration #4

Description

@carboni123

Context

WhatsApp is launching usernames — an optional privacy feature that lets users hide their phone number when messaging businesses. To support this, Meta is introducing a Business-Scoped User ID (BSUID) as a new way to identify users.

Timeline

Date Event
Early April 2026 Meta launches "contact book" feature (auto-stores phone/BSUID pairs)
May 2026 Testing phase — user_id field starts appearing in webhooks
June 2026 Username rollout begins in test countries
August 2026 Global rollout

BSUID Format

  • Pattern: CC.alphanumeric (2-letter country code + dot + up to 128 alphanumeric chars)
  • Example: BR.1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R9S0T
  • Twilio wraps it as whatsapp:CC.BSUID (max 140 chars with prefix)

Webhook Payload Changes (Cloud API)

A new user_id field will appear in all message webhooks, even for users without usernames:

{
  "contacts": [{"profile": {"name": "Jessica"}, "wa_id": "BR.1A2B3C..."}],
  "messages": [{
    "from": "BR.1A2B3C...",
    "user_id": "BR.1A2B3C...",
    "type": "text",
    "text": {"body": "Hello"}
  }]
}
  • User without username: wa_id/from = phone number, user_id = BSUID
  • User with username: wa_id/from = BSUID (no phone), user_id = BSUID
  • Phone numbers auto-returned for a rolling 30 days after any phone-based interaction
  • Auth templates (one-tap, zero-tap, copy-code) still require phone numbers

What needs to change in maia-messaging

1. _normalize_phone() in providers/meta.py

Currently assumes to is always a phone number (strips whatsapp: and +). Must detect BSUID vs phone and pass BSUIDs through without stripping the +.

2. Message type documentation

WhatsAppText.to, WhatsAppMedia.to, MetaWhatsAppTemplate.to now accept both phone numbers and BSUIDs.

3. Gateway phone fallback (gateway.py)

Phone fallback/denormalization logic must skip BSUID recipients — no Brazil phone normalization applies.

4. Types (optional)

Consider whether a user_id / bsuid field should be added to message or result types for the consuming app to pass through.

5. Twilio provider

Twilio adds a new ExternalUserId field mapping to BSUID. The to/from fields may contain a BSUID when no phone is available. Same detection logic needed.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions