WhatsApp Templates API - List and Send Templates
List your approved WhatsApp message templates and send them by API with body variables, media headers and buttons, to start or reopen a WhatsApp conversation.
Overview
The WhatsApp Templates API lets you send approved WhatsApp template messages from your own system: order confirmations, appointment reminders, payment links and any other message that has to reach a customer outside the 24-hour window. It uses the WhatsApp Business Platform (Cloud API) account connected to your ChatMaxima workspace.
Templates are the only way to start a WhatsApp conversation, or to message someone whose last message to you is more than 24 hours old. Inside the window you can send free-form messages with the WhatsApp Messages API or the Send Messages API.
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.
- At least one template approved by Meta. Create and submit templates in ChatMaxima first.
Note: If your workspace has more than one WhatsApp number, pass
account_idon every request. Get it from Channel Accounts with?platform=WhatsApp.
List templates
curl -G https://chatmaxima.com/api/v2/whatsapp/templates/ \
-H "Authorization: YOUR_API_KEY" \
--data-urlencode "account_id=a1b2c3d4e5f6"
| Query parameter | Required | Description |
|---|---|---|
account_id | No | Only return templates of this WhatsApp account. |
template | No | Return one template by its template_id. |
{
"status": "success",
"code": 200,
"data": [
{
"template_id": "tplalias123",
"template_name": "order_update",
"language": "en_US",
"language_name": "English (US)",
"template_type": "UTILITY",
"template_status": "approved",
"account_id": "a1b2c3d4e5f6",
"variables": {
"body": ["body_1", "body_2"],
"body_named": false,
"header_media": true,
"header_media_type": "image",
"header_text": false,
"buttons": [{ "index": 0, "sub_type": "url", "label": "Track order" }]
}
}
],
"meta": { "total": 1 }
}
The list includes every active template, so check template_status and only send templates that are approved. The variables object tells you exactly which fields a send needs, as described below.
Send a template
curl -X POST https://chatmaxima.com/api/v2/whatsapp/templates/send/ \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"account_id": "a1b2c3d4e5f6",
"mobile_no": "+15550001111",
"reference_id": "order-1001",
"template": {
"template_name": "order_update",
"body_1": "Jane",
"body_2": "#1001",
"header_media": "https://cdn.example.com/order-1001.jpg",
"button_url_0": "1001"
}
}'
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
mobile_no | string | Yes | Recipient's number with country code. +, spaces and dashes are removed. |
account_id | string | If you have several numbers | The WhatsApp account to send from. |
reference_id | string | No | Your own id. Returned in the response and in every webhook for this message. |
broadcast_name | string | No | Groups API sends under one broadcast name for reporting in ChatMaxima. |
template.template_name | string | Yes | The template's exact name. |
template.body_1, body_2, ... | string | Per template | Values for numbered body variables {{1}}, {{2}}. |
template.<name> | string | Per template | Values for named body variables, using the variable name as the key. |
template.header_text | string | If the text header has a variable | Value for the header variable. |
template.header_media | string | If the header is an image, video or document | Public https URL of the media. |
template.header_media_filename | string | No | File name shown for a document header. |
template.button_url_N | string | For each dynamic URL button | The variable part of the button link, for the button at index N. |
template.copy_code | string | If the template has a copy-code button | The code to copy, for example a coupon. |
Mapping variables
Read the template's variables object from the list call and fill the matching fields:
variables says | Send |
|---|---|
body: ["body_1", "body_2"], body_named: false | template.body_1, template.body_2 |
body: ["name", "order_id"], body_named: true | template.name, template.order_id |
header_text: true | template.header_text |
header_media: true | template.header_media (and the type in header_media_type) |
a button with sub_type: "url" at index: 0 | template.button_url_0 |
a button with sub_type: "copy_code" | template.copy_code |
Quick-reply buttons need no value. Fill every body variable: an empty value is sent as blank text and Meta usually rejects the message.
Response
{
"status": "success",
"code": 201,
"message": "Template message sent",
"data": {
"message_id": "wamid.XXXXXXXX",
"mobile_no": "15550001111",
"account_id": "a1b2c3d4e5f6",
"template_name": "order_update",
"broadcast_name": null,
"reference_id": "order-1001",
"status": "sent",
"created_datetime": "2026-11-03 10:00:00"
}
}
message_id is the WhatsApp message id (wamid). Use it with the message status endpoint, or match it against webhook events. created_datetime is in UTC.
How the template is chosen
ChatMaxima finds the template by name on the WhatsApp account you send from, and uses the newest approved version of it. The message goes out in that version's language. If you keep one template name in several languages, give each language its own template name so you control which one is sent.
If the number has never messaged you before, ChatMaxima adds it as a new contact, and the message appears in your Inbox like any other.
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 | MISSING_TEMPLATE_NAME | template.template_name is missing. |
| 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. |
| 404 | TEMPLATE_NOT_FOUND | No template with that name on the account. |
| 422 | TEMPLATE_BUILD_FAILED | A required header_media, button_url_N or copy_code value is missing. |
| 409 | CONTACT_NUMBER_CHANGED | The number belongs to a contact whose number was later changed in ChatMaxima. |
| 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. |
Authentication, plan and rate-limit errors are listed on the API overview.
Best Practices
- Set
reference_idto your order or event id so every delivery and reply webhook can be matched to your record. - Fill every variable shown in
variables. Meta rejects templates with blank parameters. - Use a fresh, public
httpsURL for media headers. WhatsApp downloads the file when it sends the message. - Stay within your WhatsApp messaging limit. Meta caps how many new conversations a number can open each day.
Troubleshooting
WHATSAPP_SEND_REJECTED with a parameter error
A body or header variable is missing or empty. Compare your fields with the template's variables from the list call.
The message sent but was never delivered
Subscribe to failed events with WhatsApp Webhooks. Meta reports some problems, such as an unreachable number, only after the send.