Messages
Send any message type Meta supports. The body is Meta's /messages body plus from.
Send any message type Meta supports. The body is Meta's /messages body plus from.
Base URL https://api.whabuzz.com. Every request needs Authorization: Bearer <key> unless the operation says otherwise; see Authentication. Errors follow the two-source contract.
Operations on this page:
POST /v1/messages: Send a messagePOST /v1/messages/read: Mark an inbound message read, optionally showing a typing indicatorPOST /v1/messages/batch: Send many messages from one numberGET /v1/messages/batch/{batch_id}: Batch progressGET /v1/messages/batch/{batch_id}/items: Batch items with Meta's response for eachPOST /v1/messages/batch/{batch_id}/cancel: Cancel the unsent part of a batch
#Send a message
POST/v1/messages
The body is Meta's POST /{phone_number_id}/messages body plus from (your number's phone_number_id or E.164). WhaBuzz adds nothing and checks nothing about content, category or the customer-service window. Meta decides; its answer comes back verbatim.
Auth: API key (tenant key, or app key with X-WhaBuzz-Tenant). Operation id: sendMessage.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | no | Repeat a send safely for 24 hours. Same key + same body returns the stored response; a different body returns 422. |
Request body (application/json, required)
| Field | Type | Required | Description |
|---|---|---|---|
from | string | yes | phone_number_id or E.164 of one of your numbers |
messaging_product | string | no | Default "whatsapp". |
to | string | yes | |
type | string | yes |
Request example, Text:
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "16505551234",
"type": "text",
"text": {
"preview_url": false,
"body": "Your trial is booked for 7:00 AM tomorrow."
}
}jsonRequest example, Template with body parameters:
{
"from": "+14692311132",
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "template",
"template": {
"name": "renewal_reminder",
"language": {
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Kerry"
},
{
"type": "text",
"text": "31 Oct"
}
]
}
]
}
}jsonRequest example, Authentication template (you send the copy-code button yourself):
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "template",
"template": {
"name": "login_code",
"language": {
"code": "en_US"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "482913"
}
]
},
{
"type": "button",
"sub_type": "url",
"index": "0",
"parameters": [
{
"type": "text",
"text": "482913"
}
]
}
]
}
}jsonRequest example, Image by media id:
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "image",
"image": {
"id": "1479537139650973",
"caption": "This week's timetable"
}
}jsonRequest example, Document by link:
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "document",
"document": {
"link": "https://example.com/invoice-1042.pdf",
"filename": "invoice-1042.pdf"
}
}jsonRequest example, Reply buttons:
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "interactive",
"interactive": {
"type": "button",
"body": {
"text": "Confirm your 7:00 AM session?"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "confirm_yes",
"title": "Yes"
}
},
{
"type": "reply",
"reply": {
"id": "confirm_no",
"title": "Reschedule"
}
}
]
}
}
}jsonRequest example, List:
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "interactive",
"interactive": {
"type": "list",
"body": {
"text": "Pick a slot"
},
"action": {
"button": "Slots",
"sections": [
{
"title": "Tomorrow",
"rows": [
{
"id": "slot_0700",
"title": "7:00 AM",
"description": "Strength"
},
{
"id": "slot_1800",
"title": "6:00 PM",
"description": "Conditioning"
}
]
}
]
}
}
}jsonRequest example, Location:
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "location",
"location": {
"latitude": 17.3953,
"longitude": 78.3363,
"name": "Studio",
"address": "Kokapet, Hyderabad"
}
}jsonRequest example, Reaction:
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "reaction",
"reaction": {
"message_id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEA",
"emoji": "👍"
}
}jsonRequest example, Reply in thread (context):
{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"to": "16505551234",
"context": {
"message_id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEA"
},
"type": "text",
"text": {
"body": "See you at 7."
}
}jsoncURL:
curl -X POST "https://api.whabuzz.com/v1/messages" \
-H "Authorization: Bearer $WHABUZZ_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "1013622581841046",
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "16505551234",
"type": "text",
"text": {
"preview_url": false,
"body": "Your trial is booked for 7:00 AM tomorrow."
}
}'bashResponses
200 Meta accepted the message. Body is Meta's, verbatim.
{
"messaging_product": "whatsapp",
"contacts": [
{
"input": "16505551234",
"wa_id": "16505551234"
}
],
"messages": [
{
"id": "wamid.HBgLMTY1MDU1NTEyMzQVAgARGBI5QTNDQTVCM0Q0Q0Q2RTY3RTcA",
"message_status": "accepted"
}
]
}json400 Meta rejected the request (any Meta 4xx is passed through with its own status), or WhaBuzz rejected the body.
Meta 131030 passed through (HTTP 400):
{
"source": "meta",
"error": {
"message": "(#131030) Recipient phone number not in allowed list",
"type": "OAuthException",
"code": 131030,
"error_data": {
"messaging_product": "whatsapp",
"details": "Recipient phone number not in allowed list: Add recipient phone number to recipient list and try again."
},
"fbtrace_id": "A1b2C3d4E5f6G7h8"
}
}jsonMeta 132000 passed through (HTTP 400):
{
"source": "meta",
"error": {
"message": "(#132000) Number of parameters does not match the expected number of params",
"type": "OAuthException",
"code": 132000,
"error_data": {
"messaging_product": "whatsapp",
"details": "body: number of localizable_params (1) does not match the expected number of params (2)"
},
"fbtrace_id": "B2c3D4e5F6g7H8i9"
}
}jsonwhabuzz_missing_from:
{
"source": "whabuzz",
"error": {
"code": "invalid_request",
"message": "`from` is required: a phone_number_id or E.164 number of this tenant",
"details": null
},
"request_id": "req_01JAB3P5S8V1X4Z7B0D3F6H9K2"
}json409 Number not connected, or the same Idempotency-Key is still in flight.
not_connected:
{
"source": "whabuzz",
"error": {
"code": "number_not_connected",
"message": "Number 1013622581841046 is not connected: no_verified_endpoint",
"details": {
"connection_detail": "no_verified_endpoint"
}
},
"request_id": "req_01JAB3Q6T9W2Y5A8C1E4G7J0M3"
}jsonin_flight:
{
"source": "whabuzz",
"error": {
"code": "idempotency_conflict",
"message": "A request with this Idempotency-Key is still in progress",
"details": null
},
"request_id": "req_01JAB3R7V0X3Z6B9D2F5H8K1N4"
}json422 Idempotency-Key reused with a different body
{
"source": "whabuzz",
"error": {
"code": "idempotency_conflict",
"message": "Idempotency-Key was used with a different body",
"details": null
},
"request_id": "req_01JAB3S8W1Y4A7C0E3G6J9M2P5"
}json429 Meta throttled the send (passed through)
{
"source": "meta",
"error": {
"message": "(#130429) Rate limit hit",
"type": "OAuthException",
"code": 130429,
"error_data": {
"messaging_product": "whatsapp",
"details": "Cloud API message throughput has been reached."
},
"fbtrace_id": "AbCdEf1234567890"
}
}json502 WhaBuzz could not reach Meta. The outcome is unknown; watch for message.status before resending.
{
"source": "whabuzz",
"error": {
"code": "meta_unreachable",
"message": "Meta did not answer within 15000 ms",
"details": {
"timeout_ms": 15000
}
},
"request_id": "req_01JAB49K4P7S0V3Y6B9E2G5J8M"
}jsonCommon errors. Shape and meanings are on the Errors page.
| HTTP | WhaBuzz code | Meaning |
|---|---|---|
| 401 | unauthorized | Missing or invalid credentials |
| 403 | tenant_not_approved, tenant_suspended | Tenant not approved or suspended |
#Mark an inbound message read, optionally showing a typing indicator
POST/v1/messages/read
Auth: API key (tenant key, or app key with X-WhaBuzz-Tenant). Operation id: markRead.
Request body (application/json, required)
| Field | Type | Required | Description |
|---|---|---|---|
from | string | yes | |
message_id | string | yes | |
typing_indicator | object | no | |
typing_indicator.type | text | no |
Request example:
{
"from": "1013622581841046",
"message_id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEA",
"typing_indicator": {
"type": "text"
}
}jsoncURL:
curl -X POST "https://api.whabuzz.com/v1/messages/read" \
-H "Authorization: Bearer $WHABUZZ_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "1013622581841046",
"message_id": "wamid.HBgLMTY1MDU1NTEyMzQVAgASGBQzQUY5QTdGNkU0RTFGMkI3QzFBMDEA",
"typing_indicator": {
"type": "text"
}
}'bashResponses
200 Meta's response verbatim
{
"success": true
}jsonCommon errors. Shape and meanings are on the Errors page.
| HTTP | WhaBuzz code | Meaning |
|---|---|---|
| 400 | 131030 | Meta's error, passed through with Meta's HTTP status |
#Send many messages from one number
POST/v1/messages/batch
Up to 10,000 Meta message bodies. WhaBuzz paces them to the number's throughput and records Meta's answer for each, verbatim. Each item also produces a message.outbound event, and the batch ends with batch.completed. WhaBuzz does not retry items Meta rejected.
Auth: API key (tenant key, or app key with X-WhaBuzz-Tenant). Operation id: createBatch.
Request body (application/json, required)
| Field | Type | Required | Description |
|---|---|---|---|
from | string | yes | |
client_ref | string | no | Your reference. Unique per tenant; a repeat returns the existing batch. |
messages | array of object | yes |
Request example:
{
"from": "1013622581841046",
"client_ref": "renewals-2026-11",
"messages": [
{
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "template",
"template": {
"name": "renewal_reminder",
"language": {
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Kerry"
},
{
"type": "text",
"text": "31 Oct"
}
]
}
]
}
},
{
"messaging_product": "whatsapp",
"to": "16505551235",
"type": "template",
"template": {
"name": "renewal_reminder",
"language": {
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Ravi"
},
{
"type": "text",
"text": "2 Nov"
}
]
}
]
}
}
]
}jsoncURL:
curl -X POST "https://api.whabuzz.com/v1/messages/batch" \
-H "Authorization: Bearer $WHABUZZ_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "1013622581841046",
"client_ref": "renewals-2026-11",
"messages": [
{
"messaging_product": "whatsapp",
"to": "16505551234",
"type": "template",
"template": {
"name": "renewal_reminder",
"language": {
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Kerry"
},
{
"type": "text",
"text": "31 Oct"
}
]
}
]
}
},
{
"messaging_product": "whatsapp",
"to": "16505551235",
"type": "template",
"template": {
"name": "renewal_reminder",
"language": {
"code": "en"
},
"components": [
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Ravi"
},
{
"type": "text",
"text": "2 Nov"
}
]
}
]
}
}
]
}'bashResponses
202 Queued
{
"id": "bat_01JAB3T9X2Z5B8D1F4H7K0M3Q6",
"status": "queued",
"total": 2,
"accepted": 0,
"failed": 0,
"rate_per_sec": 20,
"client_ref": "renewals-2026-11",
"created_at": "2026-10-16T10:00:00Z"
}jsonCommon errors. Shape and meanings are on the Errors page.
| HTTP | WhaBuzz code | Meaning |
|---|---|---|
| 409 | number_not_connected | Number not connected |
#Batch progress
GET/v1/messages/batch/{batch_id}
Auth: API key (tenant key, or app key with X-WhaBuzz-Tenant). Operation id: getBatch.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
batch_id | path | string | yes |
cURL:
curl -X GET "https://api.whabuzz.com/v1/messages/batch/$BATCH_ID" \
-H "Authorization: Bearer $WHABUZZ_KEY"bashResponses
200 Batch
{
"id": "bat_01JAB3T9X2Z5B8D1F4H7K0M3Q6",
"status": "completed",
"total": 2,
"accepted": 1,
"failed": 1,
"started_at": "2026-10-16T10:01:00Z",
"completed_at": "2026-10-16T10:01:01Z"
}json#Batch items with Meta's response for each
GET/v1/messages/batch/{batch_id}/items
Auth: API key (tenant key, or app key with X-WhaBuzz-Tenant). Operation id: listBatchItems.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
batch_id | path | string | yes | |
status | query | pending or accepted or failed or skipped | no | |
limit | query | integer | no | |
cursor | query | string | no | next_cursor from the previous page. |
cURL:
curl -X GET "https://api.whabuzz.com/v1/messages/batch/$BATCH_ID/items" \
-H "Authorization: Bearer $WHABUZZ_KEY"bashResponses
200 Items
{
"data": [
{
"idx": 1,
"status": "failed",
"http_status": 400,
"wamid": null,
"response": {
"error": {
"message": "(#131030) Recipient phone number not in allowed list",
"type": "OAuthException",
"code": 131030,
"error_data": {
"messaging_product": "whatsapp",
"details": "Recipient phone number not in allowed list: Add recipient phone number to recipient list and try again."
},
"fbtrace_id": "A1b2C3d4E5f6G7h8"
}
},
"event_id": "evt_01JAB3V0Y3A6C9E2G5J8M1P4R7",
"sent_at": "2026-10-16T10:01:01Z"
}
],
"next_cursor": null
}json#Cancel the unsent part of a batch
POST/v1/messages/batch/{batch_id}/cancel
Auth: API key (tenant key, or app key with X-WhaBuzz-Tenant). Operation id: cancelBatch.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
batch_id | path | string | yes |
cURL:
curl -X POST "https://api.whabuzz.com/v1/messages/batch/$BATCH_ID/cancel" \
-H "Authorization: Bearer $WHABUZZ_KEY"bashResponses
200 Cancelled
{
"id": "bat_01JAB3T9X2Z5B8D1F4H7K0M3Q6",
"status": "cancelled",
"total": 2000,
"accepted": 640,
"failed": 3
}jsonThis page as Markdown: /api/messages.md. All docs in one file: /llms-full.txt.