Templates
WhatsApp templates are pre-approved messages you can send at any time. Meta reviews every new template, so a new template is PENDING until Meta marks it APPROVED or REJECTED. Every endpoint on this page needs the /templates grant.
List templates
Section titled “List templates”GET /v2/templates
| Query | Default | Description |
|---|---|---|
status |
all | APPROVED, PENDING or REJECTED |
search |
Filter by name | |
page |
1 | Page number, starting at 1 |
pageSize |
50 | Up to 100 |
curl "https://api.wabot.shop/v2/templates?status=APPROVED&pageSize=20" -H "Authorization: $TOKEN"{ "data": { "templates": [ { "template_name": "order_update", "category": "UTILITY", "language": "en", "status": "APPROVED", "variables": ["name", "custom_order"] } ], "page": 1, "pageSize": 20, "total": 14 }}variables lists the keys to pass when you send the template.
The older GET /templates/get-templates endpoint returns every approved template in one response, with no pagination.
Get one template
Section titled “Get one template”GET /v2/templates/{name}
Returns {"data": {…template, "variables": […]}}, or 404 {"message": "Template not found"}.
Create a template
Section titled “Create a template”POST /templates/create
| Field | Required | Description |
|---|---|---|
template_name |
Yes | Lowercase letters, numbers and underscores, unique in your account, e.g. diwali_offer_2026 |
category |
Yes | MARKETING, UTILITY or AUTHENTICATION |
language |
Yes | Language code, e.g. en or en_US |
whatsappPhoneId |
Yes | The number the template belongs to |
components |
Yes | Header, body, footer, buttons or carousel (see below) |
categoryChangeAllowed |
No | Lets Meta change the category if it doesn’t match the content |
Write the body text with named variables in double braces, and give an example value for each:
{ "template_name": "order_update", "category": "UTILITY", "language": "en", "whatsappPhoneId": "123456789012345", "components": [ { "type": "header", "parameters": [{ "type": "text", "text": "Order update" }] }, { "type": "body", "parameters": [ { "type": "text", "text": "Hi {{name}}, your order {{order}} has shipped." }, { "type": "variable", "variable": { "text": "name", "value": "Asha" } }, { "type": "variable", "variable": { "text": "order", "value": "#1042" } } ] }, { "type": "footer", "parameters": [{ "type": "text", "text": "Reply STOP to opt out" }] }, { "type": "button", "parameters": [ { "type": "cta", "cta": { "text": "URL", "value": "Track order", "url": "https://example.com/track" } }, { "type": "quick_reply", "quick_reply": { "value": "Talk to us" } } ] } ]}Component reference
Section titled “Component reference”| Component | Shape |
|---|---|
| Text header | {"type": "header", "parameters": [{"type": "text", "text": "…"}]} |
| Media header | {"type": "image", "image": {"link": "https://…"}}. Also video or document |
| Body | {"type": "body", "parameters": [text, …variables]} |
| Footer | {"type": "footer", "parameters": [{"type": "text", "text": "…"}]} |
| Quick reply button | {"type": "quick_reply", "quick_reply": {"value": "Yes"}} |
| URL button | {"type": "cta", "cta": {"text": "URL", "value": "Label", "url": "https://…"}} |
| Call button | {"type": "cta", "cta": {"text": "Phone", "value": "Call us", "url": "+91…"}} |
| Carousel | {"type": "carousel", "components": [{header, body, buttons}, …]} |
Response 200: {"data": {…template, "status": "PENDING"}}.
If the name is already taken, or the phone ID isn’t found, the response is still 200, but data is a message string such as "The template \"order_update\" is already exist". Check whether data is a string or an object.
Check approval status
Section titled “Check approval status”GET /templates/status?template_name=order_update
{ "data": { "status": "APPROVED" } }To pull the latest status from Meta for all templates at once:
POST /v2/templates/sync
{ "data": { "updated": [{ "name": "order_update", "status": "REJECTED", "rejected_reason": "INVALID_FORMAT" }], "errors": [] }}You can also subscribe to the template_status_update webhook instead of polling.
Update a template
Section titled “Update a template”PUT /templates/update?template_name=order_update
Body: {"components": […], "category": "UTILITY"}. Meta reviews the template again after an update.
Typical flow
Section titled “Typical flow”POST /templates/createcreates the template, which starts asPENDING.- Call
GET /templates/statusevery few minutes, or wait for thetemplate_status_updatewebhook. - Once the status is
APPROVED, send it.
