> ## Documentation Index
> Fetch the complete documentation index at: https://documents.xobito.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamic Templates

> How Xobito describes templates that use variables — and why they're not a separate template type.

<Note>
  **"Dynamic" is not a separate template type.** A dynamic template is simply a regular WhatsApp template that uses variable placeholders (`{{1}}`, `{{2}}`, …). It lives in the same Templates list, uses the same builder, and goes through the exact same Meta approval process as any other template.

  If a template contains at least one `{{n}}` placeholder, the Xobito UI labels it "dynamic". If it has none, it's labelled "static". That's the entire distinction.
</Note>

A **dynamic template** is a template with variables — placeholders like `{{1}}`, `{{2}}`, `{{3}}` — that Xobito replaces with real values when the message is sent. Internally, Xobito stores a `body_params_count` on each template: any value greater than zero means the template has variables and the UI calls it "dynamic".

## Why variables matter

One template, many personalised messages. Without variables:

* You would need a separate template for every recipient — impractical.
* Your messages would say "Hi Customer" instead of "Hi Alex".
* You could not reference order numbers, dates, or account details.

With variables, a single approved template becomes flexible for thousands of recipients — but it's still the same template, approved once by Meta.

## Variable syntax

Xobito template variables use double-brace **numbered** placeholders:

```
{{1}}  {{2}}  {{3}}  …
```

* Double braces on each side.
* **Digits only** — no names, no spaces.
* Start at `{{1}}` and number sequentially.

<Warning>
  Template variables use `{{1}}` style — indexed numbers.

  Bot Flows use a **different** variable syntax — `{variable_name}` with single braces and a name.

  Don't mix them. Template variables are always numeric and double-braced.
</Warning>

## How variables work

Inside the body (and in text headers), you insert numbered placeholders wherever a value should be filled in:

```
Hi {{1}},

Your order *#{{2}}* is confirmed. Estimated delivery: {{3}}.

Questions? Reply HELP.
```

Each `{{n}}` is replaced at send time. For a contact named Alex with order `A1042` arriving Friday:

```
Hi Alex,

Your order *#A1042* is confirmed. Estimated delivery: Friday.

Questions? Reply HELP.
```

<Note>
  Variables must be numbered sequentially starting at `{{1}}`. Skipping numbers (`{{1}}` then `{{3}}`) will be rejected by Meta.
</Note>

## Where variables can appear

| Template part            | Variables allowed                |
| ------------------------ | -------------------------------- |
| Text header              | Yes — up to 1 variable           |
| Body                     | Yes — typically 1 to several     |
| Footer                   | No                               |
| Media header             | No (the sample file is separate) |
| Quick-reply button label | No                               |

## Example values at creation time

When you create a template with variables, you must supply a **sample value** for each one. Meta reviewers use these to see what a real message will look like.

| Variable | Example value |
| -------- | ------------- |
| `{{1}}`  | `Alex`        |
| `{{2}}`  | `A1042`       |
| `{{3}}`  | `Friday`      |

<Tip>
  Use realistic sample values. "Alex" and "A1042" look legitimate. "xxx" or "test" look like you're gaming the system — and Meta rejects them.
</Tip>

Body variable example values are stored on the template in `body_variable_value`, and (if you have a text header) header variable example values are stored in `header_variable_value`.

## How values get filled in at send time

### In a campaign

When you set up a campaign that uses a dynamic template, Xobito asks you to provide values for each variable. These are saved with the campaign as `header_params`, `body_params`, and `footer_params` JSON arrays — and applied to every message the campaign sends.

### In a CSV campaign

For a CSV-driven campaign, you upload a spreadsheet with one row per recipient. The CSV columns supply the variable values on a per-row basis, so every recipient can get different values.

Example CSV:

```csv theme={null}
phone,name,order,eta
+14155551234,Alex,A1042,Friday
+919876543210,Priya,B7721,Monday
```

Each row's columns become the substitution values for that recipient's message.

### In live chat

When you send a template in a chat, Xobito asks you to fill in the values right there — one-off per message.

## Creating a template with variables

You don't create "dynamic templates" in a separate place — you use the normal template builder and add `{{n}}` placeholders wherever you want personalisation.

