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

# Gerenciar Templates

> Crie e liste templates do WhatsApp Oficial e acompanhe a aprovação pela Meta

# Gerenciar Templates

No canal do WhatsApp Oficial, conversas só podem ser **iniciadas** com um template **aprovado pela Meta**. Esta página cobre a **gestão** (criar, listar e acompanhar aprovação); o **envio** de mensagem a partir de um template aprovado está em [Mensagem de Template](/mensagens/template).

As operações usam `POST /api/v1/message/SendCommand` com `content.type: "TEMPLATES"`, variando o `commandType` (`CREATE` ou `LIST`). Resposta síncrona: `{ "packageId": "..." }`; resultado via webhook.

## Criar template

```json theme={null}
{
  "channelId": "uuid-do-canal-oficial",
  "correlationId": "template-boas-vindas",
  "content": {
    "type": "TEMPLATES",
    "commandType": "CREATE",
    "name": "boas_vindas_cliente",
    "language": "pt_BR",
    "category": "UTILITY",
    "componentsJson": "[{\"type\":\"HEADER\",\"format\":\"TEXT\",\"text\":\"Olá, {{1}}!\",\"example\":{\"header_text\":[\"João\"]}},{\"type\":\"BODY\",\"text\":\"Seu pedido {{1}} foi confirmado e será entregue em até {{2}} dias úteis.\",\"example\":{\"body_text\":[[\"10245\",\"3\"]]}},{\"type\":\"FOOTER\",\"text\":\"Loja do João\"},{\"type\":\"BUTTONS\",\"buttons\":[{\"type\":\"URL\",\"text\":\"Acompanhar pedido\",\"url\":\"https://lojadojoao.com.br/pedidos/{{1}}\",\"example\":[\"10245\"]}]}]"
  }
}
```

<ParamField body="content.name" type="string" required>
  Nome do template em `snake_case` (minúsculas, dígitos e underscore), conforme as regras da Meta.
</ParamField>

<ParamField body="content.language" type="string" required>
  Locale da Meta (ex.: `pt_BR`, `en_US`).
</ParamField>

<ParamField body="content.category" type="string" required>
  Categoria da Meta: `MARKETING`, `UTILITY` ou `AUTHENTICATION`.
</ParamField>

<ParamField body="content.componentsJson" type="string" required>
  Estrutura dos componentes do template como **string JSON** (o array de componentes serializado).
  A MessageFy repassa o conteúdo de forma opaca à Meta, sem interpretar nem validar — monte-o
  seguindo o formato de componentes da WhatsApp Business Platform.
</ParamField>

<Warning>
  O campo é `componentsJson` e o valor é uma **string** contendo o JSON dos componentes — não um
  array. Enviar um array diretamente causa erro de desserialização (`400`).
</Warning>

### Regras de estrutura (Meta)

| Regra        | Detalhe                                                                   |
| ------------ | ------------------------------------------------------------------------- |
| `components` | Exatamente um `BODY`; no máximo um de cada: `HEADER`, `FOOTER`, `BUTTONS` |
| Variáveis    | Toda `{{n}}` exige o `example` correspondente                             |
| `FOOTER`     | Não aceita variáveis                                                      |
| `BUTTONS`    | Até 10 botões; máximo 2 `URL` e 1 `PHONE_NUMBER`                          |

Header com mídia: para `format` `IMAGE`, `VIDEO` ou `DOCUMENT`, informe a mídia em `example.header_handle` — URL pública `http(s)` ou data URI base64. Com data URI, a MessageFy sobe o arquivo para o storage e o substitui pela URL pública antes de enviar à Meta.

### Webhook de resposta

```json theme={null}
{
  "correlationId": "template-boas-vindas",
  "content": {
    "type": "TEMPLATES_CREATE_RESPONSE",
    "commandType": "TEMPLATES_CREATE_RESPONSE",
    "success": true,
    "template": {
      "id": "7b3f9c21-4d18-4a6e-90f2-1c5e8a7b4d03",
      "name": "boas_vindas_cliente",
      "language": "pt_BR",
      "category": "UTILITY",
      "status": "Pending",
      "wabaId": "104857392019283",
      "createdAt": "2026-08-19T14:20:44Z"
    }
  }
}
```

Guarde o `template.id` — é o `templateId` usado no [envio](/mensagens/template).

## Acompanhar a aprovação (TEMPLATE\_STATUS)

