> ## Documentation Index
> Fetch the complete documentation index at: https://developers.datafyapi.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Criar template

> Espelho de `POST /{waba_id}/message_templates` da Meta Cloud API. O template é enviado para análise da Meta.

Cria um template e o envia para análise da Meta. O template é criado com status `PENDING` e só pode ser utilizado em envios após ser aprovado. A resposta retorna o `id` do template:

```json theme={null}
{ "id": "5400801403478858", "status": "PENDING", "category": "UTILITY" }
```

A alteração de status é informada pelo webhook [`message_template_status_update`](https://developers.datafyapi.com.br/api-reference/whatsapp/webhooks/eventos/templates), o que dispensa a consulta periódica à listagem.

## Nome

O nome identifica o template no envio e aceita apenas letras minúsculas, números e sublinhado, sem espaços e sem acentos:

```text Aceito theme={null}
pedido_pronto
retirada_equipamento_2
```

```text Recusado theme={null}
Pedido Pronto
retirada-equipamento
```

O mesmo nome pode existir em vários idiomas, e cada idioma é analisado separadamente. A combinação de nome e idioma não pode ser repetida.

## Categoria

| Categoria | Finalidade |
| - | - |
| `UTILITY` | Mensagens referentes a uma transação existente: confirmação de pedido, aviso de entrega, cobrança |
| `MARKETING` | Ofertas, novidades, convites e demais conteúdos promocionais |
| `AUTHENTICATION` | Códigos de verificação |

A categoria determina o preço e as regras de envio. As definições estão na [visão geral de templates da Meta](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/overview), e as regras específicas de marketing em [templates de marketing personalizados](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/marketing-templates/custom-marketing-templates).

> [!WARNING]
>
> A Meta reclassifica o template quando o conteúdo não corresponde à categoria informada. Um conteúdo promocional enviado como `UTILITY` é convertido para `MARKETING`. Se já existir uma versão daquele template em outra categoria, a criação falha com "A categoria MARKETING não corresponde à categoria já associada a este modelo, UTILITY".

## Componentes

O corpo (`BODY`) é obrigatório. Cabeçalho (`HEADER`), rodapé (`FOOTER`) e botões (`BUTTONS`) são opcionais.

```json theme={null}
{
  "name": "retirada_equipamento",
  "language": "pt_BR",
  "category": "UTILITY",
  "components": [
    {
      "type": "BODY",
      "text": "Olá, {{1}}. O equipamento da ordem de serviço {{2}} está pronto para retirada.",
      "example": { "body_text": [["Rafael", "7539"]] }
    },
    { "type": "FOOTER", "text": "Assistência Técnica Datafy" }
  ]
}
```

> [!TIP]
>
> Para cabeçalho com imagem, vídeo ou documento, a Meta exige um `header_handle` no lugar da URL. Gere esse valor com [Gerar handle de arquivo](https://developers.datafyapi.com.br/api-reference/whatsapp/datafy/gerar-handle-de-arquivo.md).

## Variáveis posicionais ou nomeadas

As variáveis do template podem ser numeradas ou identificadas por nome. O formato é definido pelo campo `parameter_format`, que assume `POSITIONAL` quando não é informado.

```json Posicional theme={null}
{
  "parameter_format": "POSITIONAL",
  "components": [
    {
      "type": "BODY",
      "text": "Olá, {{1}}. O equipamento da ordem de serviço {{2}} está pronto para retirada.",
      "example": { "body_text": [["Rafael", "7539"]] }
    }
  ]
}
```

```json Nomeado theme={null}
{
  "parameter_format": "NAMED",
  "components": [
    {
      "type": "BODY",
      "text": "Olá, {{nome}}. O equipamento da ordem de serviço {{numero_os}} está pronto para retirada.",
      "example": {
        "body_text_named_params": [
          { "param_name": "nome", "example": "Rafael" },
          { "param_name": "numero_os", "example": "7539" }
        ]
      }
    }
  ]
}
```

As diferenças entre os dois formatos:

| | Posicional | Nomeado |
| - | - | - |
| `parameter_format` | `POSITIONAL` (padrão) | `NAMED` |
| Marcação no texto | `{{1}}`, `{{2}}` | `{{nome}}`, `{{numero_os}}` |
| Campo do exemplo | `body_text` | `body_text_named_params` |
| Ordem no envio | Os valores seguem a numeração | Cada valor indica o `parameter_name` correspondente |

Os nomes de parâmetro aceitam apenas letras minúsculas, números e sublinhado. Os dois formatos não podem ser combinados no mesmo template: um texto com `{{nome}}` e `{{1}}` é aceito na criação e reprovado na análise.

> [!NOTE]
>
> O formato escolhido na criação determina como as variáveis são preenchidas no envio, descrito em [Enviar template](https://developers.datafyapi.com.br/api-reference/whatsapp/templates/enviar-template.md).

## Exemplo das variáveis

Toda variável precisa de um valor de exemplo, utilizado na análise do template. O comportamento difere conforme o formato:

* No formato nomeado, a ausência de `body_text_named_params` retorna `HTTP 400` com a mensagem "o componente do tipo BODY não contém o(s) campo(s) esperado(s) (example)".
* No formato posicional, a ausência de `body_text` não gera erro na requisição: a resposta é `HTTP 200`, o template é criado e passa para `REJECTED`, com `rejected_reason` igual a `INVALID_FORMAT`.

```json Com exemplo theme={null}
{
  "type": "BODY",
  "text": "Olá, {{1}}. Seu pedido {{2}} foi enviado.",
  "example": { "body_text": [["Rafael", "7539"]] }
}
```

```json Reprovado na análise theme={null}
{
  "type": "BODY",
  "text": "Olá, {{1}}. Seu pedido {{2}} foi enviado."
}
```

Um template reprovado pode ser corrigido em [Editar template](https://developers.datafyapi.com.br/api-reference/whatsapp/templates/editar-template.md), sem necessidade de outro nome.

## Erros comuns

A Meta retorna a descrição em `error_user_msg`, em português:

| Situação | Mensagem da Meta |
| - | - |
| Nome com maiúscula, espaço ou hífen | "O nome do modelo de mensagem só pode ter letras minúsculas e sublinhados." |
| Nome e idioma já utilizados | "Já existe conteúdo em Portuguese (BR) para esse modelo. Você pode criar um novo modelo e tentar novamente." |
| Categoria diferente da já registrada | "A categoria MARKETING não corresponde à categoria já associada a este modelo, UTILITY." |
| Exemplo ausente ou incompatível com o formato das variáveis | "o componente do tipo BODY não contém o(s) campo(s) esperado(s) (example)" |

As regras de formato e os limites de cada componente estão em [gerenciamento de templates da Meta](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/template-management).


## OpenAPI

````yaml api-reference/whatsapp/openapi.json POST /v1/{waba_id}/message_templates
openapi: 3.1.0
info:
  title: Datafy API — WhatsApp
  version: 1.0.0
  description: Espelho da Meta Cloud API e endpoints próprios da Datafy.
servers:
  - url: https://cloud.datafyapi.com.br
    description: Produção
security:
  - bearerAuth: []
tags:
  - name: Templates
  - name: Mídia
  - name: Datafy
paths:
  /v1/{waba_id}/message_templates:
    post:
      tags:
        - Templates
      summary: Criar template
      description: >-
        Espelho de `POST /{waba_id}/message_templates` da Meta Cloud API. O
        template é enviado para análise da Meta.
      operationId: criarTemplate
      parameters:
        - $ref: '#/components/parameters/WabaId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplateCreate'
            examples:
              utilidade:
                summary: Utilidade com variáveis
                value:
                  name: pedido_pronto
                  language: pt_BR
                  category: UTILITY
                  components:
                    - type: BODY
                      text: >-
                        Olá, {{1}}. O equipamento da ordem de serviço {{2}} está
                        pronto para retirada.
                      example:
                        body_text:
                          - - Rafael
                            - '7539'
              marketing_imagem:
                summary: Marketing com imagem e botão
                value:
                  name: oferta_semana
                  language: pt_BR
                  category: MARKETING
                  components:
                    - type: HEADER
                      format: IMAGE
                      example:
                        header_handle:
                          - 4::aW1hZ2UvanBlZw==:ARb...
                    - type: BODY
                      text: >-
                        Olá, {{1}}! Use o cupom {{2}} e aproveite até
                        sexta-feira.
                      example:
                        body_text:
                          - - Camila
                            - PASSOLEVE
                    - type: BUTTONS
                      buttons:
                        - type: URL
                          text: Ver oferta
                          url: https://exemplo.com/oferta
              nomeado:
                summary: Variáveis nomeadas
                value:
                  name: retirada_equipamento
                  language: pt_BR
                  category: UTILITY
                  parameter_format: NAMED
                  components:
                    - type: BODY
                      text: >-
                        Olá, {{nome}}. O equipamento da ordem de serviço
                        {{numero_os}} está pronto para retirada.
                      example:
                        body_text_named_params:
                          - param_name: nome
                            example: Rafael
                          - param_name: numero_os
                            example: '7539'
      responses:
        '200':
          description: Template criado e enviado para análise.
          content:
            application/json:
              example:
                id: '5400801403478858'
                status: PENDING
                category: UTILITY
        '400':
          $ref: '#/components/responses/MetaError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      externalDocs:
        description: Referência de templates da Meta
        url: >-
          https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates
components:
  parameters:
    WabaId:
      name: waba_id
      in: path
      required: true
      schema:
        type: string
      description: ID da conta do WhatsApp Business. Descubra com `GET /me`.
  schemas:
    TemplateCreate:
      type: object
      required:
        - name
        - language
        - category
        - components
      properties:
        name:
          type: string
          description: >-
            Nome do template, em letras minúsculas e com `_` no lugar de
            espaços.
        language:
          type: string
          description: Código do idioma, como `pt_BR`.
        category:
          type: string
          enum:
            - MARKETING
            - UTILITY
            - AUTHENTICATION
        parameter_format:
          type: string
          enum:
            - POSITIONAL
            - NAMED
          default: POSITIONAL
          example: POSITIONAL
          description: >-
            Formato das variáveis: `POSITIONAL` usa `{{1}}`, `{{2}}`; `NAMED`
            usa `{{nome}}` e exige `body_text_named_params` no exemplo.
        components:
          type: array
          description: Cabeçalho, corpo, rodapé e botões do template.
          items:
            type: object
    MetaError:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
            type:
              type: string
            code:
              type: integer
            error_subcode:
              type: integer
            fbtrace_id:
              type: string
    DatafyError:
      type: object
      properties:
        statusCode:
          type: integer
        message:
          type: string
  responses:
    MetaError:
      description: Erro retornado pela Meta, repassado sem alteração.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/MetaError'
          example:
            error:
              message: (#131030) Recipient phone number not in allowed list
              type: OAuthException
              code: 131030
              fbtrace_id: AbCdEfGhIjK
    Unauthorized:
      description: Token ausente ou inválido.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatafyError'
          example:
            statusCode: 401
            message: Token inválido ou não encontrado.
    PaymentRequired:
      description: Assinatura da Datafy inativa.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatafyError'
          example:
            statusCode: 402
            message: >-
              Assinatura inativa. Ative sua assinatura no painel para voltar a
              usar a API.
    TooManyRequests:
      description: Limite de requisições excedido.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatafyError'
          example:
            statusCode: 429
            message: Rate limit excedido (60 req/min). Tente novamente em 12s.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Token gerado no painel da Datafy ao criar o canal. Formato:
        `sk_live_xxx`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.