Connect a number through Meta's WhatsApp Business Platform — your verified business name, message templates, no QR code to keep alive — and send on it, or on your QR-code number, through one endpoint. Sozuri picks the right number for every message.

POST https://sozuri.net/api/v1/whatsapp/messages

Connect an official number

In the dashboard open Project → WhatsApp → Official WhatsApp (Meta) and press Connect with Meta. Meta's own sign-in window opens: log in with Facebook, choose or create your business portfolio and WhatsApp Business Account, and verify the phone number by SMS or voice call. Sozuri finishes the setup and the number appears on the page, ready to send.

You need admin access to the business portfolio, and a payment method on the WhatsApp Business Account — Meta bills its own fees to you directly (see Pricing).

Keep using the WhatsApp Business app

A number already on the WhatsApp Business app can join the official platform without leaving the app: you keep chatting from your phone, and Sozuri sends from the same number. Press Connect my WhatsApp Business app number, choose to connect your existing app account in Meta's window, then follow Settings → Account → Business Platform in the app.

  • You need WhatsApp Business app 2.24.17 or later.
  • Your contacts and the last six months of 1:1 chats can be brought across — only in the first 24 hours, and only once. Sozuri asks for them the moment you connect; chats you imported appear in your inbox but never trigger an automation or your webhook.
  • Messages you send from the app are free at Meta and are never charged by Sozuri. A reply you type on your phone pauses the AI agent for that conversation, exactly like a reply from the inbox.
  • Such a number sends at most 20 messages a second. Group chats are not synchronised, and broadcast lists in the app become read-only.
  • A number on the official platform can't also be linked on the QR-code channel — Sozuri ignores the QR copy of every message, so nothing is answered twice.

The 24-hour window and templates

On the official channel you may send any message to a customer who has written to that number in the last 24 hours. Outside that window only an approved template can be sent — it is how a conversation is started or restarted. Create templates under Official WhatsApp → Templates (or with the API); Meta reviews each one. A free-form send outside the window is refused before it reaches Meta, with the time the window closed.

Send a message

POST /api/v1/whatsapp/messages works for both WhatsApp channels. It accepts the official channel's typed shape, and the exact body of /v1/whatsapp/send — an integration written for the QR channel works unchanged.

FieldRequiredTypeDescription
projectYesStringThe project name that owns the API key.
toYesStringInternational format, country code first, no + or leading 0 (254700000000). A QR-channel JID (...@s.whatsapp.net, ...@g.us) or an official-channel user id (KE.1234...) also works — each exists on one channel only.
typeFor the typed shapeStringtext, image, video, audio, document, sticker, location, interactive, reaction or template, plus an object of the same name: "text": {"body": "…"} (or just "text": "…"), "image": {"link": "https://…", "caption": "…"}, "template": {"name": "order_ready", "language": "en", "params": {"body": ["Amina"]}}.
text, imageUrl, …For the QR shape—The /v1/whatsapp/send fields: text plus at most one media, location or contact field.
channelNoStringqr or meta to choose the channel yourself.
fromNoStringOne of your numbers, when you have several — it also decides the channel.
replyToNoStringThe id of the message you are answering (official channel).
A template (starts a conversation)
curl -X POST https://sozuri.net/api/v1/whatsapp/messages \
  -H "Authorization: Bearer $SOZURI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "project": "your_project_name", "to": "254700000000", "type": "template",
        "template": { "name": "order_ready", "language": "en", "params": { "body": ["Amina", "A-1042"] } } }'
A reply (inside the 24-hour window)
curl -X POST https://sozuri.net/api/v1/whatsapp/messages \
  -H "Authorization: Bearer $SOZURI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "project": "your_project_name", "to": "254700000000", "text": "Your order is on its way" }'

Which number a message leaves from

With both channels connected, the first rule that applies decides:

  1. channel or from, when you send them.
  2. An address that exists on one channel only (a JID on QR, a user id on the official channel).
  3. A template → the official channel, the only one with templates.
  4. A reply → the number the customer last wrote to in the past 24 hours. Automated answers (the AI agent, keyword rules, workflows) always leave from the number the message arrived on.
  5. Your project's default, set on the Official WhatsApp page.
  6. Otherwise the QR channel — a free-form message to somebody who has not written would be refused on the official one.

The response says which channel carried the message and why (channel, routed).

