# List WhatsApp Templates

> List a WhatsApp number's message templates, with each one's status and what a send must fill in, through GET /v1/agents/{agentId}/connections/{connectionId}/whatsapp-templates, before sending one with the Mojeeb Public API.

Before you send a template, list the WhatsApp number's templates. You get each template's exact name and language, whether Meta approved it, and what a send must fill in, read live from Meta, so you never have to guess a name or read `available_templates` off a failed send.

## How do I list a number's templates?

First find the number's connection: list the agent's connections with `GET /v1/agents/{agentId}/connections` and take the `id` of the one whose `platform` is `whatsapp` (see [Channels and Follow-ups](../agents/channels-and-follow-ups)). Then call:

```bash
curl https://api.mojeeb.app/v1/agents/YOUR_AGENT_ID/connections/YOUR_CONNECTION_ID/whatsapp-templates \
  -H "Authorization: Bearer mk_live_YOUR_KEY_HERE"
```

You get one item per language version of each template, sorted by name and then language. Every field is in the [List a WhatsApp number's templates reference](../api-reference/list-whats-app-templates).

## Which templates can I send?

Only those with `status: approved`. Templates in every other status, such as `pending`, `rejected`, `paused` and `disabled`, are listed too, so you can see why one isn't going out; a rejected one carries Meta's reason in `rejected_reason`. Each language version is its own item with its own status, so a template can be approved in one language and still pending in another.

Mojeeb doesn't stop you from sending a template that isn't approved: the send is accepted and then fails at Meta. Check the status here first.

## How do I turn a listed template into a send?

Copy what the list says into [`POST /v1/whatsapp/templates`](./send-template):

- `name` and `language` become `template.name` and `template.language`.
- `body.parameters` are the keys of `template.parameters`, and a text header's `header.parameters` are the keys of `template.header_parameters`. Every key needs a value.
- An image, video or document header takes an optional `template.header_media_url`.
- Each button with a `send_field` becomes one entry of `template.buttons`: its `index`, plus its value in the field that `send_field` names. You can leave out a button whose `required` is `false`.

For example, a template whose body has two numbered placeholders and whose first button is a URL with a placeholder:

```bash
curl -X POST https://api.mojeeb.app/v1/whatsapp/templates \
  -H "Authorization: Bearer mk_live_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "12345678-1234-1234-1234-123456789012",
    "from":     "+15557654321",
    "to":       "+15551234567",
    "template": {
      "name":       "order_shipped",
      "language":   "en_US",
      "parameters": { "1": "Sara", "2": "EG-A12345" },
      "buttons":    [ { "index": 0, "url_suffix": "orders/A12345" } ]
    }
  }'
```

`from` is the WhatsApp number as a `+` followed only by digits, such as `+15557654321`. The connection's `handle` holds the number as Meta displays it, which can include spaces or dashes (`+20 100 219 4693`): keep only the `+` and the digits, or the send answers `422 invalid_from_phone`.

## Positional or named placeholders?

`parameter_format` says which. A `positional` template has numbered placeholders such as `{{1}}`: send the keys `"1"`, `"2"` and so on, in the order `body.parameters` lists them. A `named` template has placeholders such as `{{customer_name}}`: send those names as the keys. It's null when neither the header nor the body has a placeholder.

## How often should I list templates?

Keep the list rather than reading it before every send, and read it again after your templates change. Because every call reads from Meta, this endpoint has a lower rate limit of its own, which protects the Meta quota your sends rely on; see [Rate Limits](../rate-limits).

## What can go wrong?

- `404 not_found`: the connection isn't one of the agent's, or it isn't a WhatsApp number.
- `409 connection_inactive`: the number is disconnected. Reconnect it in the dashboard.
- `409 connection_needs_reconnection`: Meta no longer accepts the number's access (it was revoked or expired, or the number left its WhatsApp Business Account). Reconnect it in the dashboard; retrying won't help.
- `503 meta_unavailable`: Meta didn't return the templates (an outage, a timeout or Meta's own rate limit). Retry with backoff.
- `429 rate_limit_exceeded`: wait as long as `Retry-After` says.

See [Errors](../errors) for the envelope and every code.

## Common questions

### Why is a template missing from the list?

A template deleted in Meta isn't listed. A new one is listed as soon as you submit it, with `status: pending`. A number with a very large library lists up to the cap on the reference page.

### Can I create or edit templates through the API?

Not yet. Create and edit them in the dashboard; see [WhatsApp Templates](/docs/channels/whatsapp-templates).

### Can every approved template be sent through the API?

Most can. Templates with a location header, carousels and limited-time offers can't be filled through the API yet.

### Does one call cover all my WhatsApp numbers?

No. Each call lists one number's templates, so call it once per WhatsApp connection.

### Which scope does it need?

`whatsapp:read`, which every key holds today; see [Authentication](../authentication).
