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

# Template variables and dynamic content

> Use variables in WhatsApp template headers, body, buttons, and URLs — syntax rules, sample values, HubSpot personalisation tokens, and rejection traps.

Variables let a single approved template send personalised messages to thousands of contacts without resubmitting to Meta. This page is a deep dive on how variables work in Flowella, where they can appear, and how to wire them up to HubSpot data.

For a high-level overview of template structure, see [Template reference](/app/template-reference). For step-by-step template creation, see [Templates](/app/templates).

## Syntax

WhatsApp templates use **positional variables** with double curly braces and a 1-based index:

```text theme={null}
Hi {{1}}, your booking on {{2}} is confirmed. Reference: {{3}}.
```

Rules:

* Indexes start at `{{1}}` and must be **sequential** — you cannot skip from `{{1}}` to `{{3}}`.
* The same index can be reused inside a single component (body, header, or URL) but Flowella will send the same value to each occurrence.
* Whitespace inside the braces is not allowed: `{{ 1 }}` is invalid.
* Variables are **text only**. Numbers, dates, and currency are sent as strings — format them upstream in HubSpot before sending.

<Note>
  Meta is rolling out **named variables** (`{{first_name}}`) for new templates. Flowella supports both, but positional indexes remain the most reliable format across all template types and Cloud API versions.
</Note>

## Where variables can appear

| Component                                     | Variables allowed            | Notes                                                    |
| --------------------------------------------- | ---------------------------- | -------------------------------------------------------- |
| **Header (TEXT)**                             | 1                            | Short values only — no line breaks.                      |
| **Header (media)**                            | 1 (the media handle or URL)  | Variable is the media itself, not text.                  |
| **Header (LOCATION)**                         | 4 (lat, long, name, address) | All four are required when the header is variable.       |
| **Body**                                      | Up to \~10 in practice       | Each variable counts toward Meta's body character limit. |
| **Footer**                                    | None                         | Footer is static text only.                              |
| **URL button**                                | 1                            | Appended to the end of a static base URL.                |
| **COPY\_CODE button**                         | 1                            | The full code value.                                     |
| **Quick reply, Phone, Flow, Catalog buttons** | None                         | Static configuration.                                    |
| **Carousel cards**                            | Up to 3 per card body        | Each card's variables are numbered independently.        |

## Sample values

When you submit a template to Meta, every variable needs a **sample value**. Meta uses the samples to:

1. Decide if the template's content matches the chosen category (Marketing, Utility, Authentication).
2. Estimate quality and spam risk.
3. Display a preview to reviewers.

Sample values are not used at send time — they are only for review. But they matter:

* Use **realistic** values. `{{1}} = "John"` is fine; `{{1}} = "xxx"` often triggers rejection.
* Keep samples **short**. Pasting a paragraph into a single variable is a classic rejection signal.
* Make sure the sample is **type-appropriate**. If `{{2}}` is a date, use a date. If it's an order number, use something that looks like an order number.

## Wiring variables to HubSpot data

In a HubSpot workflow that uses Flowella's **Send WhatsApp Template** action:

<Steps>
  <Step title="Pick the template">
    Flowella shows every approved template for your channel. Variables are auto-detected from the template body, header, and buttons.
  </Step>

  <Step title="Map each variable to a HubSpot value">
    For each `{{n}}`, choose a HubSpot contact, company, deal, or ticket property — or type a static value. You can mix personalisation tokens and literal text in the same mapping.
  </Step>

  <Step title="Set a fallback for empty values">
    If a contact has no value for the mapped property, the message will fail unless you provide a fallback. Common fallbacks: `"there"` for first name, `"your account"` for account name.
  </Step>

  <Step title="Test before going live">
    Send the workflow to a single test contact first. Meta rejects sends where any variable is empty, contains only whitespace, or contains a newline.
  </Step>
</Steps>

<Warning>
  Empty variables fail at send time, not at template approval. A workflow that runs against thousands of contacts can be silently dropped if a critical property is missing. Always set fallbacks.
</Warning>

## Variable formatting tips

**Names**

```text theme={null}
Hi {{1}},
```

Capitalise the property in HubSpot upstream, or use a HubSpot workflow step to copy `firstname` into a "First name (formatted)" property.

**Dates**

WhatsApp templates do not format dates. If your HubSpot property is `2026-05-24T00:00:00Z`, that's what arrives in the message. Use a HubSpot calculated property or workflow action to format dates as `24 May 2026` before mapping them.

**Currency**

Same as dates — format upstream. Include the currency symbol in the static text (`Total: £{{1}}`) so the variable is just the number.

**URLs in body text**

You can include the full URL inside a body variable, but the link preview will not render and the URL counts against the body character limit. Use a **URL button** with a variable suffix instead:

```text theme={null}
Base URL: https://acme.com/orders/
Variable: {{1}}
At send time: https://acme.com/orders/AB-1234
```

## Common rejection reasons related to variables

* **Skipped indexes** (`{{1}}` then `{{3}}`). Always renumber.
* **Variable at the very start or end** of the body with no surrounding text (`{{1}}` alone). Add a word before or after.
* **Two variables adjacent** (`{{1}}{{2}}`). Separate them with at least a space or punctuation.
* **Sample values that look like placeholders** — `"test"`, `"xxx"`, `"123"` — especially in Marketing templates.
* **Variables in the footer** — not allowed.
* **More than one variable in a URL button** — only one is allowed, and it must be at the **end** of the URL.

## Advanced patterns

### Re-using a value across components

If a customer name appears in both the header and the body, define it once in your workflow and map both `{{1}}` (header) and `{{1}}` (body) to the same HubSpot property. Flowella sends each component its own parameter list, so the indexes are independent — you map the value twice, but you only store it once in HubSpot.

### Conditional content

WhatsApp templates do not support if/else logic inside the template. To send different content to different contact segments, create **separate templates** and branch in your HubSpot workflow — for example, "VIP welcome" and "Standard welcome".

### Multi-language templates

A template's name and structure are shared across languages, but each language is **submitted, approved, and stored separately**. Variables must be in the same positions in every language version. Flowella picks the right language based on the contact's `hs_language` property (or a fallback you configure).

## Troubleshooting

* **Template approved but messages fail with "parameter mismatch"** — Meta and Flowella disagree on how many variables the template has. Re-fetch the template in Flowella (Templates → refresh) so the variable count syncs.
* **Variable shows literal `{{1}}` in the delivered message** — the workflow didn't map a value to that index. Check the workflow action's parameter list.
* **Message rejected at send with "policy violation"** — a variable contains a URL or content that doesn't match the template's category. Marketing-style content cannot be injected into a Utility template via variables.

<Tip>
  For the full lifecycle of submitting, editing, and pausing templates, see [Templates](/app/templates) and [Template reference](/app/template-reference). For rejection-specific help, see [Template rejected](/troubleshooting/template-rejected).
</Tip>
