Skip to main content
Modelos definem conteúdo de mensagem reutilizável. Crie e gerencie-os no painel (/templates), pela API REST (/v1/templates) ou pelo servidor MCP (templates_create / templates_update / templates_delete). Ao enviar, referencie o modelo pelo templateId em POST /v1/messages/send e passe um objeto variables com chaves correspondentes.
Página de Templates do Pilot Status

A página de Templates — gere com IA, envie para a Meta e veja status de aprovação e categoria por template.

Categorias

A categoria é definida no momento da criação e não pode ser alterada depois:
  • MARKETING — mensagens promocionais (as mais sensíveis às políticas do WhatsApp).
  • UTILITY — mensagens transacionais (atualizações de conta, alertas, lembretes).
  • OTP — mensagens de código único / de verificação.

Aprovação da Meta vs. modelos locais

  • Números oficiais (Meta): ao salvar um modelo com um número Meta selecionado, o painel pergunta se você deseja enviá-lo para revisão da Meta agora ou mantê-lo como rascunho e enviá-lo mais tarde. Uma vez enviado, categoria, idioma e status de aprovação seguem as regras da Meta. Um modelo só pode ser enviado em um número Meta depois de ter uma versão aprovada.
  • Números não oficiais (Pilot Status web): os modelos são criados localmente e são imediatamente utilizáveis — não há etapa de aprovação.
Os modelos retornados por GET /v1/templates trazem um campo source (de onde o modelo veio), um campo metaStatus (status de revisão da Meta, por exemplo PENDING, APPROVED, REJECTED) e uma flag sendable indicando se ele pode ser usado para envios agora.

Estrutura do modelo

Editor de template do Pilot Status

O editor de template — nome, mídia, corpo com {{variáveis}}, botões, categoria (OTP/Utilidade/Marketing), idioma e geração por IA.

Apenas o body é obrigatório. Valores de header de mídia: via REST passe header.url (URL http(s) pública) ou header.base64 (data URI, re-hospedado automaticamente no servidor). Via MCP apenas header.url é aceito.
Não existe header LOCATION. Também não são suportados: CATALOG/MPM, LIMITED_TIME_OFFER, preenchimento automático/one-tap/zero-tap de OTP e botões VOICE_CALL.Templates de carrossel são suportados em números Meta — categoria MARKETING, 2 a 10 cartões de mídia; veja Templates de carrossel.Botões FLOW são suportados em números Meta — eles abrem um Flow dentro da conversa. O botão amarra por flow_id, flow_name ou flow_json embutido. O ORDER_DETAILS (card de pedido itemizado) pode ser montado, pré-visualizado e salvo; a submissão à Meta é tentada na versão atual da Graph API e, quando a conta ainda não está elegível ao WhatsApp Pay, a recusa volta como um erro claro de elegibilidade em vez de um 400 críptico da Meta.Em números não oficiais (web) os templates suportam até 3 botões no total, e o preview do editor mostra exatamente como a mensagem é entregue para o número selecionado — incluindo a substituição ao vivo das {{variáveis}} com seus valores de exemplo.O parameter_format NAMED é suportado: um template criado no painel da Meta com variáveis nomeadas ({{nome_do_cliente}}) é importado com as variáveis certas e enviado com parameter_name em cada parâmetro.

Botão de pagamento PIX (PAYMENT_REQUEST)

Entrega um código PIX copia-e-cola (BR Code). É o jeito certo de mandar PIX — o COPY_CODE limita em 15 caracteres alfanuméricos, enquanto um BR Code real tem 100-400 caracteres com pontuação. O botão funciona nos dois tipos de número, com renderização diferente:
  • Números Meta (oficiais) — o card de pagamento do WhatsApp Pay (linha “Pagar com” + ícone do meio de pagamento), quando a conta tem pagamentos habilitados. Sem a habilitação, a Meta recusa o template com 100 / subcode 2388128 — a habilitação é gradual e por conta, e não há campo de API para consultar.
  • Números não oficiais (web) — entregue como um botão “Copiar código Pix” com o BR Code completo (sem limite de tamanho; validado em aparelhos reais). Ele combina normalmente com os demais botões do template, e o preview do editor mostra exatamente essa forma.
O código é um valor por envio: coloque uma variável no example do botão e passe o código real em variables na hora do envio, como qualquer outra variável.
A variável do código PIX é obrigatória no envio. Se faltar, o envio é recusado em vez de entregue: sem o parâmetro, a Meta usaria o código de amostra salvo no template, e o cliente pagaria a conta errada.

Card de pedido itemizado (orderDetails)

