Atualizado em 20/10/2026
Mensagens interativas são envios com type: "interactive" que mostram ao usuário botões de resposta (até 3), uma lista (até 10 opções), um botão de link, um pedido de localização, um carrossel ou um WhatsApp Flow; quando ele toca, o webhook devolve o id que você definiu. São mensagens de serviço, portanto só podem ser enviadas com a janela de 24 horas aberta. Para iniciar uma conversa com botões ou Flow, use um template.
Abaixo estão os payloads de cada tipo, os limites de caracteres, o formato da resposta no webhook e um roteador em Node.js para tratar tudo. Os exemplos usam a Vectalk (https://apis.vectalk.com.br/api/messages), que aceita o mesmo corpo da Cloud API da Meta.
Visão geral dos tipos
| Tipo | interactive.type | Limites principais | O que volta no webhook |
|---|---|---|---|
| Botões de resposta | button | Até 3 botões; rótulo de 20 caracteres; corpo de 1.024 | interactive.button_reply com id e title |
| Lista | list | Até 10 seções e 10 linhas no total; botão de 20 caracteres | interactive.list_reply com id, title e description |
| Botão de link | cta_url | 1 botão; rótulo de 20 caracteres | Nada (abre o navegador) |
| Pedido de localização | location_request_message | Corpo de 1.024 caracteres | Mensagem type: "location" |
| Carrossel de mídia | carousel | De 2 a 10 cartões com imagem ou vídeo | Depende do botão usado |
| Flow | flow | flow_message_version igual a "3" | interactive.nfm_reply com response_json |
| Produto e multiproduto | product, product_list | Ligados a um catálogo | Pedido (type: "order") |
Mídia simples (imagem, vídeo, documento, áudio) e localização fixa não são interativas, mas costumam aparecer nos mesmos fluxos e também estão neste guia.
Botões de resposta
O formato mais usado para confirmar, escolher entre poucas opções ou desviar para um atendente.
curl -X POST https://apis.vectalk.com.br/api/messages \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messaging_product": "whatsapp",
"to": "5584999999999",
"type": "interactive",
"interactive": {
"type": "button",
"header": { "type": "text", "text": "Consulta de amanhã" },
"body": { "text": "Olá, Marina. Sua consulta está marcada para 21/10 às 9h. Você confirma?" },
"footer": { "text": "Clínica Exemplo" },
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "confirmar_8812", "title": "Confirmar" } },
{ "type": "reply", "reply": { "id": "remarcar_8812", "title": "Remarcar" } },
{ "type": "reply", "reply": { "id": "atendente", "title": "Falar com alguém" } }
]
}
}
}'
Regras da Meta para esse tipo:
- até 3 botões, com rótulos únicos de até 20 caracteres;
idde até 256 caracteres;- corpo de até 1.024 caracteres e rodapé de até 60;
- cabeçalho opcional de texto, imagem, vídeo ou documento.
Use o id para carregar contexto. No exemplo, confirmar_8812 já diz a ação e o agendamento, e o webhook não depende do texto do botão. Quando o usuário toca, chega:
"interactive": {
"type": "button_reply",
"button_reply": { "id": "confirmar_8812", "title": "Confirmar" }
}
Lista interativa
Para mais de três opções: cardápio, horários, departamentos, planos. O usuário toca no botão e abre um painel com as linhas.
{
"messaging_product": "whatsapp",
"to": "5584999999999",
"type": "interactive",
"interactive": {
"type": "list",
"header": { "type": "text", "text": "Horários disponíveis" },
"body": { "text": "Escolha um horário para a sua visita técnica." },
"footer": { "text": "Horário de Brasília" },
"action": {
"button": "Ver horários",
"sections": [
{
"title": "Quarta, 22/10",
"rows": [
{ "id": "slot_2210_09", "title": "09:00", "description": "Técnico disponível" },
{ "id": "slot_2210_14", "title": "14:00", "description": "Técnico disponível" }
]
},
{
"title": "Quinta, 23/10",
"rows": [
{ "id": "slot_2310_10", "title": "10:00" }
]
}
]
}
}
}
| Campo | Limite |
|---|---|
action.button | 20 caracteres, um botão |
| Seções | Até 10, título de até 24 caracteres |
| Linhas | Até 10 somando todas as seções |
rows[].title | 24 caracteres |
rows[].description | 72 caracteres, opcional |
rows[].id | 200 caracteres |
| Corpo | 4.096 caracteres |
| Cabeçalho | Só texto, 60 caracteres |
O limite de 10 linhas é o total da mensagem, não por seção. Se você tem mais opções, quebre em etapas (primeiro o dia, depois o horário). A escolha volta como list_reply:
"interactive": {
"type": "list_reply",
"list_reply": { "id": "slot_2210_14", "title": "14:00", "description": "Técnico disponível" }
}
Botão de link (CTA URL)
Esconde uma URL longa atrás de um botão. Útil para boleto, rastreio, área do cliente.
{
"messaging_product": "whatsapp",
"to": "5584999999999",
"type": "interactive",
"interactive": {
"type": "cta_url",
"body": { "text": "Sua segunda via está pronta." },
"action": {
"name": "cta_url",
"parameters": {
"display_text": "Abrir boleto",
"url": "https://cliente.exemplo.com.br/boletos/7731?origem=whatsapp"
}
}
}
}
O rótulo vai até 20 caracteres e o corpo até 1.024. O toque abre o navegador e não gera mensagem do usuário, então não renova a janela de 24 horas. Para medir cliques, use parâmetros na própria URL.
Localização: enviar e pedir
Para enviar um endereço fixo (loja, ponto de retirada), use type: "location". Latitude e longitude são obrigatórias; nome e endereço são opcionais.
{
"messaging_product": "whatsapp",
"to": "5584999999999",
"type": "location",
"location": {
"latitude": -5.7945,
"longitude": -35.2110,
"name": "Loja Exemplo Centro",
"address": "Av. Exemplo, 100 - Natal, RN"
}
}
Para pedir a localização do usuário (entrega, atendimento em campo), use a mensagem interativa com o botão de enviar localização:
{
"messaging_product": "whatsapp",
"to": "5584999999999",
"type": "interactive",
"interactive": {
"type": "location_request_message",
"body": { "text": "Para calcular o frete, toque no botão e envie a sua localização." },
"action": { "name": "send_location" }
}
}
A resposta chega como uma mensagem comum de localização, com latitude, longitude e, se o usuário quiser compartilhar, name e address. O campo context.id aponta para a mensagem de pedido, o que ajuda a ligar a resposta ao pedido certo.
Carrossel de mídia
O carrossel mostra de 2 a 10 cartões com rolagem horizontal. Cada cartão precisa de cabeçalho de imagem ou vídeo, pode ter corpo de até 160 caracteres e deve ter um botão de link ou botões de resposta rápida, com o mesmo tipo e a mesma quantidade em todos os cartões. Funciona bem para mostrar variações de um produto. A estrutura completa está na página de carrossel da documentação da Meta.
WhatsApp Flows
Flows são formulários de várias telas dentro do WhatsApp: cadastro, agendamento, pesquisa, simulação de crédito. O conteúdo das telas é definido num arquivo JSON (Flow JSON), e o resultado volta para você no webhook.
A Meta lista como pré-requisitos ter a empresa verificada e manter a qualidade das mensagens alta.
1. Criar, subir o JSON e publicar
Na Vectalk, o ciclo é feito por API com token de instância:
# Cria o Flow em rascunho
curl -X POST https://apis.vectalk.com.br/api/flows \
-H "Authorization: Bearer SEU_TOKEN_DE_INSTANCIA" \
-H "Content-Type: application/json" \
-d '{ "name": "agendamento_visita", "categories": ["APPOINTMENT_BOOKING"] }'
# Envia o flow.json (multipart)
curl -X POST https://apis.vectalk.com.br/api/flows/FLOW_ID/assets \
-H "Authorization: Bearer SEU_TOKEN_DE_INSTANCIA" \
-F "file=@flow.json" -F "name=flow.json" -F "asset_type=FLOW_JSON"
# Publica
curl -X POST https://apis.vectalk.com.br/api/flows/FLOW_ID/publish \
-H "Authorization: Bearer SEU_TOKEN_DE_INSTANCIA"
A resposta do upload traz validation_errors. Corrija tudo antes de publicar: para mudanças grandes em um Flow já publicado, a Meta recomenda criar um novo clonando o anterior com clone_flow_id, e um Flow publicado não pode ser excluído, só descontinuado.
2. Enviar o Flow dentro da janela
{
"messaging_product": "whatsapp",
"to": "5584999999999",
"type": "interactive",
"interactive": {
"type": "flow",
"header": { "type": "text", "text": "Agendar visita" },
"body": { "text": "Escolha data, horário e endereço em poucos passos." },
"footer": { "text": "Leva cerca de 1 minuto" },
"action": {
"name": "flow",
"parameters": {
"flow_message_version": "3",
"flow_id": "FLOW_ID",
"flow_token": "ag_5584999999999_20261020",
"flow_cta": "Agendar",
"flow_action": "navigate",
"flow_action_payload": { "screen": "INICIO", "data": { "nome": "Marina" } }
}
}
}
}
O flow_token é seu: use-o para identificar a sessão quando a resposta voltar. A Meta recomenda CTA de até 30 caracteres, sem emoji. Para iniciar o contato com um Flow fora da janela, crie um template com botão do tipo FLOW, como explica o guia de templates da API do WhatsApp.
3. Receber a resposta
Quando o usuário conclui, chega uma mensagem interativa do tipo nfm_reply. O response_json é uma string com os dados definidos na ação de conclusão do Flow:
"interactive": {
"type": "nfm_reply",
"nfm_reply": {
"name": "flow",
"body": "Sent",
"response_json": "{\"flow_token\":\"ag_5584999999999_20261020\",\"data\":\"2026-10-22\",\"horario\":\"14:00\"}"
}
}
Fique de olho na saúde do Flow. Se o endpoint do Flow ficar instável, a Meta muda o status para THROTTLED (envio limitado a 10 mensagens por hora) e, se piorar, para BLOCKED, quando ele não pode ser enviado nem aberto. As mudanças chegam pelo webhook flows.
Mídia: imagem, vídeo, documento e áudio
Mídia vai por link (URL pública) ou por id (obtido no upload). Pela Vectalk, o upload é feito em /api/media e devolve o media_id.
{
"messaging_product": "whatsapp",
"to": "5584999999999",
"type": "document",
"document": {
"link": "https://arquivos.exemplo.com.br/contratos/7731.pdf",
"filename": "contrato-7731.pdf",
"caption": "Segue o contrato para assinatura."
}
}
Com link, a Cloud API guarda o arquivo em cache por 10 minutos e reaproveita se a URL for igual. Se o arquivo mudou mas a URL não, acrescente um parâmetro aleatório na query string. Em cabeçalhos de botões, a Meta indica preferir o id de mídia enviada por upload em vez do link.
Roteando as respostas no webhook
Um roteador simples para os tipos acima, aproveitando que a Vectalk entrega o payload da Meta sem alteração:
function rotear(msg) {
if (msg.type === "location") {
return calcularFrete(msg.from, msg.location.latitude, msg.location.longitude, msg.context?.id);
}
if (msg.type !== "interactive") return tratarTextoLivre(msg);
const i = msg.interactive;
switch (i.type) {
case "button_reply":
if (i.button_reply.id === "atendente") return transferirParaHumano(msg.from);
return executarAcao(msg.from, i.button_reply.id);
case "list_reply":
return reservarHorario(msg.from, i.list_reply.id);
case "nfm_reply": {
const dados = JSON.parse(i.nfm_reply.response_json);
return salvarAgendamento(dados.flow_token, dados);
}
default:
return registrarNaoTratado(msg);
}
}
Respostas de botões de template (resposta rápida) chegam com type: "button", um formato diferente do button_reply; trate os dois. O guia de webhooks da API do WhatsApp mostra o servidor completo com fila e deduplicação, e o artigo sobre chatbot com IA no WhatsApp mostra como combinar botões e respostas geradas por IA.
Como escolher o tipo certo
A escolha depende do que você precisa receber de volta:
| Necessidade | Tipo indicado | Motivo |
|---|---|---|
| Sim ou não, confirmar ou remarcar | Botões de resposta | Um toque, resposta estruturada e renovação da janela |
| Escolher entre 4 e 10 opções | Lista | Cabe numa mensagem só, com descrição por linha |
| Levar para pagamento, rastreio ou portal | Botão de link | Esconde a URL e mantém o texto limpo |
| Endereço de entrega ou visita | Pedido de localização | Coordenadas exatas, sem digitação |
| Coletar vários campos (nome, data, endereço, preferências) | Flow | Telas com validação, sem idas e voltas no chat |
| Mostrar variações de produto | Carrossel ou mensagens de catálogo | Comparação visual lado a lado |
Se a conversa precisa de mais de duas perguntas em sequência, um Flow costuma ser mais curto para o usuário do que vários botões seguidos.
Boas práticas
- Rótulos curtos e com verbo. “Confirmar” e “Remarcar” funcionam melhor que frases. O limite de 20 caracteres corta o resto.
- Sempre uma saída para pessoa. A Política de Mensagens do WhatsApp Business pede caminhos claros de escalonamento em experiências automatizadas, como a transferência para um atendente humano. Um botão “Falar com alguém” resolve.
- IDs estáveis. Trate o
idcomo contrato com o seu backend. Mudar o texto do botão não deve quebrar o roteamento. - Aceite texto livre. O usuário pode ignorar os botões e digitar. O roteador precisa entender “sim”, “pode ser às 14h” ou um áudio.
- Não conte com a ordem de entrega. A Meta avisa que a ordem de entrega de uma sequência de mensagens não é garantida. Se a ordem importa, espere o status
deliveredda anterior antes de mandar a próxima. - Uma pergunta por mensagem. Três mensagens interativas seguidas confundem e geram respostas para a mensagem errada. O
context.iddo webhook mostra a qual mensagem o usuário respondeu.
Perguntas frequentes
Posso enviar botões para um cliente que não falou comigo hoje?
Não como mensagem interativa. Fora da janela de 24 horas, use um template com botões de resposta rápida, de link ou de Flow.
Dá para colocar mais de 3 botões de resposta?
Na mensagem interativa, não. Use uma lista (até 10 opções). Em templates, o limite é de até 10 botões, com regras por tipo.
Mensagens interativas são cobradas?
São mensagens de serviço. Desde 1º de outubro de 2026, a Meta dá 1.000 mensagens de serviço gratuitas por número por mês e cobra a partir daí, exceto dentro da janela de ponto de entrada gratuito aberta por anúncio.
Preciso de endpoint próprio para usar Flows?
Não para Flows simples, em que os dados ficam no próprio Flow JSON e voltam no nfm_reply. Flows que buscam dados em tempo real (horários disponíveis, preço) usam a ação data_exchange e exigem um endpoint seu.
Construa conversas interativas com a Vectalk
Na Vectalk, botões, listas, localização, mídia e Flows usam o mesmo payload da Cloud API, e as respostas chegam no webhook no formato da documentação da Meta. Um token atende todas as suas contas, a coexistência com o app WhatsApp Business está disponível e a cobrança da Meta passa pela Vectalk, sem cartão cadastrado na Meta. Crie sua conta em apps.vectalk.com.br/register, veja os exemplos em docs.vectalk.com.br ou fale com o time pela Central de Ajuda.
Fontes oficiais consultadas em 20/10/2026: Mensagens com botões de resposta, Mensagens de lista, Envio de Flows.
