Messages
Send approved templates (the only thing that works outside the 24-hour window), reply with text inside it, and check what happened to a message.
Paths are relative to https://api.chatboxai.dev/api, so /v1/messages/template means https://api.chatboxai.dev/api/v1/messages/template. Every request needs an API key, see Authentication.
Send a template
/v1/messages/templatemessages:sendIdempotentSend an approved template. This is the one that works outside the 24-hour window, so it is what an order-confirmation, shipping or delivery integration actually uses.
POST /api/v1/messages/template
X-Api-Key: cbk_live_7mK2pQx9Lw4t....
Idempotency-Key: shopify-order-1234-shipped
Content-Type: application/json
{
"to": "+919999900000",
"name": "Asha Menon",
"template": "order_shipped",
"language": "en",
"reference": "shopify:order:4521:shipped",
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Asha" },
{ "type": "text", "text": "#1234" },
{ "type": "text", "text": "Friday" }
]
}
]
}| Field | Required | Notes |
|---|---|---|
to | one of | The customer's phone. Spaces, dashes and parentheses are stripped. Include the country code. |
contactId | one of | Our id, if you already have it. Use instead of to. |
name | no | Used only if to is somebody we have never seen, to name the new contact. |
template | yes | The template name as approved, not its id. |
language | no | Defaults to the template's own language. |
components | no | Meta's send-time components, passed through unchanged. Omit it and the template is filled in with the contact's name where it has a single {{1}}. |
reference | no | Your identifier for this message, up to 128 characters. Stored as sent and handed back on every webhook about it, and on the customer's reply to it. See matching an event to your own records. |
Response:
{
"id": "clx9m4p2t0003",
"waMessageId": "wamid.HBgMOTE5OTk5OTAwMDAwFQIAERgSN0E4...",
"conversationId": "clx7k1m8n0002",
"contactId": "clx8h2k9p0001",
"direction": "OUTBOUND",
"type": "TEMPLATE",
"text": "Your order has shipped",
"mediaUrl": null,
"status": "SENT",
"error": null,
"reference": "shopify:order:4521:shipped",
"createdAt": "2026-10-17T10:14:02.441Z"
}status: "SENT" means WhatsApp accepted it. It does not mean it was delivered. Subscribe to message.delivered and message.failed, or poll GET /v1/messages/{id}.
If the contact does not exist, it is created. If they have opted out, you get 422 contact_opted_out and nothing is sent or charged.
Send a text message
/v1/messages/textmessages:sendIdempotentSend a plain text message. Only works within 24 hours of the customer's last message to the business. Use it to answer someone, not to start a conversation.
POST /api/v1/messages/text
Content-Type: application/json
{
"to": "+919999900000",
"text": "It's out for delivery and should reach you by 6pm.",
"reference": "shopify:order:4521:eta"
}reference works exactly as it does on a template send, and is optional in the same way. The response has the same shape as above. Outside the window you get:
{
"error": {
"code": "session_window_closed",
"message": "WhatsApp only allows a plain text message within 24 hours of the customer writing to you. Send an approved template instead.",
"details": { "contactId": "clx8h2k9p0001", "sessionExpiresAt": "2026-10-16T14:22:00.000Z" }
}
}Get a message
/v1/messages/{id}messages:readWhat happened to a message. {id} may be either the id we returned or the waMessageId, whichever you stored.
{
"id": "clx9m4p2t0003",
"waMessageId": "wamid.HBgMOTE5OTk5OTAwMDAwFQIAERgSN0E4...",
"conversationId": "clx7k1m8n0002",
"contactId": "clx8h2k9p0001",
"direction": "OUTBOUND",
"type": "TEMPLATE",
"text": "Your order has shipped",
"mediaUrl": null,
"status": "FAILED",
"error": { "code": 131049, "title": "This message was not delivered to maintain healthy ecosystem engagement." },
"reference": "shopify:order:4521:shipped",
"createdAt": "2026-10-17T10:14:02.441Z"
}status is one of QUEUED, SENT, DELIVERED, READ, FAILED. reference is whatever you sent with the message, or null, including for every message sent from the dashboard rather than through this API.
Error 131049 is Meta throttling a marketing template, not a bug in your integration. See marketing delivery is not guaranteed.