POSThttps://wabapi.com/api/v1/messages/template
Sends one approved template to one number. The call is synchronous up to the point our messaging platform accepts the message; delivery to the handset is reported afterwards and can be read from the status endpoint.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| to | string | yes | Recipient's Indian mobile number, digits only, with the country code: 917021948630. A leading + or 0091 is accepted and normalised. |
| template_name | string | yes | The template's name exactly as it appears in the app. |
| template_language | string | no | The template's language code, for example en or hi. Defaults to en. |
| components | array | no | The template's variable values, in Meta's send-template components format. Required when the template has variables; omit it for a template with none. |
Components
components uses the same structure as Meta's Cloud API, so a payload written for Meta — or for WhatsbizAPI — works unchanged. Three component types are supported:
| Field | Type | Required | Description |
|---|---|---|---|
| body | component | no | parameters is a list of { type: "text", text } in variable order. The count must equal the number of variables in the template body — {{1}}, {{2}}, and so on. |
| header | component | no | One { type: "image", image: { link } }, { type: "video", video: { link } } or { type: "document", document: { link, filename } } to replace the media the template was approved with. Only valid for a template that has that kind of media header. For a document template the filename is what the recipient sees on the attachment; omit it and the file name from the URL is used. |
| button | component | no | sub_type "url", an index, and one text parameter: the dynamic suffix for a URL button whose template URL ends in {{1}}. Only valid for that kind of button. |
Example
curl -X POST https://wabapi.com/api/v1/messages/template \
-H "Authorization: Bearer wab_live_0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-d '{"to":"917021948630","template_name":"ticket_confirmation","template_language":"en","components":[{"type":"body","parameters":[{"type":"text","text":"Prajesh"},{"type":"text","text":"Thane"},{"type":"text","text":"04:00 PM"}]}]}'{
"id": "msg_3f9c2b1e7a4d4c0e9b2a1f6d",
"status": "SENT",
"to": "917021948630",
"template_name": "ticket_confirmation",
"credits": 1
}Keep the id. It is what you pass to the status endpoint, and it is the reference on your credit ledger.
Idempotency
Send an Idempotency-Key header (any string up to 128 characters, unique per message on your side, such as your ticket id) and a retried request with the same key returns the original result instead of sending twice or charging twice. Strongly recommended for anything that retries on timeout.
Idempotency-Key: ticket-48213-confirmationErrors
| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_request | The body is not valid JSON or fails the schema. |
| 401 | invalid_api_key | The Authorization header is missing, malformed, unknown or revoked. |
| 422 | invalid_phone | `to` is not a valid Indian mobile number. |
| 404 | template_not_found | No template with that name and language exists on this account. |
| 409 | template_not_approved | The template exists but Meta has not approved it yet, or rejected it. |
| 409 | unsupported_template | Carousel templates cannot be sent through the API yet. |
| 409 | number_not_connected | The account's WhatsApp number is not connected and live. |
| 422 | variable_count_mismatch | The number of body parameters does not match the template's variables. |
| 422 | unsupported_component | A component was supplied that this template does not have, or of a type the API does not support. |
| 429 | rate_limited | Too many sends on this key in the last minute. Retry after the `Retry-After` seconds. |
| 402 | insufficient_credits | The account does not hold enough credits for this template's category. |
| 502 | send_failed | Our messaging platform refused the send. Any credits debited were refunded. |
Nothing is charged for a request that fails validation. A send_failed response has already been refunded by the time you read it.