<Steps>
  <Step title="Open the template builder">
    **Templates → Add Template**. See [Create a Template](/templates/create-template) for the full walkthrough.
  </Step>

  <Step title="Write the body with variables">
    Insert `{{1}}`, `{{2}}`, etc. wherever you want a personalised value. Numbers must be sequential starting at `{{1}}`. The moment you add one, the template is considered "dynamic".
  </Step>

  <Step title="Provide sample values">
    For each variable, type a realistic example. Meta uses these during review.
  </Step>

  <Step title="Save and wait for approval">
    Submission sends the template to Meta. The status moves to PENDING, then APPROVED or REJECTED — same flow as any other template.
  </Step>

  <Step title="Supply values when sending">
    Once approved, every campaign or chat that uses the template asks you to supply the actual values — either campaign-wide, per CSV row, or per message.
  </Step>
</Steps>

## Previewing before you send

<Tip>
  Always preview at least one message before sending a campaign. A preview renders the template with one recipient's real data — catching empty values, weird capitalisation, or mismatched columns before they go out to thousands of people.
</Tip>

## Variables in URL buttons

If you use URL buttons that include a variable (for example `https://yoursite.com/receipt/{{1}}`), you supply the value at send time, the same way as body variables. See [Variables & Media](/templates/variables-and-media) for details on button availability.

## Rules and limits

| Rule             | Detail                                                                                  |
| ---------------- | --------------------------------------------------------------------------------------- |
| Variable format  | Double braces around a digit: `{{1}}`, `{{2}}`                                          |
| Numbering        | Sequential, starts at `{{1}}`, no gaps                                                  |
| Sample required  | Every variable must have a sample value at creation time                                |
| Body start/end   | Meta often rejects templates that begin or end with a bare variable — wrap them in text |
| No nested braces | `{{{{1}}}}` is not valid                                                                |

## Best practices

<AccordionGroup>
  <Accordion title="Keep variables short and specific">
    `{{1}}` for a first name, `{{2}}` for an order number. Not for an entire sentence — Meta rejects those as "meaningless placeholder".
  </Accordion>

  <Accordion title="Use realistic sample values">
    Meta reviewers look at examples. "Alex" and "A1042" look legitimate. "xxx" and "test" look like you're gaming the system.
  </Accordion>

  <Accordion title="Think about empty values">
    Decide what to do when a contact has no value for a variable. Either skip that recipient or provide a campaign-level fallback.
  </Accordion>

  <Accordion title="Preview every campaign">
    Before a 10,000-recipient send, preview at least three real recipients. Catch formatting issues before they go live.
  </Accordion>

  <Accordion title="Number carefully">
    If you remove a middle variable like `{{2}}`, you must renumber the rest so the sequence is `{{1}}`, `{{2}}`, `{{3}}` without gaps.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Template rejected for 'meaningless variable'">
    Meta thinks `{{1}}` is being used as a placeholder for vague or large content. Shorten the variable — a name, a number, a date. Use fixed text for bulk copy.
  </Accordion>

  <Accordion title="Variable shows as {{1}} in the actual message">
    Either the variable wasn't supplied at send time, or the source value is empty. Check the campaign setup and the recipient's record.
  </Accordion>

  <Accordion title="Template rejected with 'variable sequence wrong'">
    Variables must be numbered 1, 2, 3… with no gaps. If you removed `{{2}}` but kept `{{3}}`, renumber.
  </Accordion>

  <Accordion title="Only some recipients got the message">
    Recipients with missing values may have been skipped. See the campaign log for per-recipient details.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Variables & media" icon="image" href="/templates/variables-and-media">
    Deep dive into headers and media uploads.
  </Card>

  <Card title="Custom fields" icon="file-pen" href="/contacts/custom-fields">
    Store the data you'll use as variable values.
  </Card>

  <Card title="Create a campaign" icon="bullhorn" href="/campaigns/create-campaign">
    Send your dynamic template to a group.
  </Card>

  <Card title="Meta approval" icon="circle-check" href="/templates/meta-approval">
    Avoid rejection with our full guide.
  </Card>
</CardGroup>
