> ## 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.

# Templates API: cross-channel approved message templates

> Reusable, carrier-approval-aware message templates across every channel, with CRUD, cross-channel content, AI localization, and per-locale approval tracking.

# Templates API

A template is a reusable message body you author once and send many times — a WhatsApp/RCS template that needs carrier approval before it can be used, an SMS or email body, or an interactive layout. Templates carry their own scope (`templates:read` / `templates:write`) distinct from `messages:*`, because managing a template is a content-authoring + carrier-approval action, not just a send.

**Base path:** `/api/v1/messages/templates`

**Authentication:** API key (`X-API-Key`) or session JWT.

| Method   | Path                                 | Scope             | Purpose                                                                    |
| -------- | ------------------------------------ | ----------------- | -------------------------------------------------------------------------- |
| `GET`    | `/api/v1/messages/templates`         | `templates:read`  | List / search templates (`?search=`, `?channel=`, `?status=`, `?waba_id=`) |
| `GET`    | `/api/v1/messages/templates/summary` | `templates:read`  | Per-channel template counts                                                |
| `POST`   | `/api/v1/messages/templates`         | `templates:write` | Create a template                                                          |
| `GET`    | `/api/v1/messages/templates/{id}`    | `templates:read`  | Get one template                                                           |
| `PATCH`  | `/api/v1/messages/templates/{id}`    | `templates:write` | Update a template                                                          |
| `DELETE` | `/api/v1/messages/templates/{id}`    | `templates:write` | Delete a template                                                          |

`GET /api/v1/templates` is a read-only search alias at the top level (used by the dashboard's command-palette search) that delegates to the same list handler and scope — writes always go through `/messages/templates`.

## Creating a template

For `channel: "whatsapp"` with a `components` array (the rich `HEADER` / `BODY` / `FOOTER` / `BUTTONS` shape), the template is submitted for carrier approval using your own WhatsApp Business Account credentials rather than platform-shared ones. Other channels (SMS, email, RCS, etc.) use a plain `content` string.

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/templates \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "order_shipped",
    "channel": "whatsapp",
    "category": "utility",
    "language": "en",
    "components": [
      { "type": "BODY", "text": "Your order {{1}} has shipped and will arrive by {{2}}." }
    ]
  }'
```

A newly-created WhatsApp/RCS template starts in a pending carrier-approval `status`; poll `GET /{id}` or listen for the template-approval webhook to know when it's ready to send.

The response carries the template id and its initial status:

```json theme={null}
{
  "data": {
    "id": "tpl_9f8e7d6c5b4a",
    "name": "order_shipped",
    "channel": "whatsapp",
    "status": "pending",
    "category": "utility",
    "language": "en",
    "components": [
      { "type": "BODY", "text": "Your order {{1}} has shipped and will arrive by {{2}}." }
    ]
  }
}
```

A WhatsApp template can only be sent once it reaches `approved`. For non-carrier-approval channels (SMS, email) the template is usable immediately.

## Sending a template message

Reference the approved template by name on the unified send endpoint and pass the positional variable substitutions in `variables` (keyed by the `{{1}}`, `{{2}}` placeholders you authored):

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+14155550123",
    "channel": "whatsapp",
    "template_name": "order_shipped",
    "language": "en",
    "variables": { "1": "DV-48291", "2": "Aug 26" }
  }'
```

Either `body`, `template_name`, or `media_url` is required on every send — a template send substitutes for the freeform body. See the [Messaging API](/api-reference/endpoints/messaging) reference for the full request and response shape.

## AI localization

`POST /{id}/localize` auto-translates one canonical template's body and button labels into up to 25 target locales, then creates one `(channel, name, language)` row per locale through the same carrier-submission path a hand-authored variant uses — so each translated variant goes through carrier approval exactly like an original. `GET /{id}/localizations` returns the per-locale approval tracker: every language variant sharing the template's `(channel, name)`, each with its own status.

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/templates/tpl_abc123/localize \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "locales": ["es", "fr", "pt-BR"] }'
```

## Reusable content templates

`/api/v1/messages/content-templates` is a separate, channel-agnostic layer above per-channel templates — group several channel-specific variants under one logical content id with an author-declared fallback chain (send WhatsApp if approved, else fall back to SMS), similar to Twilio's Content API.

| Method   | Path                                             | Purpose                                             |
| -------- | ------------------------------------------------ | --------------------------------------------------- |
| `GET`    | `/api/v1/messages/content-templates`             | List content templates                              |
| `POST`   | `/api/v1/messages/content-templates`             | Create one                                          |
| `GET`    | `/api/v1/messages/content-templates/{id}`        | Get one                                             |
| `PATCH`  | `/api/v1/messages/content-templates/{id}`        | Update one                                          |
| `DELETE` | `/api/v1/messages/content-templates/{id}`        | Delete one                                          |
| `GET`    | `/api/v1/messages/content-templates/{id}/render` | Preview the rendered output for a channel (no send) |

## Cross-campaign analytics

`GET /api/v1/templates/{id}/analytics` returns the consolidated engagement rollup for a template reused across many campaigns — sent / delivered / read / click counts aggregated across every campaign that used it, rather than the per-campaign view alone.

```bash theme={null}
curl -X GET "https://api.orbit.devotel.io/api/v1/templates/tpl_9f8e7d6c5b4a/analytics" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

The response contains four groups of fields:

* `template` — the template's id, name, channel, and current approval status. A `404` here means the id does not exist in your tenant.
* `totals` — engagement counters aggregated across every campaign that referenced the template: `sent`, `delivered`, `failed`, `opened`, `clicked`.
* `rates` — the derived funnel: `delivery_rate` (delivered over terminal messages), `open_rate` (opened over delivered), and `click_rate` (clicked over delivered). Rates are fractions rounded to two decimals, e.g. `0.42` for 42%.
* `campaigns` — the per-campaign breakdown, one entry per campaign that used the template with its own counters and status, so a strong- or weak-performing campaign is visible against the rollup.

A `degraded: true` flag on the response means the live per-message scan timed out and the numbers were read from denormalized campaign counters instead — the totals remain correct for campaigns that have run, but very recent sends may not be reflected yet.

## See also

* [WhatsApp templates & the 24-hour window](/guides/whatsapp/24h-window) — when a template send is required vs. optional
* [WhatsApp getting started](/guides/whatsapp/getting-started) — template approval turnaround and rejection causes
* [Messaging API](/api-reference/endpoints/messaging) — sending a message that references a template
