Use this file to discover all available pages before exploring further.
Templates are pre-approved message formats required for contacting users outside the 24-hour conversation window. They must be submitted to Meta for approval before use.
A template can use one of two placeholder formats, and you pass values the same way for both:
Positional: {{1}}, {{2}}, {{3}} — keyed by position.
Named: {{customer_name}}, {{order_id}} — keyed by name.
Template body: "Hi {{1}}, your order #{{2}} is confirmed. Delivery: {{3}}." ^ ^ ^ | | |Variables: "1": "John" "2": "ORD-12345" "3": "January 20, 2025"
In both cases you provide the values through templateVariables. The keys match
the placeholders in the template body — numbers for positional templates, names
for named templates:
You must provide values for all variables defined in the template. Missing variables will cause the message to fail (#100 INVALID_PARAMETER from Meta).
You normally don’t need to care: Zavu detects the format per template and builds the correct Meta payload. The distinction matters only when you decide what keys to use in templateVariables:
How the template was created
Format at Meta
Keys to use
Created in Zavu (POST /v1/templates)
Positional — Zavu converts {{name}} → {{1}} at submit time
Position numbers ("1", "2") or the original names
Imported from an existing WhatsApp Business Account
Whatever Meta has on file — named or positional
Match the placeholders in the template body
Fetch the template (GET /v1/templates/{id}) and read its body to see which placeholders it expects. If the body shows {{customer_name}}, use { "customer_name": "..." }; if it shows {{1}}, use { "1": "..." }.
A template can have a text header with its own variable, e.g. Invitación Boda {{novios}}. The header variable is independent from the body variables, but you pass its value through the sametemplateVariables object, keyed by the header placeholder’s name (or {{1}} for a positional header):
WhatsApp text headers allow at most one variable. Static text headers (no placeholder) need no value — Meta has the text baked into the approved template.
When a template has a URL button with a {{1}} placeholder, pass the substitution under templateButtonVariables keyed by the button’s position in the template’s buttons array.templateVariables is for body placeholders. templateButtonVariables is for buttons. They use different keys:
templateVariables keys → position of the placeholder in the body text ("1", "2", …).
templateButtonVariables keys → index of the button in the buttons array ("0", "1", "2").
WhatsApp URL buttons only accept {{1}} (positional, numeric, no whitespace, no name). Even though body placeholders may use named parameters like {{name}}, URL buttons do not. Anything else ({{token}}, {{ 1 }}, {{user.id}}, etc.) is approved by Meta as literal text in the URL — there is no way to substitute it later.If your template was approved with a non-{{1}} placeholder in a URL button, you must recreate the template with {{1}} and resubmit it for approval. Zavu now returns 400 invalid_request instead of silently delivering broken URLs like https://...%7B%7Bvariable%7D%7D.
Example. Suppose your approved template looks like this:
{ "id": "tpl_discipline_report", "body": "Hi {{1}}, your child received a {{2}}.", "buttons": [ { "type": "url", "text": "View report", "url": "https://reporte.link/{{1}}" } ]}
For templates with several buttons, supply one entry per dynamic button. Static URL buttons (no {{1}}) and quick_reply buttons are not included in templateButtonVariables.