WhatsApp

Connect WhatsApp

Connect a WhatsApp Business number to a profile with Embedded Signup or a Meta token, set its business profile and watch its quality and limits.

A WhatsApp account in Pozy is one WhatsApp Business number attached to a profile. Once it is connected you send templates, replies, flows and broadcasts from it, take calls on it and read every conversation in the inbox. This page gets a number connected and ready to send.

#Before you start

  • A Meta Business account. If it has no WhatsApp Business Account (WABA) yet, Meta creates one during signup.
  • A phone number for WhatsApp. Either buy one through Pozy or bring one you already own.
  • A Pozy profile id and an API key.

A personal WhatsApp account cannot be connected. Only WhatsApp Business numbers on Meta's Cloud API can.

Two WhatsApp rules apply to everything you send:

Rule What it means for you
24-hour customer service window After a customer messages you, you can reply with anything for 24 hours. Outside that window the first message must be an approved template.
Messaging limit tier Meta caps how many unique people a number can start conversations with per day. A new number starts at TIER_250 (250 per day). Meta raises the tier as the number builds history with good quality.

#Pick the kind of number

Where the number comes from decides what else it can do.

Number How it connects Calls and SMS on the same number
Bought or ported through Pozy Embedded Signup. The number is already verified and shows as Verified in Meta's picker. Yes
Your own number on your own carrier Embedded Signup, or a Meta System User token No

A number bought through Pozy is pinned to the profile you bought it for. Connecting it from another profile returns 409. Move it first with PATCH /v1/whatsapp/phone-numbers/{id}/profile.

A profile can hold several WhatsApp numbers, and each one becomes its own account. A number can only be live on one profile at a time.

#Cloud API only or coexistence

Meta lets a business keep using the WhatsApp Business app on the same number while the API is connected. Meta calls this coexistence. It is convenient, but it switches features off.

Feature Cloud API only Coexistence
Throughput Meta's standard tiers Fixed at 20 messages per second
Group chats Yes No
Calling Yes No
Profile photo Managed through the API Locked, managed in the app
Message history Starts at connection Up to 6 months synced from the app
Sends from the phone Not possible Allowed, and reported on message.sent with source: "whatsapp_business_app"

Pass onboarding=api to connect Cloud API only. Leave it out, or pass onboarding=business_app, to offer coexistence. With coexistence the person connecting scans a QR code from the WhatsApp Business app during signup, so they need the phone with them.

Warning

Meta has no API to leave coexistence. The business disconnects it in the app (Settings > Account > Business Platform > Disconnect). Pozy then deactivates the account and sends account.disconnected. To get groups and calling afterwards, connect the number again with onboarding=api.

#Connect with Embedded Signup

Embedded Signup is Meta's own signup window. You ask Pozy for a URL, send the person there, and they come back to your redirect_url with the new account id.

curl "https://api.pozy.ai/v1/connect/whatsapp?profileId=6710c4e2b9a1f03d8e5c7a21&redirect_url=https://app.example.com/whatsapp/done&onboarding=api" \
  -H "Authorization: Bearer $POZY_API_KEY"

The person logs in to Meta, picks or creates a WABA and picks the number. They land back on your page with the result in the query string:

Redirect
https://app.example.com/whatsapp/done?connected=whatsapp&profileId=6710c4e2b9a1f03d8e5c7a21&accountId=6712a9d4c0e3b58f1a7d2e64&username=%2B14155550142

Store accountId. Every WhatsApp endpoint takes it.

If signup fails, the redirect carries error and platform=whatsapp instead:

error Meaning
connection_cancelled The person closed Meta's window before finishing.
one_whatsapp_per_profile The profile rules allow no more WhatsApp numbers here. Use another profile.
whatsapp_number_pinned_to_profile A Pozy number that belongs to another profile. Connect it there or move it first.
whatsapp_number_already_connected The number is live on another profile or workspace. Disconnect it there first.
payment_required The workspace needs a payment method.
whatsapp_error Meta refused the signup. Meta's reason, when given, is in error_message.

#Let Pozy host the signup page

When one Facebook login manages several WhatsApp accounts (agency staff, a business with several brands), the redirect flow above can only learn that the person authorized, not which number they picked in Meta's window. Pozy then asks them to pick the number a second time.