Response

{
  "status": "accepted",
  "channel": "meta",
  "routed": "template",
  "message": {
    "id": "wamid.HBgLMjU0NzAw...",
    "to": "254700000000",
    "from": "254711000000",
    "type": "template",
    "status": "pending"
  }
}

message.id is the key delivery and read receipts arrive under. On the official channel an accepted message is pending: sent, delivered and read follow as Meta reports them.

List your channels

GET /api/v1/whatsapp/channels?project=your_project_name returns what the project has:

{
  "default": null,
  "channels": [
    { "channel": "qr", "available": true, "status": "connected", "number": "254700000001" },
    { "channel": "meta", "available": true, "numbers": [
        { "number": "254711000000", "phoneNumberId": "1098...", "verifiedName": "Duka Bora", "connected": true,
          "quality": "GREEN", "coexistence": false } ] }
  ]
}

Templates

GET /api/v1/whatsapp/templates lists your templates and their review status; POST /api/v1/whatsapp/templates submits one for Meta's review (name, language, category of marketing, utility or authentication, and its body). Only an APPROVED template can be sent.

Receiving messages

Set Your webhook for this number on the Official WhatsApp page. Every message the number receives is POSTed to it — the same envelope as the QR channel, plus the fields only this channel has:

{
  "event": "message.received",
  "channel": "meta",
  "from": "254722000000",
  "to": "254711000000",
  "chatId": "254722000000",
  "profileName": "Amina",
  "message": { "id": "wamid.HBgL...", "type": "text", "text": "Is my order ready?", "fromMe": false },
  "timestamp": "2026-09-27T09:06:40+00:00"
}

to is which of your numbers was written to. A customer who uses a WhatsApp username may arrive with fromUserId (e.g. KE.1234…) — reply to from through this API and it reaches them either way. Media arrives with a media object once Sozuri holds a copy of the file (its url), and a reply carries message.replyTo. Requests are signed exactly like every Sozuri callback — X-Sozuri-Signature, secret under Manage API → Callback URLs → Webhook security.

Delivery & read receipts

Receipts always update the dashboard and the inbox. With status callbacks enabled (ask support), they are also POSTed to the number's webhook, once per status:

{
  "event": "message.status",
  "channel": "meta",
  "messageId": "wamid.HBgL...",
  "status": "delivered",
  "to": "254722000000",
  "from": "254711000000",
  "timestamp": "2026-09-27T09:07:02+00:00"
}

A failed message carries reason, in words, e.g. undeliverable.

Rate limits

Each channel keeps its own per-project limit, and /v1/whatsapp/messages draws on the same allowance as the channel-specific endpoint: a message routed to QR counts against the QR channel's (deliberately small) limit, one routed to the official channel against the official one. Separately, Meta lets a number send 80 messages a second — 20 for a number shared with the WhatsApp Business app — and a burst beyond that is answered 429 throughput_exceeded before it reaches Meta. Both are safe to retry.

Pricing

Meta bills its fee to your WhatsApp Business Account's payment method, per delivered message, by category: marketing, utility and authentication templates, and — from 1 October 2026 — service replies (each number has 1,000 free service messages a month) and utility templates sent inside the 24-hour window. Messages inside a free entry point window (a customer who reached you from a click-to-WhatsApp ad) are free for 72 hours. Sozuri's own per-message fee is taken from your project balance when Meta reports the message delivered, at the rate for the category Meta reports; nothing is charged for a message that was not delivered.

Error responses

Errors are { "error": { "code", "message", "status", "channel"? } }:

StatusCodeWhat to do
409not_connected, channel_unavailableThe channel you need is not connected on this project.
422window_closedSend an approved template; error.window says when the window closed.
422template_not_found, template_not_approved, template_parametersCheck the template's name, language and values.
422unsupported_on_qr, unsupported_on_metaThat kind of message exists on the other channel only.
422address_not_on_channelThe channel or from you named cannot reach that address: a …@s.whatsapp.net, @lid or @g.us address exists only on the QR channel, a user id (KE.…) only on the official one. Leave both out and the address decides.
422from_requiredThe project has several official numbers: say which in from.
402insufficient_balanceTop up the project.
429rate_limited, RATE_LIMITED, throughput_exceededSlow down and retry.
503channel_off, channel_reconnectingTemporary — retry shortly.