Skip to main content
Templates definem conteúdo de mensagem reutilizável. Crie e gerencie-os no painel (/templates) ou via API REST pública (/v1/templates) e o servidor MCP (templates_create / templates_update / templates_delete). Ao enviar, referencie o template pelo templateId e passe um objeto variables com chaves correspondentes.
Modal de envio de template via API com curl pronto

Todo template tem uma chamada de API pronta — o modal "Enviar via API" do editor gera o curl exato com o templateId.

Todas as requisições usam o header x-api-key: ps_... (ou x-api-key-id). URL base: https://pilotstatus.com.br/v1.

Categoria

Definida no momento da criação; não pode ser alterada depois.
  • MARKETING — mensagens promocionais (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.

Estrutura do template

Apenas o body é obrigatório.
  • API REST: passe header.url (URL http(s) pública) ou header.base64 (data URI) — o base64 é re-hospedado no servidor automaticamente.
  • MCP: header.url apenas — base64 não é suportado via MCP.
Não existe header LOCATION.

Body

  • Até 1024 caracteres.
  • Variáveis escritas como {{nome}} (estilo nomeado).
  • O body não pode começar nem terminar com uma variável.
  • Emojis e múltiplas variáveis são permitidos.
Texto estático de até 60 caracteres. Sem variáveis.

Buttons

Até 10 botões no total; botões de resposta rápida e CTA podem ser combinados.
  • Botão de URL dinâmica: a URL termina com uma variável (ex.: https://loja.com/promo/{{link}}) — no máximo uma variável, nunca no domínio. O valor de exemplo vai em examples.
  • Copy-code: o valor vai no botão como example (array, ex.: ["PROMO10"]), somente alfanumérico, até 15 caracteres. Não serve para chave PIX ou e-mail — para PIX use o botão PAYMENT_REQUEST abaixo.

Botão de pagamento PIX (PAYMENT_REQUEST)

Botão de pagamento do WhatsApp Pay Brasil: o cliente toca e copia o código PIX. É o caminho certo para PIX copia-e-cola — o COPY_CODE trava em 15 caracteres alfanuméricos e um BR Code tem 100-400 caracteres com pontuação. O código é por envio: escreva uma variável no example do botão e mande o valor real em variables no envio, como qualquer outra variável.
Esse botão depende de a Meta ter liberado pagamentos para a sua WhatsApp Business Account. A liberação é gradual e por conta — a própria Meta diz “this feature is rolling out and might not be available yet for your WhatsApp Business account”. Numa conta sem liberação, a Meta recusa a criação do template com 100 / subcode 2388128 (“Button at index 0 has unexpected type (PAYMENT_REQUEST)”). Não há como consultar essa permissão pela API — só tentando criar.
Ao enviar, a variável do código PIX é obrigatória. Se ela faltar, o envio é recusado em vez de seguir: sem o parâmetro a Meta usaria o código de exemplo cadastrado no template, e o cliente pagaria para a conta errada.
ORDER_DETAILS — o botão de pagamento legado da Meta — não é suportado. Ele exige a API de Pedidos (order details) completa. Use PAYMENT_REQUEST.
  • Botões são permitidos junto com um header de vídeo ou documento (PDF).

Variáveis & examples (obrigatório)

Ao criar/atualizar via REST ou MCP você deve incluir um objeto examples mapeando cada variável usada (body + texto do header + URL dinâmica) para um valor de exemplo real. O valor do copy-code é a única exceção (ele fica no botão).
Após salvar, GET /v1/templates/{id} retorna todas as chaves detectadas no array variables de nível superior (um string[]) — forneça todas elas em variables no envio. Não há objeto latestVersion na resposta da API pública.

Limites de caracteres

Criar via API REST

  • body pode ser um objeto (recomendado), uma string JSON ou texto simples (templates só de body).
  • Edite com PUT /v1/templates/{id} (mesmo formato); remova com DELETE /v1/templates/{id} — para um template Meta isso também pede à Meta para excluí-lo, e a resposta depende do que a Meta faz (veja Excluir).
  • GET /v1/templates / GET /v1/templates/{id} retornam source (META | PILOT_STATUS), metaStatus (APPROVED | PENDING | REJECTED | DISABLED | null), metaLanguage e sendable — em um número Meta apenas templates META com metaStatus: "APPROVED" são enviáveis.

Excluir

DELETE /v1/templates/{id} não retorna mais sucesso sempre. Para um template Meta a exclusão é encaminhada à Meta, e o resultado depende do que a Meta faz:
  • Um 200 { "deleted": true, "id" } é a única resposta que significa que o template realmente sumiu — removido na Meta e localmente.
  • Um 409 significa que nada foi removido: a Meta rejeitou a exclusão (ex.: o system token não tem permissão na WABA), então o template ainda existe na Meta e o nome dele continua reservado. O registro local é mantido, e a mensagem nomeia o template e o motivo. Corrija a permissão e tente de novo.
  • Se a Meta informar que o template não existe (um 404 de verdade / “template does not exist”), o registro local obsoleto é removido e você ainda recebe 200 { "deleted": true, "id" }.

Templates de carrossel

Um template de carrossel é um template aprovado cujo body carrega um bloco carousel: uma faixa rolável na horizontal com 2 a 10 cartões de mídia, cada um com sua própria imagem, linha de texto e botões. Templates de carrossel são exclusivos de números Meta e sempre da categoria MARKETING — em um número Meta a criação é enviada à Meta como um componente CAROUSEL. Diferente do carrossel de sessão (interativo, somente resposta rápida — um botão de URL ali retorna 400), um cartão de carrossel de template pode combinar botões QUICK_REPLY e URL no mesmo cartão. Ele fica dentro de body, ao lado de body.text — a mensagem exibida acima dos cartões (o corpo do carrossel).

Limites (validados na criação e na atualização)

Os mesmos limites e regras de mídia valem para POST (criar) e PUT (atualizar) — a validação não é mais pulada. Mídia do cartão — cada card.media.url deve ser uma URL https pública terminada em .png, .jpg, .jpeg ou .webp, sem query string. A Meta aceita uma imagem inacessível com 200 e depois não entrega nada, então a URL é buscada e recusada antes do envio, com um erro tipado que nomeia o cartão problemático.
Um header de nível superior não é permitido com carousel (a mídia fica em cada cartão), e os botões dos cartões substituem os buttons de nível superior.

Criar um template de carrossel

Aqui todo cartão repete o par QUICK_REPLY + URL declarado em cardTemplate.buttons, nessa ordem. Um cartão que omite um botão, troca a ordem ou muda um tipo é recusado antes do envio.

Aprovação

  • Números Meta: os templates são enviados à Meta para revisão (“Submit to Meta” em /templates, ou ao salvar). Categorias, idioma e status seguem as regras da Meta.
  • Números não oficiais (Pilot Status web): os templates são criados localmente e ficam imediatamente utilizáveis — sem etapa de aprovação.

Não suportado

FLOW, LOCATION (header ou botão), CATALOG/MPM, LIMITED_TIME_OFFER, OTP autofill/one-tap/zero-tap, botões VOICE_CALL e ORDER_DETAILS (botão de pagamento legado — use PAYMENT_REQUEST). (O carousel de sessão — a variante fora de template — está na referência de Enviar mensagem.) 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.

Erros de envio & rejeição

Botões de link/URL aceitam uma única variável que deve estar no final da URL e nunca no domínio; botões de chamada precisam do código do país (ex.: +55).

Verificado antes de enviar à Meta

Validação do lado da API

A Meta rejeitou o envio

Rejeitado após revisão

Bloqueios ao enviar (mesmo aprovado)

Erro comum ao enviar

404 — template sem uma versão aprovada (não existe para a chave, ou o template Meta ainda não tem versão aprovada).