A decisão da Meta chega **de forma espontânea** (pode levar horas ou dias) pelo evento `TEMPLATE_STATUS`:

```json theme={null}
{
  "channelId": "uuid-do-canal-de-feedback",
  "content": {
    "type": "TEMPLATE_STATUS",
    "templateId": "7b3f9c21-4d18-4a6e-90f2-1c5e8a7b4d03",
    "providerTemplateId": "1523498712340987",
    "name": "boas_vindas_cliente",
    "wabaId": "104857392019283",
    "status": "APPROVED",
    "reason": null
  }
}
```

| Campo                | Tipo           | Descrição                                                                                                            |
| -------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------- |
| `templateId`         | string         | Id do template na MessageFy (o elo com o CREATE original)                                                            |
| `providerTemplateId` | string         | Id do template no provedor (waba\_template\_id)                                                                      |
| `name`               | string         | Nome do template                                                                                                     |
| `wabaId`             | string         | WABA dona do template                                                                                                |
| `status`             | string         | Estado em **MAIÚSCULAS**, exatamente como a Meta enviou (`APPROVED`, `REJECTED`, `PENDING`, `PAUSED`, `DISABLED`, …) |
| `reason`             | string \| null | Motivo, quando há (ex.: `INVALID_FORMAT`)                                                                            |

<Note>
  `TEMPLATE_STATUS` é um evento **da conta**, não de um número: a mesma WABA pode ter vários
  canais. Ele é entregue no canal de feedback do Router e **não** carrega
  `correlationId`/`originPackageId` — correlacione pelo `templateId`. O conjunto de status é
  governado pela Meta: compare por igualdade e trate valores desconhecidos como um estado novo,
  não como erro.
</Note>

## Listar templates

```json theme={null}
{
  "channelId": "uuid-do-canal-oficial",
  "content": { "type": "TEMPLATES", "commandType": "LIST" }
}
```

Webhook:

```json theme={null}
{
  "content": {
    "type": "TEMPLATES_LIST_RESPONSE",
    "commandType": "TEMPLATES_LIST_RESPONSE",
    "success": true,
    "count": 2,
    "templates": [
      {
        "id": "7b3f9c21-4d18-4a6e-90f2-1c5e8a7b4d03",
        "name": "boas_vindas_cliente",
        "language": "pt_BR",
        "category": "UTILITY",
        "status": "Approved",
        "components": "[{\"type\":\"BODY\",\"text\":\"Seu pedido {{1}} foi confirmado...\"}]",
        "wabaId": "104857392019283",
        "createdAt": "2026-08-19T14:20:44Z"
      },
      {
        "id": "a1c2e3f4-5b6d-4e7f-8a90-1b2c3d4e5f60",
        "name": "promo_black_friday",
        "language": "pt_BR",
        "category": "MARKETING",
        "status": "Rejected",
        "rejectionReason": "INVALID_FORMAT: o texto contém formatação não permitida"
      }
    ]
  }
}
```

Campos de cada template: `id`, `whatsAppNumberId`, `name`, `language`, `category`, `components` (string JSON, como devolvida pelo provedor), `status`, `rejectionReason`, `wabaId`, `wabaTemplateId`, `createdAt`, `updatedAt`.

<Note>
  O `LIST` devolve **todos os templates do business** (todos os números da WABA), não apenas os
  do número deste canal — o canal do pacote define de qual business vêm as credenciais. Filtre do
  seu lado se precisar. Não há filtro por número.
</Note>

Para buscar **um** template, informe `templateId` no LIST:

```json theme={null}
{
  "channelId": "uuid-do-canal-oficial",
  "content": { "type": "TEMPLATES", "commandType": "LIST", "templateId": "7b3f9c21-4d18-4a6e-90f2-1c5e8a7b4d03" }
}
```

<Note>
  Id inexistente **não é erro**: a resposta vem com `success: true`, lista vazia e `count: 0`.
</Note>

## Motivos comuns de rejeição

A Meta rejeita templates por, entre outros: formatação inválida (`INVALID_FORMAT`), conteúdo que viola as políticas do WhatsApp, categoria incorreta para o conteúdo, variáveis sem exemplo, uso de conteúdo promocional em categoria `UTILITY`/`AUTHENTICATION`, links encurtados/suspeitos e nomes de template enganosos. Corrija e crie um novo template (não é possível editar um rejeitado).
