Skip to main content
custom Free text with variables, header and buttons. It is the most used model and the only fully open one: nothing here is written by Meta, and no field depends on a catalog, a payment or a flow.

Nine ideas to start from

Drag the strip sideways. These nine are starting points, not a catalog: they are all the same custom, and what changes is which components go in. You combine whichever you want — a header in any format, or none; a footer, or none; up to ten buttons, or none.
Open the example closest to what you want and copy the JSON with the button in the corner of the block. It creates exactly the template in the preview; from there, change text, variables and buttons.
With no variables, the body carries no example. Bold is WhatsApp’s *asterisk*, and the paragraphs are \n — only the message accepts line breaks. At send time, a media header requires the image parameter: the one at creation is just the sample Meta reviews.
The quick reply comes after the URL, not between other types: buttons sit in two groups. Giving an explicit way out reduces blocks, which is what hurts number quality the most.
A video header accepts MP4 and 3GPP, up to 16 MB. The quick reply opens the 24-hour window when the customer taps it, and from there you talk without a template.
The customer’s answer comes back on your webhook with the button text. Note the variable neither opens nor closes the text — if it did, Meta would reject it with 2388299.
The URL button accepts one variable, only at the end of the address. It is positional even on a named template, because that is the button’s own numbering.
The location header has nothing to fill in at creation: the address, the place name and the coordinates go at send time. It lets you send the same message pointing at different stores.
Not every template needs an action. With no variables and no buttons, this is the cheapest shape to get approved and the hardest to get rejected.
The least a template can be: a message and nothing else. With no variables and a fixed link, the send carries only the name and the language.
It is this page’s full payload: text header with a variable, message, footer and the three free button types. It sits complete in the creation JSON, with the send JSON next to it.

How it works

You write the text once, mark what changes per customer as a variable, and Meta approves the mold. At send time, each variable gets the value for that dispatch. It is the model for everything that isn’t commerce, authentication or a promotion with its own structure: order confirmation, status update, billing, appointment reminder, re-engagement.

At creation and at send time

Fields in this model

Full JSON

Two JSON payloads: one creates the template, and Meta approves it once. The other sends the message, and goes on every dispatch, with that send’s values in the variables marked with braces.

1. Create the template

POST /whatsapp/businesses/{wabaId}/templates — see API reference.

2. Send it once approved

POST /v1/channels/{channelId}/messages — see Send template.

What Meta rejects here

  • A variable opening or closing the header or message text.
  • A variable without an example.
  • Short text with too many variables.
  • A quick reply in the middle of the other buttons.
  • A button address without http or https, and a phone without the country code.
The error code for each case is in Validation.