WhatsApp Messages API - Send Session Messages
Send free-form WhatsApp text, image, video, audio and document messages inside the 24-hour window by API, and check any WhatsApp message's delivery status.
Overview
The WhatsApp Messages API sends free-form WhatsApp messages (text, images, videos, audio and documents) to a customer who has written to you in the last 24 hours. It is the API version of replying from the Inbox, and the message is saved to the conversation like any agent reply.
Outside the 24-hour window WhatsApp only accepts approved templates. Use the WhatsApp Templates API for those.
Note: The Send Messages API does the same job for every channel, including WhatsApp, using one request shape and built-in safe retries. Use this page's endpoint if you work only with WhatsApp and phone numbers.
Prerequisites
- An API key on a plan with API access (Pro or higher). See ChatMaxima API.
- A WhatsApp account connected through the Cloud API. See WhatsApp channel setup.
- An open conversation. The customer's last message to you must be less than 24 hours old.
Send a session message
Text
curl -X POST https://chatmaxima.com/api/v2/whatsapp/messages/send/ \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"account_id": "a1b2c3d4e5f6",
"mobile_no": "+15550001111",
"reference_id": "ticket-2042",
"message": "Thanks Jane, your refund has been approved."
}'
Image, video, audio or document
Send message as an object instead of a string:
{
"account_id": "a1b2c3d4e5f6",
"mobile_no": "+15550001111",
"reference_id": "invoice-1001",
"message": {
"type": "document",
"media_url": "https://cdn.example.com/invoice-1001.pdf",
"file_name": "invoice-1001.pdf",
"caption": "Your invoice"
}
}
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
mobile_no | string | Yes | Customer's number with country code. |
account_id | string | If you have several numbers | The WhatsApp account to send from, from Channel Accounts. |
reference_id | string | No | Your own id. Required if you want webhooks for this message. |
message | string or object | Yes | A string sends text. An object sends the given type. |
message.type | string | In object form | text, image, video, audio or document. |
message.text or message.caption | string | For text | The text, or the caption for media. |
message.media_url | string | For media | Public https URL of the file. |
message.file_name | string | No | File name shown for documents. |
Response
{
"status": "success",
"code": 201,
"message": "Message sent",
"data": {
"message_id": "wamid.XXXXXXXX",
"mobile_no": "15550001111",
"account_id": "a1b2c3d4e5f6",
"reference_id": "ticket-2042",
"status": "sent",
"created_datetime": "2026-11-03 10:05:00"
}
}
Note: Delivery, read and failure webhooks are only sent for session messages that include a
reference_id. Template sends always trigger them.
The 24-hour window
ChatMaxima checks the window before sending. If the customer has never written to you, or their last message is more than 24 hours old, the request fails with 422 WINDOW_CLOSED:
{
"error": {
"code": "WINDOW_CLOSED",
"message": "The 24-hour customer service window is closed (last inbound message was 31.4 hours ago). Send an approved template to reopen the conversation.",
"details": { "window_open": false, "hours_since_last_inbound": 31.4 }
}
}
Send an approved template with the WhatsApp Templates API instead. When the customer replies, the window opens again for 24 hours.
Check a message status
Look up any WhatsApp message in your workspace by its wamid, whether it was sent by the API, a bot or an agent. URL-encode the id.
curl https://chatmaxima.com/api/v2/whatsapp/messages/wamid.XXXXXXXX/status/ \
-H "Authorization: YOUR_API_KEY"
{
"status": "success",
"code": 200,
"data": {
"message_id": "wamid.XXXXXXXX",
"status": "delivered",
"error": null,
"created_datetime": "2026-11-03 10:05:00",
"updated_datetime": "2026-11-03 10:05:04"
}
}
| Status | Meaning |
|---|---|
sent | WhatsApp accepted the message. |
delivered | It reached the customer's phone. |
read | The customer opened it. Played voice notes also count as read. |
failed | WhatsApp could not deliver it. error contains Meta's report. |
Status only moves forward. A late delivered update never overwrites read. Times are in UTC.
Errors
| HTTP | Code | When it happens |
|---|---|---|
| 422 | MISSING_MOBILE_NO | mobile_no is missing. |
| 422 | INVALID_MOBILE_NO | The number is not 7 to 15 digits after cleaning. |
| 422 | UNSUPPORTED_MESSAGE_TYPE | message.type is not one of the supported types. |
| 422 | MISSING_MESSAGE | The text is empty. |
| 422 | MISSING_MEDIA_URL | A media type was sent without media_url. |
| 422 | INVALID_MEDIA_URL | media_url is not an https URL. |
| 403 | PLAN_EXPIRED | Your plan has ended. |
| 403 | MESSAGE_LIMIT_REACHED | Your monthly message allowance is used up. |
| 422 | ACCOUNT_RESOLUTION_FAILED | account_id is not one of your WhatsApp accounts, none is connected, or you have several and did not pass one. |
| 422 | WINDOW_CLOSED | The 24-hour window is closed or was never opened. |
| 422 | WHATSAPP_SEND_REJECTED | Meta rejected the message. details carries Meta's error. |
| 502 | SEND_UNCONFIRMED | ChatMaxima could not confirm the send. Check the status before retrying. |
| 404 | NOT_FOUND | Status lookup: no message with that wamid in your workspace. |
Authentication, plan and rate-limit errors are listed on the API overview.
Best Practices
- Always send
reference_idif you rely on webhooks for delivery tracking. - Check the window first in your own logic if you know when the customer last wrote, to avoid failed calls.
- Prefer webhooks over polling the status endpoint for high volumes.