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

# Create and approve a WhatsApp message template

> Walk a WhatsApp template from blank editor to approved: category, body variables with sample values, header/footer/buttons, per-language submission, and how to respond to a rejection.

# Create and approve a WhatsApp message template

Every business-initiated WhatsApp conversation starts with a template Meta has reviewed and approved. This guide walks the full task — drafting, submitting, tracking, and resubmitting after a rejection. If you are still connecting the account itself, do the [WABA setup](/guides/whatsapp/waba-setup) first, then come back here. The [concept page](/concepts/template-lifecycle) explains the lifecycle model this guide executes; the [troubleshooting page](/troubleshooting/whatsapp-template) covers templates stuck at pending and reclassifications.

## Why templates exist

Two rules shape everything on WhatsApp. Meta only lets a business *start* a conversation with a pre-approved template — an order confirmation, a one-time passcode, a shipping update. When the customer replies, a 24-hour *service window* opens and free-form messages (text, media, interactive buttons) are allowed without a template. When the window closes, you are back to templates only. [The 24-hour window guide](/guides/whatsapp/24h-window) covers the full model.

Because every cold-open send depends on one, template approval is the gate for the rest of your WhatsApp setup — campaigns, flows, and inbox workflows all reference approved templates.

## Step 1 — Pick the right category

The category you declare drives both [what Meta charges](/guides/whatsapp/pricing) and how strictly the review judges the content.

| Category           | Use for                                                         | Cost signal                                      |
| ------------------ | --------------------------------------------------------------- | ------------------------------------------------ |
| **Authentication** | OTPs, login codes, password resets                              | Cheapest tier                                    |
| **Utility**        | Order status, appointment reminders, delivery updates, receipts | Mid-tier                                         |
| **Marketing**      | Promotions, re-engagement, upsells, abandoned cart              | Most expensive                                   |
| **Service**        | Replies inside a user-initiated support conversation            | Free for the first 1,000 conversations per month |

**The honest-categorization rule:** declare what the message actually is. A promotional body submitted as `utility` to pay the cheaper rate is the single most common rejection — and a suspended WABA is the downstream risk if Meta reclassifies it anyway. Always send what the customer expects in the least expensive category the content genuinely qualifies for. The [content policy](/compliance/whatsapp-content-policy) lists what Meta rejects outright (gambling, adult content, illegal products, misleading claims).

## Step 2 — Draft the body with variables

Body variables are numbered placeholders — `{{1}}`, `{{2}}`, `{{3}}` — filled at send time:

```
Hi {{1}}, your order {{2}} shipped. Track it here: {{3}}
```

For each variable the submission requires a **sample value** — Meta's reviewer reads the message with the samples filled in, and a template with no sample values is routinely rejected as unverifiable. Give realistic values, not `test` or `xxx`:

| Variable | Good sample                         | Bad sample |
| -------- | ----------------------------------- | ---------- |
| `{{1}}`  | `Ada`                               | `NAME`     |
| `{{2}}`  | `ORD-12345`                         | `test`     |
| `{{3}}`  | `https://track.example.com/o/12345` | `url`      |

Formatting rules Meta enforces:

* Variables cannot contain newlines, tabs, or more than four consecutive spaces at send time
* Formatting markers (`*bold*`, `_italic_`, `~strikethrough~`) must be paired — an unmatched `*` is a formatting-error rejection
* URLs are allowed in the body; avoid shortened/obfuscated links (bit.ly et al.) — they read as phishing to the reviewer

## Step 3 — Header, footer, buttons

Optional components, configured per template.

### Header

* **Text** — a single line, up to 60 characters. It may contain one variable.
* **Media** — an image, video, or document (PDF). Always provide a sample file at submission so the reviewer can see it. Use a media header when the visual carries the message (a product photo, a boarding pass).

A text header beats a media header when the message has to survive low-bandwidth clients.

### Footer

Static text, up to 60 characters, no variables. Use it for legal lines ("Reply STOP to opt out") or a support hint.

### Buttons

Two types; do not mix them in one template.

* **Quick reply** — up to 3 buttons. Each press sends a predefined text back to you and opens (or resets) the 24-hour window. Labels are ≤25 characters, plain text.
* **Call-to-action** — up to 2 buttons, each either **URL** (deep link, may use one variable suffix) or **phone number** (opens the dialer with a fixed number).

