8. Templates (HSM)#
Templates (HSM — Highly Structured Messages) são modelos de mensagem aprovados
pela Meta. No canal oficial, um template aprovado é a única forma de iniciar
uma conversa fora da janela de 24h (após uma mensagem do contato, você tem 24h
para responder livremente; depois disso, só templates). Um template pode ter
cabeçalho, corpo com variáveis {{1}}, rodapé e botões (resposta rápida, link,
telefone).
Ciclo de vida: você cria o template → a Meta revisa (PENDING) → aprova
(APPROVED) ou rejeita (REJECTED). Você acompanha a transição pelo webhook
official.template_status. Só templates APPROVED podem ser
enviados.
Listar templates#
GET /v1/instances/{instanceId}/templates
Retorna os templates da sua WABA com o status de aprovação.
{
"templates": [
{
"id": "123456789",
"name": "confirmacao_pedido",
"language": "pt_BR",
"status": "APPROVED",
"category": "UTILITY",
"components": [
{ "type": "HEADER", "format": "TEXT", "text": "Olá {{1}}" },
{ "type": "BODY", "text": "Seu pedido {{1}} foi confirmado e chega em {{2}} dias úteis." },
{ "type": "BUTTONS", "buttons": [{ "type": "QUICK_REPLY", "text": "Acompanhar pedido" }] }
]
}
]
}
Criar template#
POST /v1/instances/{instanceId}/templates
O nome deve ser snake_case (minúsculas, números e _). A categoria é
MARKETING, UTILITY ou AUTHENTICATION. O array components segue o formato
da Graph API da Meta.
| Componente | Campos |
|---|---|
HEADER (opcional) |
format: "TEXT", text. Com variável, exige example.header_text: ["exemplo"]. Aceita no máximo uma variável ({{1}}). |
BODY (obrigatório) |
text com {{1}}, {{2}}… Com variáveis, exige example.body_text: [["ex1","ex2"]] (array aninhado). |
FOOTER (opcional) |
text. |
BUTTONS (opcional, até 3) |
buttons[]: QUICK_REPLY (text), URL (text, url), PHONE_NUMBER (text, phone_number). |
Request
{
"name": "confirmacao_pedido",
"language": "pt_BR",
"category": "UTILITY",
"components": [
{ "type": "HEADER", "format": "TEXT", "text": "Olá {{1}}", "example": { "header_text": ["Ana"] } },
{ "type": "BODY", "text": "Seu pedido {{1}} foi confirmado e chega em {{2}} dias úteis.", "example": { "body_text": [["#12345", "3"]] } },
{ "type": "FOOTER", "text": "Responda SAIR para não receber mais" },
{ "type": "BUTTONS", "buttons": [{ "type": "QUICK_REPLY", "text": "Acompanhar pedido" }] }
]
}
Response 201 — o template entra em revisão (PENDING); acompanhe pelo webhook
official.template_status.
Remover template#
DELETE /v1/instances/{instanceId}/templates/{name}
{ "deleted": true, "name": "confirmacao_pedido" }
Enviar um template aprovado#
POST /v1/instances/{instanceId}/official/send-template
Requer Idempotency-Key. É a única mensagem que abre uma conversa fora da janela
de 24h. Fora da janela, um envio livre (/messages/text) retorna
409 OUTSIDE_SERVICE_WINDOW — use este endpoint.
Request
{
"to": "5541999998888",
"template_name": "confirmacao_pedido",
"language": "pt_BR",
"components": [
{ "type": "header", "parameters": [{ "type": "text", "text": "Ana" }] },
{ "type": "body", "parameters": [{ "type": "text", "text": "#12345" }, { "type": "text", "text": "3" }] }
]
}
Response 202
{ "status": "queued", "message_id": "<uuid>", "task_id": "...", "idempotency_key": "..." }
Os parâmetros preenchem as variáveis {{n}} do template na ordem. O message_id
retornado é o UUID Catcher que aparecerá nos webhooks message.sent /
message.delivered / message.read.
Opt-out de marketing: enviar um template
category:"marketing"para um contato que optou por sair (eventoofficial.marketing_optoutcomopted_out=true) retorna409 BLOCKED_MARKETING_OPTOUT. Templatesutilityeauthenticationsempre passam, independentemente do opt-out.