Botões, listas e enquetes
O WhatsApp não garante que botões e listas apareçam em toda conexão por aparelho vinculado: o app às vezes deixa de desenhá-los depois de uma atualização. Por isso o Recadu numera as opções no texto por padrão e entende quando o contato responde "2". O seu sistema recebe o mesmo evento, seja qual for o jeito que o contato respondeu.
Veja quais formatos estão funcionando hoje em GET https://api.recadu.com.br/v1/status/interactive (público): resultado do monitor automático dos últimos 30 dias e a conferência manual por aparelho (Android, iPhone, Web).
Botões
{
"instance_id": "ins_...",
"to": "5537999990000",
"type": "interactive",
"interactive": {
"body": "Confirma o horário de amanhã às 9h?",
"footer": "Clínica Exemplo",
"buttons": [
{"type": "reply", "id": "confirmar", "label": "Confirmar"},
{"type": "reply", "id": "remarcar", "label": "Remarcar"}
]
}
}
Até 3 botões; texto do botão até 25 caracteres; body até 1.024; footer até 60.
type |
Campo obrigatório | O que faz |
|---|---|---|
reply |
id |
Resposta: gera message.interactive_reply com esse id |
url |
url |
Abre um link |
call |
phone |
Liga para o número |
copy |
code |
Copia um código (PIX copia e cola, cupom) |
Lista
"interactive": {
"body": "Escolha a unidade:",
"list": {
"button": "Ver unidades",
"sections": [
{"title": "Belo Horizonte", "rows": [
{"id": "bh-centro", "title": "Centro", "description": "Av. Afonso Pena, 1000"},
{"id": "bh-savassi", "title": "Savassi"}
]},
{"title": "Divinópolis", "rows": [
{"id": "div-centro", "title": "Centro"}
]}
]
}
}
Até 10 seções com até 10 linhas cada. Título da linha até 24 caracteres, descrição até 72, texto do botão até 20. Um interativo leva buttons ou list, nunca os dois.
Enquete
{
"type": "poll",
"poll": {
"name": "Como foi o atendimento?",
"options": [
{"id": "otimo", "label": "Ótimo"},
{"id": "bom", "label": "Bom"},
{"id": "ruim", "label": "Ruim"}
],
"selectable": 1
}
}
De 2 a 12 opções. selectable é quantas o contato pode marcar. A enquete é o formato mais estável: o WhatsApp sempre a desenha.
Modos
O modo decide como botões e listas saem. Ele é da instância (interactive_mode) e pode ser trocado numa mensagem só (interactive.mode).
| Modo | Como sai | Quando usar |
|---|---|---|
native+text (padrão) |
Botões ou lista de verdade e as opções numeradas no texto | Quase sempre: se o app não desenhar os botões, o contato ainda vê as opções e responde com o número |
native |
Só os botões ou a lista | Quando a interface sem números é importante e você acompanha o status dos interativos |
text |
Só texto, com as opções numeradas | Quando os botões não estão aparecendo, ou para não depender deles |
No modo native+text, o contato vê algo assim:
Confirma o horário de amanhã às 9h?
1. Confirmar
2. Remarcar
Botões url, call e copy não têm número: no modo text eles viram o link, o telefone ou o código escrito no texto.
interactive.format (native_flow ou legacy) escolhe a variante técnica dos botões; deixe vazio, a não ser que o suporte indique outra. Depois do envio, rendered_as diz como a mensagem saiu.
Respostas
Clique em botão, escolha na lista, voto na enquete ou resposta digitada com o número ou o nome da opção: tudo chega como message.interactive_reply.
{
"type": "message.interactive_reply",
"timestamp": "2026-10-13T14:05:40Z",
"data": {
"instance_id": "ins_...",
"message_id": "msg_...",
"wa_message_id": "3EB0C4...",
"chat": {"id": "5537999990000@s.whatsapp.net", "is_group": false, "phone": "5537999990000"},
"from": {"id": "5537999990000@s.whatsapp.net", "phone": "5537999990000", "name": "Maria"},
"from_me": false,
"type": "text",
"text": "2",
"reply": {
"option_id": "remarcar",
"label": "Remarcar",
"source": "text",
"in_reply_to": "msg_...",
"in_reply_to_wa_message_id": "3EB0A1..."
}
}
}
Trate pelo reply.option_id. reply.in_reply_to é o msg_... do menu respondido, para você saber a qual pergunta a resposta se refere.
reply.source |
Como o contato respondeu |
|---|---|
native_flow, button, template_button |
Clicou num botão |
list |
Escolheu na lista |
poll |
Votou na enquete (vote_removed: true quando tirou o voto) |
text |
Digitou o número ("2", "opção 2") ou o nome da opção |
Assine message.interactive_reply no seu webhook além de message.received: uma resposta reconhecida chega só como interactive_reply, não duas vezes.
Quando a resposta em texto é reconhecida
- Só vale o menu mais recente daquela conversa, ou o menu que o contato citou ao responder.
- Por 24 horas depois do envio do menu (
menu_ttl_hoursna política). - O número ("2", "2.", "opção 2") só vale nos modos que numeram as opções (
native+textetext); no modonative, "2" chega comomessage.receivedcomum. O nome da opção (sem diferença de acento ou maiúsculas) vale em todos os modos. - Depois que um menu foi respondido, um novo "2" não é tratado como resposta a ele.