Skip to main content
POST
Creates a WhatsApp message template and submits it to WhatsApp for review — the same thing the Create button does in Chatbot Manager → Message Templates, from your own code. Once WhatsApp approves it you can send it with Send Template Message.
Creating a template does not make it sendable. It starts as Submitted, and WhatsApp reviews it before it can be used. Check progress with Template Status. There is no edit or delete endpoint: to change a template, create a corrected copy under a new name.

Example Request

The body is JSON. The key goes in the Authorization header, so it stays out of the body and out of logs.
Send Accept: application/json. Without it, a wrong or missing key is answered with a redirect to the login page (an HTML page) instead of a JSON 401 {"message":"Unauthenticated."}.

The three kinds of template

One endpoint takes three shapes. Which one you get is set by template_type and category; if you leave template_type out it is mixed.
WhatsApp fixes the layout of a one-time-passcode message, with its Copy code button. Do not send body_text, header or buttons for an AUTHENTICATION template. A carousel built from catalog products (carousel_product) needs a connected store; create those from Chatbot Manager → Message Templates → Create → Carousel Product Template.

Normal messages

A header can be text ({"type":"text","text":"Order update"}) or media (image, video or document, with a public media_url). Buttons are one of four kinds:

One-time passcodes

verification_code is the placeholder that carries the code each time you send. code_expiration_minutes is from 1 to 90 and is shown in the footer. add_security_recommendation adds WhatsApp’s line For your security, do not share this code.

Carousels

bubble_body_text is the text above the cards. Each card has an image or video, its own text, and one or two url or quick_reply buttons. WhatsApp needs at least 2 cards and allows 10, and every card must use the same media_type and the same buttons in the same order. Carousel templates count against your plan’s carousel allowance.

Placeholders

Anywhere you write text, you can put a placeholder that ChatSyncs fills in when the template is sent: The reply’s variable_map shows how each placeholder was read, by position: {"body": {"1": "#LEAD_USER_FIRST_NAME#"}}. Read Template Variables vs Custom Variables for when to use which.

Limits

The response

The reply carries two IDs. id is ChatSyncs’ own short number, which Send Template Message takes as its template_id. template_id is WhatsApp’s long number, which Template Status takes. Keep both.

Errors

A failure comes back as HTTP 200 with "status": "0", so always check status. The message is the reason:
If a request times out, look before you retry. The template may have been created. Check Bot Template Get for the name; sending the same name again is answered with WhatsApp template name already exists.

Frequently asked

WhatsApp has to approve it first. It starts as Submitted. Poll Template Status until it reads APPROVED. One-time-passcode templates are often approved within seconds; marketing templates and carousels can take longer.
Not through this API. Create a corrected copy under a new name and stop using the old one. A rejected template can never be sent as it is.
UTILITY is for a message about something the customer did or asked for: an order update, a booking, a receipt. A promotion, an offer or an announcement is MARKETING, even if it mentions an order. WhatsApp re-categorises or rejects a template filed in the wrong one, and a marketing message costs more to send. See Guidelines for Utility and Marketing Templates.
The verification_code placeholder you chose when you created the template. Send it as a template variable value through Send Template Message.
Yes. The ChatSyncs MCP server has a create_template ability that checks the template against these limits before it submits it, and a get_template_status ability to follow it afterwards.

Body

application/json
phone_number_id
string
required

The WhatsApp account's phone number ID. Where to find it.

Example:

"PHONE-NUMBER-ID"

name
string
required

The template's name. Lowercase letters, numbers and underscores only — no spaces or capitals. It must be unique on the WhatsApp account, and it is permanent.

Example:

"summer_promo_2026"

category
enum<string>
required

MARKETING for promotions, offers and announcements. UTILITY for messages about something the customer did or asked for (an order, a booking, a receipt). AUTHENTICATION for one-time passcodes only. Carousels must be MARKETING. WhatsApp can re-categorise or reject a template filed in the wrong one.

Available options:
MARKETING,
UTILITY,
AUTHENTICATION
Example:

"MARKETING"

apiToken
string

Your ChatSyncs API key (not a WhatsApp/Meta access token). Leave it out of the body if you send it as Authorization: Bearer <key> instead — both work. Where to find it.

Example:

"API-KEY"

language
string
default:en_US

The template's language code. Defaults to en_US. Examples: en_US, en_GB, hi_IN, bn_BD, pt_BR.

Example:

"en_US"

template_type
enum<string>
default:mixed

Which kind of template this is. mixed (the default) is a normal message, wp is a WordPress template, authentication is a one-time-passcode message, carousel is swipeable image or video cards, and carousel_product is a carousel built from catalog products. The fields below depend on it.

Available options:
mixed,
wp,
authentication,
carousel,
carousel_product
body_text
string

Normal messages (mixed, wp) — required. The message text, up to 1,024 characters when WhatsApp reviews it (each #placeholder# counts as one character). Not used by authentication or carousel templates.

Example:

"Hi #LEAD_USER_FIRST_NAME#, get #discount#% off using code #coupon#!"

header
object

Normal messages — optional. A header shown above the message.

Normal messages — optional. Small grey text under the message, up to 60 characters. Static: it takes no placeholders.

Example:

"Valid till Sunday"

buttons
object[]

Normal messages — optional. Up to 10 buttons, at most one copy_code. quick_reply is a tappable reply, url opens a link, phone_number starts a call, and copy_code copies a coupon code.

verification_code
string

Authentication templates — required. The placeholder that carries the one-time code: a template variable such as #!system_otp!#, or a custom field such as #otp_field#.

Example:

"#!system_otp!#"

add_security_recommendation
boolean

Authentication templates — optional. true adds WhatsApp's line "For your security, do not share this code."

Example:

true

code_expiration_minutes
integer

Authentication templates — optional. How long the code stays valid, from 1 to 90 minutes. It is shown in the footer.

Required range: 1 <= x <= 90
Example:

5

bubble_body_text
string

Carousels — required. The introduction text shown above the cards, up to 1,024 characters.

Example:

"Hey #LEAD_USER_FIRST_NAME#, check out our top trending collection!"

cards
object[]

Carousels — required. The cards, 2 to 10 of them. Every card must use the same media_type and the same buttons in the same order.

Response

Standard ChatSyncs response. status is "1" when the template was created and submitted, and "0" on failure. Read the failure reason from message.

status
string

"1" = created and submitted, "0" = failure.

message
string

Human-readable result, or the failure reason.

data
object

The new template. Present on success.