Add signup=hosted and authUrl points to a Pozy page instead of Meta's dialog. That page opens Meta's window itself, reads which number the person chose and connects exactly that one. You embed nothing and register no domain with Meta.

Parameter Effect Rules
brandName Page title reads "Connect your WhatsApp number to brandName" 1 to 60 characters
primaryColor Colour of the main button and step accents Hex #RRGGBB
language Language of the page and its checklist en (default), es or pt-BR

These three only work with signup=hosted. Anywhere else they return 400. The hosted page stays valid for 60 minutes; after that the person lands on your redirect_url with error=session_expired and you request a new URL.

#Pick the number in your own UI

Pass headless=true if you want to show your own number picker. When the chosen WABA holds two or more numbers, the person lands on your redirect_url with step=select_phone_number, profileId and a short-lived tempToken. A WABA with one number connects straight away and skips this step.

# 1. List the numbers the person can pick from
curl "https://api.pozy.ai/v1/connect/whatsapp/select-phone-number?profileId=6710c4e2b9a1f03d8e5c7a21&tempToken=$TEMP_TOKEN" \
  -H "Authorization: Bearer $POZY_API_KEY"

# 2. Connect the one they chose
curl -X POST https://api.pozy.ai/v1/connect/whatsapp/select-phone-number \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "profileId": "6710c4e2b9a1f03d8e5c7a21",
    "phoneNumberId": "109876543210987",
    "wabaId": "204567890123456",
    "tempToken": "'"$TEMP_TOKEN"'"
  }'

Each listed number includes its display_phone_number, verified_name, quality_rating, name_status and messaging_limit_tier, which is enough to build a useful picker.

#Connect with a Meta token (no browser)

If you already manage the business in Meta, connect from your server with a permanent System User token. This suits provisioning scripts and server-to-server setups.

  1. In Meta Business Suite, create a System User and generate a token with whatsapp_business_management and whatsapp_business_messaging. Add whatsapp_business_manage_events if you want to send Click-to-WhatsApp conversions.
  2. Copy the WABA id and the phone number id from WhatsApp Manager.
  3. Call POST /v1/connect/whatsapp/credentials. Add pin if the number has two-step verification turned on.
curl -X POST https://api.pozy.ai/v1/connect/whatsapp/credentials \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "profileId": "6710c4e2b9a1f03d8e5c7a21",
    "accessToken": "EAAG...system-user-token",
    "wabaId": "204567890123456",
    "phoneNumberId": "109876543210987",
    "pin": "205718"
  }'

Pozy checks the token with Meta, creates the account, subscribes the WABA to message events and registers the number. If phoneNumberId is not in that WABA, the 400 lists the numbers that are.

Existing webhooks on the WABA stop

Connecting routes the WABA's events to Pozy. Any callback URL you had set on that WABA stops receiving events right away. Do not unsubscribe your Meta app from the WABA afterwards, or Pozy stops receiving messages too and you have to connect again.

#Set the business profile

The business profile is what customers see when they open your chat. Update only the fields you send.

curl -X POST https://api.pozy.ai/v1/whatsapp/business-profile \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "6712a9d4c0e3b58f1a7d2e64",
    "about": "Fresh bread, baked every morning",
    "description": "Neighbourhood bakery in Lisbon. Order by 6pm for next-day pickup.",
    "email": "hello@example.com",
    "websites": ["https://example.com"]
  }'
Field Limit
about 139 characters
description 512 characters
websites 2 URLs
vertical One of Meta's business categories

The profile photo, display name and WhatsApp username have their own endpoints:

#Watch quality and limits

Meta rates every number on how recipients react to its messages. A falling rating can lower the messaging limit or get templates paused.

GET /v1/whatsapp/number-info reads the live state from Meta:

Field Values
phone.quality_rating GREEN, YELLOW, RED or UNKNOWN
phone.messaging_limit_tier TIER_250 for a new number, then TIER_2K, TIER_10K, TIER_100K, TIER_UNLIMITED
phone.name_status Display name approval state
phone.status Meta's connection status, for example CONNECTED
waba.business_verification_status Whether Meta has verified the business behind the WABA

