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

# Templates

> The only thing you may send outside the 24-hour window.

WhatsApp permits free-form messages only within 24 hours of the customer's last
inbound message. Outside it — a broadcast, an order update, a payment reminder,
anyone who has never written to the merchant — only an **approved template** may
be sent.

So a partner running campaigns needs to create and track templates without a
merchant logging into anything.

<Note>
  Reading takes `channels:read`; creating and deleting take `channels:write`.
</Note>

## Listing

```http theme={null}
GET /api/v1/partner/tenants/{ref}/templates/?limit=100
```

Returns Meta's own payload — `data[]` with each template's `name`, `status`,
`category`, `language`, `components` and, when it was refused,
`rejected_reason`.

Pass `phone_number_id` when a merchant holds numbers on more than one WhatsApp
Business Account: templates belong to the WABA, not to the merchant.

## Creating

```bash theme={null}
curl -X POST https://api.impellabs.tech/api/v1/partner/tenants/merchant_8812/templates/ \
  -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
  -d '{
    "name": "order_update",
    "category": "UTILITY",
    "language": "en_US",
    "body_text": "Hi {{1}}, your order {{2}} has shipped.",
    "example_body_params": ["Priya", "#10241"],
    "footer_text": "Moti Creations"
  }'
```

<ParamField body="category" type="string" required>
  `UTILITY`, `MARKETING` or `AUTHENTICATION`. This is what you are **billed** on,
  and Meta re-categorises templates it thinks are miscategorised — a marketing
  message dressed as a utility one gets moved, and priced accordingly.
</ParamField>

<ParamField body="body_text" type="string" required>
  Positional placeholders, `{{1}}` upward. Every one of them needs a matching
  entry in `example_body_params` or Meta rejects the template outright.
</ParamField>

**201** with Meta's response, including the template id and its initial status —
almost always `PENDING`.

A template Meta refuses at submission comes back **400** carrying their
validation error verbatim rather than a flattened one, because their message
names the component that was wrong.

## Approval is asynchronous, and slow

<Warning>
  A **201 does not mean you can send it.** Review takes minutes at best and hours
  routinely. A campaign scheduled against a template created moments earlier will
  fail at send time with a `channel_rejected` naming the template.
</Warning>

The outcome arrives as a webhook:

```json theme={null}
{
  "type": "template.status_changed",
  "tenant_ref": "merchant_8812",
  "data": { "object": {
    "name": "order_update",
    "language": "en_US",
    "status": "APPROVED",
    "category": "UTILITY",
    "rejected_reason": ""
  } }
}
```

`status` is `APPROVED`, `REJECTED`, `PAUSED` or `DISABLED`. A template can move
**after** approval: Meta pauses one whose recipients repeatedly block or report
the sender, and disables it if that continues. Treat `PAUSED` as a signal about
the message, not a glitch — it means people did not want it.

Store the status against your own copy and check it before scheduling, rather
than listing templates on every send.

## Sending one

Templates are sent through the ordinary message routes, addressed either to a
thread or straight to a number:

```json theme={null}
{ "type": "template", "template_name": "order_update", "lang": "en_US",
  "body_params": ["Priya", "#10241"] }
```

Positional, in `{{1}}`, `{{2}}` order. See
[Conversations](/reseller/channels/whatsapp/conversations#sending) and
[messaging a number with no thread](/reseller/channels/whatsapp/conversations#messaging-someone-who-has-not-written).

## Deleting

```http theme={null}
DELETE /api/v1/partner/tenants/{ref}/templates/{name}/
```

Meta deletes by **name**, which removes every language version of it. Anything
still scheduled against that template starts failing at send time rather than
here, so delete deliberately.

## What to build

<AccordionGroup>
  <Accordion title="Mirror the status, do not poll for it">
    Store each template's status locally and update it from
    `template.status_changed`. Listing templates before every send costs a Graph
    call per broadcast and tells you nothing new between approvals.
  </Accordion>

  <Accordion title="Categorise honestly">
    `UTILITY` is cheaper than `MARKETING`, which is why every platform sees
    merchants labelling promotions as order updates. Meta re-categorises, bills the
    corrected category, and a merchant whose templates keep being moved attracts
    quality review. Label it as what it is.
  </Accordion>

  <Accordion title="Expect the window, design around it">
    A merchant's first contact with a customer is always a template. Free-form
    replies only become available once the customer answers — which is what the
    24-hour window in every conversation payload tells you.
  </Accordion>
</AccordionGroup>
