Skip to main content

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, sincronizar e acompanhar aprovação); o envio de mensagem a partir de um template aprovado está em Mensagem de Template. As operações usam POST /api/v1/message/SendCommand com content.type: "TEMPLATES", variando o commandType (CREATE, LIST ou SYNC). Resposta síncrona: { "packageId": "..." }; resultado via webhook.

Criar template

Com header de imagem e botão de resposta rápida:
components é um array de objetos. O antigo componentsJson (string com o JSON dentro) foi substituído e não é mais lido.
string
required
Nome do template em snake_case (minúsculas, dígitos e underscore), conforme as regras da Meta.
string
required
Locale da Meta (ex.: pt_BR, en_US).
string
required
Categoria da Meta: MARKETING, UTILITY ou AUTHENTICATION.
object[]
required
Array tipado de componentes do template. Cada item tem um type que determina a seção (HEADER, BODY, FOOTER, BUTTONS ou CAROUSEL) e os campos específicos daquela seção. A MessageFy valida a estrutura antes de repassar à Meta, recusando payloads inválidos com HTTP 400.

Componentes (components)

Cada item de components é um objeto com type discriminando a seção do template. Os valores de type são em MAIÚSCULAS.

HEADER — Cabeçalho

O conteúdo depende do format: em TEXT vai em text; em IMAGE, VIDEO ou DOCUMENT a mídia vai em example.header_handle.
string
required
Formato do cabeçalho: TEXT, IMAGE, VIDEO, DOCUMENT ou LOCATION.
string
Texto do cabeçalho. Obrigatório quando format é TEXT.
object
Exemplos exigidos pela Meta. Para TEXT, use header_text (lista de strings); para mídia, use header_handle (lista de URLs ou data URIs base64).

BODY — Corpo

Único componente obrigatório. Contém o texto principal do template com variáveis posicionais ({{1}}, {{2}}, …). Variáveis nomeadas ({{nome}}) não são aceitas.
string
required
Texto do corpo com variáveis. Em AUTHENTICATION não envie (veja abaixo).
object
Exemplos das variáveis em body_text: lista de listas (um conjunto de valores por exemplo).
boolean
Apenas em AUTHENTICATION: acrescenta ao corpo o aviso de não compartilhar o código. O texto é escrito pela Meta (localizado por idioma).
Texto puro, sem variáveis.
string
required
Texto do rodapé. Em AUTHENTICATION não envie (veja abaixo).
integer
Apenas em AUTHENTICATION: validade do código em minutos (1 a 90). A Meta transforma esse valor no texto do rodapé.

BUTTONS — Botões

Bloco de botões do template.
object[]
required
Lista de botões. Até 10 botões; máximo 2 URL e 1 PHONE_NUMBER.
Cada botão tem:
string
required
Tipo do botão: QUICK_REPLY, URL, PHONE_NUMBER, COPY_CODE ou OTP (este apenas em AUTHENTICATION).
string
Rótulo exibido no botão. Obrigatório em todos os tipos, exceto OTP (a Meta preenche um rótulo localizado).
string
Destino do botão URL. Aceita uma variável no final ({{1}}).
string
Telefone do botão PHONE_NUMBER, em formato internacional (ex.: +5511999999999).
string[]
Exemplos da variável do botão URL.
string
Como o código é entregue no botão OTP: COPY_CODE, ONE_TAP ou ZERO_TAP.
string
Pacote do app Android que recebe o código (OTP ONE_TAP/ZERO_TAP).
string
Hash de assinatura do app Android (OTP ONE_TAP/ZERO_TAP).
string
Rótulo do botão de autopreenchimento (OTP ONE_TAP/ZERO_TAP). Opcional na Meta.
Cartões de um template carrossel. A Meta exige que todos os cartões tenham a mesma estrutura.
object[]
required
Lista de cartões. Cada cartão tem components: HEADER de mídia (IMAGE ou VIDEO) + BODY e, opcionalmente, BUTTONS. A ordem da lista define a posição; card_index é opcional.

Regras de estrutura (Meta)

Templates de autenticação (AUTHENTICATION)

Na categoria AUTHENTICATION a Meta escreve o texto do template a partir do código de uso único, então as regras mudam:
  • Sem HEADER e sem CAROUSEL.
  • BODY sem text; use só add_security_recommendation (opcional).
  • FOOTER sem text; use só code_expiration_minutes (1 a 90, opcional).
  • Exatamente um BUTTONS, com um botão OTP (otp_type: COPY_CODE, ONE_TAP ou ZERO_TAP). ONE_TAP e ZERO_TAP exigem package_name e signature_hash.
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

Guarde o template.id — é o templateId usado no envio.

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

Listar templates

Webhook:
Campos de cada template: id, businessId, name, language, category, components (array tipado de componentes), status, metaStatus, qualityScore, rejectionReason, error (detalhe estruturado da rejeição), wabaId, wabaTemplateId, createdAt, updatedAt, deletedAt.
Quando os componentes de um template não puderem ser tipados (um formato novo da Meta que ainda não existe no protocolo), o template vem com components: null e um componentsError descrevendo a falha. Os demais templates da listagem vêm normais — a falha é contida no template afetado.
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.
Para buscar um template, informe templateId no LIST:
Id inexistente não é erro: a resposta vem com success: true, lista vazia e count: 0.

Sincronizar templates

Use SYNC quando o webhook de status de um template não chegou (o template parece preso em um estado antigo) ou para forçar uma reconciliação completa com a Meta. O comando pede ao provider que rebusque todos os templates e atualize status, qualidade, motivo de reprovação e componentes. Sem wabaPhoneNumberId, o SYNC varre todas as WABAs conectadas do business; com o campo, restringe à WABA desse número.
Com filtro por WABA:
string
Opcional. Restringe a sincronização à WABA associada a este número. Quando omitido, todas as WABAs conectadas do business são sincronizadas.

Webhook de resposta

O resultado chega como TEMPLATES_SYNC_RESPONSE, com contadores consolidados e o detalhe por WABA:
Campos de cada item em wabas: wabaId, success, imported, updated, unchanged, skipped, totalFromMeta e error (string | null, descreve a falha daquela WABA quando success é false).
O SYNC é a principal ferramenta de troubleshooting quando um template criado pela Meta não dispara o TEMPLATE_STATUS esperado. Rode um SYNC antes de investigar mais a fundo.

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