Messages
Every request sends x-api-key. New here? Start with the
quickstart, or read API keys.
| Operation | SDK call | Endpoint |
|---|---|---|
| Send a message | messages.send | POST /v1/messages/ |
| Get a message | messages.get | GET /v1/messages/{id} |
Send a message
Send a WhatsApp message to a phone number. A template message may be sent at any time; text and media only within 24 hours of the recipient's last inbound message, which is WhatsApp's rule rather than ours. The sender is the number this key was issued against. Pass variables to fill a template's placeholders for this send. A test key runs the whole path without delivering anything and returns testMode: true.
Text
Template
Media
Body
| Field | Type | Required | Description |
|---|---|---|---|
to | string | yes | The recipient's phone number in E.164 format. |
type | template | text | media | yes | text only works inside the 24-hour window. template works any time but must be approved by Meta. media sends a file you uploaded first. |
text | string | no | The message body. Required when type is text. |
templateId | string | no | From GET /v1/templates. Required when type is template. |
variables | object | no | Template placeholder values, keyed by name or index. Omit one and the template's own example value is sent instead. Template messages only. |
mediaId | string | no | From POST /v1/media/. Required when type is media. |
caption | string | no | Text shown with the file. Media messages only. |
replyTo | string | no | A msg_ id or a WhatsApp id to quote, threading this as a reply. |
Response 201
{
"id": "msg_7726793e1a4b4c8d9e0f1a2b3c4d5e6f",
"status": "accepted",
"type": "template"
}| Field | Type | Description |
|---|---|---|
id | string | Pass this to GET /v1/messages/\{id\} for delivery status. |
status | accepted | sent | delivered | read | failed | accepted means we have it, not that it arrived. It moves to sent, delivered and read as WhatsApp reports back, or to failed. |
to | string | The recipient, echoed back. |
type | template | text | media | The kind of message that was sent. |
whatsappMessageId | string | Meta's own id, for correlating in WhatsApp Manager. Null on a test key. |
error | object | Null unless status is failed. |
error.code | string | Meta's error code. |
error.message | string | Meta's reason for the failure. |
createdAt | string (ISO 8601) | When we accepted the message. |
testMode | true | Present and true on a test key. Nothing reached WhatsApp. |
Errors
Returns 400, 401, 403, 404, 409, 429, 502, 503. Every one carries the standard envelope — branch on code, not the status. See Errors.
Get a message
Fetch a message's delivery status. accepted means we hold it and Meta has not confirmed yet; sent, delivered and read track WhatsApp's own receipts; failed carries the reason in error. Covers any message in the account, including ones sent from the dashboard.
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | The msg_ id returned by POST /v1/messages. |
Response 200
{
"id": "msg_7726793e1a4b4c8d9e0f1a2b3c4d5e6f",
"status": "accepted",
"type": "template"
}| Field | Type | Description |
|---|---|---|
id | string | Pass this to GET /v1/messages/\{id\} for delivery status. |
status | accepted | sent | delivered | read | failed | accepted means we have it, not that it arrived. It moves to sent, delivered and read as WhatsApp reports back, or to failed. |
to | string | The recipient, echoed back. |
type | template | text | media | The kind of message that was sent. |
whatsappMessageId | string | Meta's own id, for correlating in WhatsApp Manager. Null on a test key. |
error | object | Null unless status is failed. |
error.code | string | Meta's error code. |
error.message | string | Meta's reason for the failure. |
createdAt | string (ISO 8601) | When we accepted the message. |
testMode | true | Present and true on a test key. Nothing reached WhatsApp. |
Errors
Returns 400, 401, 403, 404, 429, 503. Every one carries the standard envelope — branch on code, not the status. See Errors.