You do not have to poll. Pozy sends whatsapp.account.quality_updated when the rating or the tier changes, with both the old and the new value, and whatsapp.account.status_updated when Meta restricts or reinstates the WABA. A restriction lists what was blocked (for example RESTRICTED_BIZ_INITIATED_MESSAGING) and when it lifts.

Business verification happens in Meta Business Manager, not through the API. Some features, such as conversion tracking for Click-to-WhatsApp ads, need a verified business. Read waba.business_verification_status before you turn them on.

Phone numbers for WhatsApp explains how to tell a dead channel from a healthy one.

#Ice breakers and slash commands

Give people something to tap when they open the chat. POST /v1/whatsapp/conversational-automation sets:

  • up to 3 ice breaker prompts, 80 characters each
  • up to 30 slash commands (command_name up to 30 characters, command_description up to 256)
  • enable_welcome_message, which lets Meta greet first-time visitors

A tapped prompt arrives as an ordinary message.received with the prompt text, so a keyword workflow can answer it.

#Measure Click-to-WhatsApp ads

When a conversation starts from a Click-to-WhatsApp ad, Meta attaches a click id to the first message. Pozy stores it on the conversation so you can report results back to Meta and see which ad paid off.

  1. Create the dataset once per WABA with POST /v1/whatsapp/dataset. The call is safe to repeat.
  2. When something happens in the chat, send it with POST /v1/whatsapp/conversions: eventName (LeadSubmitted, QualifiedLead, Purchase, AddToCart, InitiateCheckout, ViewContent, OrderCreated, OrderCanceled or OrderReturned), a stable eventId and the conversationId.

Meta attributes events for 7 days after the click. Create the ads themselves from Meta Ads.

#Endpoints

Endpoint What it does
GET /v1/connect/{platform} Get OAuth connect URL
GET /v1/connect/whatsapp/select-phone-number List numbers for selection
POST /v1/connect/whatsapp/select-phone-number Complete number selection
POST /v1/connect/whatsapp/credentials Connect WhatsApp via credentials
POST /v1/connect/whatsapp/embedded-signup Connect WhatsApp from Embedded Signup
GET /v1/connect/whatsapp/sdk-config Get Embedded Signup SDK config
GET /v1/whatsapp/business-profile Get business profile
POST /v1/whatsapp/business-profile Update business profile
POST /v1/whatsapp/business-profile/photo Upload profile picture
GET /v1/whatsapp/business-profile/display-name Get display name status
POST /v1/whatsapp/business-profile/display-name Request display name change
GET /v1/whatsapp/business-profile/username Get business username
POST /v1/whatsapp/business-profile/username Set business username
DELETE /v1/whatsapp/business-profile/username Delete business username
GET /v1/whatsapp/business-profile/username/suggestions Get username suggestions
GET /v1/whatsapp/number-info Get number status
GET /v1/whatsapp/conversational-automation Get ice breakers and commands
POST /v1/whatsapp/conversational-automation Set ice breakers and commands
DELETE /v1/whatsapp/conversational-automation Clear ice breakers and commands
GET /v1/whatsapp/block-users List blocked users
GET /v1/whatsapp/block-users/status Check if a user is blocked
POST /v1/whatsapp/block-users Block users
DELETE /v1/whatsapp/block-users Unblock users
GET /v1/whatsapp/account-events List account notifications
GET /v1/whatsapp/dataset Get CTWA conversions dataset
POST /v1/whatsapp/dataset Provision CTWA dataset
GET /v1/whatsapp/conversions List conversion events
POST /v1/whatsapp/conversions Send WhatsApp conversion event

#Webhook events

Event When it fires
account.connected Account connected.
account.disconnected Account disconnected.
whatsapp.account.quality_updated WhatsApp quality rating or messaging limit changed.
whatsapp.account.status_updated WhatsApp Business Account restricted or reinstated.
whatsapp.account.alert_received WhatsApp account alert received.
whatsapp.contact.identity_changed WhatsApp contact identity changed.
whatsapp.account.name_status_updated WhatsApp display-name review outcome.
whatsapp.automatic_event WhatsApp automatic event detected.