Quick-reply buttons are the cheapest way to turn a notification into a conversation: "Track order" / "Reschedule" / "Talk to support".

## Step 4 — Languages

Each locale is a **separate submission** with its own status — approving `en` does not approve `es`. Reuse the same template **name** across locales so a single send call resolves the right language via the `language.code` you pass:

```
Template name: order_confirmation
Languages: en, es, pt-BR (three submissions, one name)
```

Translate the body, keep the variable order identical, and match the declared `language` to the actual body language — a Spanish body under `language=en` is one of the most common rejections. Track each locale's status independently: `es` can be approved while `pt-BR` is still pending.

## Step 5 — Submit and track status

In the dashboard: **Channels → WhatsApp → Templates → New Template**. Filling the form creates the template in `draft`; pressing **Submit** moves it to `pending`. From there:

| Status     | Meaning                        |
| ---------- | ------------------------------ |
| `draft`    | Authored, not yet sent to Meta |
| `pending`  | In Meta's review queue         |
| `approved` | Sendable                       |
| `rejected` | Refused — edit and resubmit    |

Most templates are approved within minutes; allow up to 24 hours. The full lifecycle model — including `active`, `paused`, and `archived` states — is on the [template lifecycle concept page](/concepts/template-lifecycle). The API carries the same statuses; poll `GET /api/v1/messages/templates?status=pending` to watch open submissions.

## Step 6 — Handle a rejection

A rejection is a do-over, not a dead end. Meta keeps the template name free for 30 days, so edit the rejected template and resubmit under the same name. Map the rejection to one of the usual causes:

| Rejection pattern     | Cause                                                    | Fix                                                                                |
| --------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Category mismatch     | Promotional copy declared as `utility`                   | Re-declare as `marketing`, or strip the promotion                                  |
| Missing sample values | Variable(s) have `test`/blank samples                    | Fill realistic samples for every variable                                          |
| Off-policy content    | Gambling, adult, misleading claims, prohibited verticals | Remove the content — see the [content policy](/compliance/whatsapp-content-policy) |
| Formatting error      | Unpaired `*`, stray newline in a button label            | Fix the markers                                                                    |
| Language mismatch     | Body language ≠ declared language                        | Correct the `language` field                                                       |

**Resubmission example.** This body was rejected when submitted as `utility`:

```
Special promotion! 20% off all plans this weekend. {{1}}, grab it now.
```

Two clean fixes:

1. **Re-categorize.** Resubmit the identical body as `marketing`, sample `{{1}}` = `Ada`. Approved.
2. **De-promote the copy.** If it must stay `utility`, remove the promotion:

```
Hi {{1}}, your current plan renews on {{2}}. Manage your plan: {{3}}
```

If Meta's own feedback names a policy — "promotional content", "missing sample" — fix that specific item rather than rewriting the whole template.

## Step 7 — Send with the approved template

Reference the approved template by `name` and `language`, and fill the variables through `components`:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/whatsapp \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155552671",
    "type": "template",
    "template": {
      "name": "order_confirmation",
      "language": { "code": "en" },
      "components": [
        {
          "type": "body",
          "parameters": [
            { "type": "text", "text": "Ada" },
            { "type": "text", "text": "ORD-12345" }
          ]
        }
      ]
    }
  }'
```

Next moves, depending on the shape of your send:

* **Interactive follow-ups** — wrap the template send in a WhatsApp Flow (a form the recipient fills in-chat). See [WhatsApp Flows](/guides/whatsapp/whatsapp-flows).
* **Broadcast to a segment** — reference this template from a campaign. The [campaign launch playbook](/guides/whatsapp/campaign-launch-playbook) covers opt-in checks, throttling, and delivery tracking.
* **Free-form replies** — once the recipient answers, drop the template and use the 24-hour window. See [The 24-hour window](/guides/whatsapp/24h-window).

## Checklist before you submit

1. Category declared honestly (marketing copy as `marketing`)
2. Realistic sample value on every `{{n}}` variable
3. Header ≤60 chars (text) or a sample media file attached
4. Buttons: one type only, up to 3 quick-reply **or** up to 2 call-to-action
5. Declared `language` matches the body language
6. No prohibited content per the [content policy](/compliance/whatsapp-content-policy)
