Skip to main content

POST /v1/messages

Send one WhatsApp message. Delivery is asynchronous: a 202 means it is queued, not delivered.

Scope: messages:send

Headers​

HeaderRequiredNotes
AuthorizationyesBearer wsk_…
Content-Typeyesapplication/json
Idempotency-KeyyesAny unique string per logical message (UUID recommended)

Body​

FieldTypeRequiredNotes
tostringyesDigits with country code, 8–15 digits. + and spaces are stripped.
categorystringyesutility, marketing or authentication
number_idstringnoSend from a specific number. Defaults to the workspace's active number.
templateobjectconditionalRequired for template messages
template.namestringyesTemplate name, lowercase
template.languagestringyese.g. en, en_US, hi
template.componentsarraynoBody parameters for {{1}}, {{2}} …
textstringconditionalFree-form text. Only inside a 24-hour service window.

Template parameters​

{
"type": "body",
"parameters": [
{ "type": "text", "text": "Ravi" },
{ "type": "text", "text": "A-102" }
]
}

Parameters map positionally to {{1}}, {{2}} … in the approved template body.

Example​

curl -X POST https://api.msgpanda.com/v1/messages \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6b1f0b7e-2f2b-4a58-9b0e-9a1d2c3e4f50" \
-d '{
"to": "919811100010",
"category": "utility",
"template": {
"name": "order_update",
"language": "en",
"components": [{ "type": "body", "parameters": [
{ "type": "text", "text": "Ravi" },
{ "type": "text", "text": "A-102" }
]}]
}
}'
{ "id": "ea62acf4-2973-4fec-884a-ddab50214a48", "status": "queued" }

Responses​

StatusBodyMeaning
202{ id, status }Queued for sending
200{ id, status, idempotent_replay: true }You retried with a key we already saw; the original message is returned
400idempotency_key_requiredMissing header
400validation_failedBad phone, unknown category, missing template
403scope_not_permitted / number_not_allowedKey lacks the scope, or is not bound to that number
409number_not_activeThe sending number is paused
409template_not_approvedTemplate is not approved by Meta

Idempotency semantics​

  • Scope is your workspace.
  • A second request with the same Idempotency-Key returns the original message and its current status.
  • Two different payloads with the same key return the original message — the payload is not compared.
  • Keys never expire automatically; use a deterministic UUID per logical message.

What status means​

StatusMeaning
queuedAccepted, waiting for the worker
sendingIn flight to Meta
sentMeta accepted it (a wamid exists)
deliveredReached the recipient's device
readThe recipient opened it
failedPermanently failed; see error on the message