Um template pode carregar um card de pedido itemizado — PEDIDO #referência, itens com quantidade, a linha “Pagar com” e o total — gravado como um bloco orderDetails (order com itens/subtotal/impostos em centavos inteiros, mais paymentSettings com o meio de pagamento). Comportamento por tipo de número:
  • Meta (oficial) — o card é montado, pré-visualizado e salvo; a submissão à Meta é tentada na versão atual da Graph API e retorna um erro claro de elegibilidade quando a conta não tem WhatsApp Pay.
  • Não oficial EVO_V2 — o card é entregável hoje (review_and_pay). Quando o template também tem texto, botões ou mídia no header, eles são entregues primeiro como mensagem normal e o card de pedido vem numa segunda mensagem; se o card falhar depois da primeira mensagem entregue, o envio é marcado como falho (sem retry, pra não duplicar o texto).
  • Não oficial EVO_GO — não há card itemizado; quando o pedido tem trilho PIX, degrada para um botão “Copiar código Pix” anexado aos demais botões do template.
Variáveis no card de pedido: campos de texto (nome do item, referência, moeda) aceitam {{variáveis}} como qualquer outro campo. Campos numéricos — preço do item, quantidade, subtotal, impostos, total — também aceitam um único token {{variável}}: o exemplo precisa ser um inteiro não-negativo (em centavos), o valor real é substituído no envio, e um envio com valor numérico corrompido é recusado em vez de entregue com o valor errado.

Regras de variáveis

  • Escreva variáveis como {{name}} no body, no header de texto e em botões de URL dinâmica (por exemplo https://shop.com/promo/{{link}} — uma variável, no fim da URL, nunca no domínio).
  • O body não pode começar nem terminar com uma variável — sempre inclua texto literal em ambas as extremidades.
  • Ao criar/atualizar via API ou MCP, um objeto examples mapeando todas as variáveis a um valor de exemplo real é obrigatório. Amostras ausentes retornam 400 TEMPLATE_EXAMPLES_REQUIRED com as chaves faltantes em details.missing.
  • O valor do copy-code é a única exceção: ele vai no botão como example (por exemplo ["PROMO10"]), não em examples de nível superior. Em um número oficial esse example é só uma amostra — o código que o cliente copia vai em variables como button_<N> a cada envio (veja abaixo).
  • Ao enviar, todo marcador — incluindo chaves usadas apenas em botões — deve ser fornecido em variables, e cada valor deve ser uma string não vazia.
  • Marcadores numerados em botões (modelos criados no painel da Meta). Um modelo criado no WhatsApp Manager da Meta e sincronizado no Pilot Status (source: "META") com marcadores posicionais numera a variável de um botão de URL dinâmica por conta própria: em https://ctlnk.io/{{1}}, esse {{1}} não é o {{1}} do body. Forneça-o como variables["button_<N>"], em que N é a posição do botão na lista de botões do modelo, começando em 1 — todos os botões contam, inclusive os estáticos. Passe só a parte variável (o sufixo da URL), não a URL inteira. Um envio sem essa chave, ou com valor vazio, é recusado com 400 MISSING_TEMPLATE_VARIABLES (ou INVALID_TEMPLATE_VARIABLE_VALUE) nomeando a chave.
Para um modelo com os marcadores {{1}}, {{2}}, {{3}} no body e um único botão de URL https://ctlnk.io/{{1}}:
Marcadores nomeados não mudam: um botão criado no Pilot Status como https://shop.com/promo/{{link}} é preenchido por variables.link. Botões de copiar código em números oficiais. Para a Meta, o código digitado num botão de copiar código na criação é só um exemplo; o código que o cliente copia é um parâmetro obrigatório de todo envio. Por isso, num modelo aprovado pela Meta (source: "META" — todo modelo de um número oficial, criado no painel da Meta ou no Pilot Status), um botão de copiar código cujo valor não tem {{variável}} (um exemplo fixo como PROMO10) recebe o código como variables["button_<N>"], com a mesma regra de N. Para os botões [QUICK_REPLY, COPY_CODE] com o exemplo PROMO10:
Um envio sem essa chave, ou com valor vazio, é recusado com 400 MISSING_TEMPLATE_VARIABLES (ou INVALID_TEMPLATE_VARIABLE_VALUE) nomeando a chave. Um botão de copiar código cujo exemplo é uma variável nomeada (["{{cupom}}"]) continua sendo preenchido por variables.cupom, e o botão de código de um modelo de autenticação (OTP) continua recebendo o código do body. Em números não oficiais (web/QR) o código também é por envio: escreva-o no botão como {{variável}} e preencha em variables.

Formatação de texto

Marcadores de formatação do WhatsApp funcionam no body: *bold*, _italic_, ~strikethrough~, monospace. O header de texto não permite marcadores de formatação, emojis nem quebras de linha.

API de Modelos

Uma criação bem-sucedida retorna 201:
Após salvar, GET /v1/templates/{id} retorna todas as chaves de variáveis detectadas no array variables de nível superior (plano). Para um modelo criado no painel da Meta com marcador numerado em botão, o array também lista a chave button_<N> do botão (ex.: ["1", "2", "3", "button_1"]), e num número oficial lista a chave de um botão de copiar código sem {{variável}} — button_3 para o promo_coupon acima — forneça no envio todas as chaves que ele lista.

Erros comuns de envio e submissão

Um 404 ao enviar significa que o modelo não existe para a chave ou — em um número Meta — ainda não tem uma versão aprovada.

Relacionados