curl --request POST \
--url https://api.wppfy.com/send/menu \
--header 'Content-Type: application/json' \
--header 'token: <api-key>' \
--data '
{
"number": "5511999999999",
"type": "button",
"text": "Como podemos ajudar?",
"choices": [
"Suporte|suporte",
"Fazer pedido|pedido"
]
}
'{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"messageid": "<string>",
"chatid": "<string>",
"sender": "<string>",
"senderName": "<string>",
"isGroup": false,
"fromMe": false,
"messageType": "<string>",
"source": "<string>",
"messageTimestamp": 0,
"status": "<string>",
"text": "",
"quoted": "",
"edited": "",
"reaction": "",
"vote": "",
"convertOptions": "",
"buttonOrListid": "",
"owner": "",
"error": "",
"content": {},
"wasSentByApi": true,
"pinned": true,
"sendFunction": "<string>",
"sendPayload": {},
"fileURL": "<string>",
"callPeer": {
"jid": "<string>",
"name": "<string>",
"imagePreviewUrl": "<string>"
},
"send_folder_id": "<string>",
"track_source": "<string>",
"track_id": "<string>",
"ai_metadata": {
"agent_id": "<string>",
"turn": "<string>",
"flow_id": "<string>",
"request": {
"messages": "<array>",
"tools": "<array>",
"options": {
"model": "<string>",
"temperature": 123,
"maxTokens": 123,
"topP": 123,
"frequencyPenalty": 123,
"presencePenalty": 123
}
},
"response": {
"choices": "<array>",
"toolResults": "<array>",
"error": "<string>"
},
"outcome": {
"status": "sent",
"texts": 123,
"audio": true,
"menus": 123,
"files": 123,
"handoff": "<string>",
"lead": [
"<string>"
],
"detail": "<string>"
}
},
"sender_pn": "<string>",
"sender_lid": "<string>",
"sender_image_preview_url": "<string>",
"response": {
"status": "success",
"message": "Menu sent successfully"
}
}{
"error": "Missing required fields or invalid menu type"
}{
"error": "Invalid token"
}{
"error": "Rate limit exceeded"
}{
"error": "Failed to send menu"
}Enviar menu interativo (botões, carrossel, lista ou enquete)
Este endpoint oferece uma interface unificada para envio de quatro tipos principais de mensagens interativas:
- Botões: Para ações rápidas e diretas
- Carrossel de botões: Para uma lista horizontal de botões com imagens
- Listas: Para menus organizados em seções
- Enquetes: Para coleta de opiniões e votações
Suporte a campos de rastreamento: Este endpoint também suporta track_source e track_id documentados na tag “Enviar Mensagem”.
Estrutura Base do Payload
Todas as requisições seguem esta estrutura base:
{
"number": "5511999999999",
"type": "button|button_legacy|list|poll|carousel",
"text": "Texto principal da mensagem",
"choices": ["opções baseadas no tipo escolhido"],
"footerText": "Texto do rodapé (opcional para botões e listas)",
"listButton": "Texto do botão (para listas)",
"selectableCount": "Número de opções selecionáveis (apenas para enquetes)"
}
Tipos de Mensagens Interativas
1. Botões (type: “button”)
Cria botões interativos com diferentes funcionalidades de ação.
Campos Específicos
footerText: Texto opcional exibido abaixo da mensagem principalchoices: Array de opções que serão convertidas em botões
Formatos de Botões
Cada botão pode ser configurado usando | (pipe) ou \n (quebra de linha) como separadores:
-
Botão de Resposta:
"texto|id"ou"texto\nid"ou"texto"(ID será igual ao texto)
-
Botão de Cópia:
"texto|copy:código"ou"texto\ncopy:código"
-
Botão de Chamada:
"texto|call:+5511999999999"ou"texto\ncall:+5511999999999"
-
Botão de URL:
"texto|https://exemplo.com"ou"texto|url:https://exemplo.com"
Botões com imagem, vídeo ou documento
O cabeçalho do botão pode levar uma imagem, um vídeo ou um documento em file, por URL ou base64, como no
/send/media. O tipo sai do próprio arquivo; para forçar, mande mimetype: image, video, document ou o MIME type do arquivo (por exemplo, video/mp4). O documento usa o
nome de docName; sem ele, o nome do arquivo.
Áudio não vai no botão: o WhatsApp não tem áudio no cabeçalho, e a API responde 400. Envie o áudio antes,
com o /send/media. Sem mimetype, a API reconhece o áudio pela extensão da URL ou pelo início do base64; numa
URL sem extensão, informe o mimetype.
{
"number": "5511999999999",
"type": "button",
"text": "Escolha um produto:",
"file": "https://exemplo.com/produto1.jpg",
"choices": [
"Produto A|prod_a",
"Mais Info|https://exemplo.com/produto-a",
"Produto B|prod_b",
"Ligar|call:+5511999999999"
],
"footerText": "Produtos em destaque"
}
{
"number": "5511999999999",
"type": "button",
"text": "Tabela de preços de outubro",
"file": "https://exemplo.com/tabela.pdf",
"docName": "Tabela de preços.pdf",
"choices": ["Quero comprar|comprar", "Falar com vendedor|vendedor"]
}
Se a mídia não baixar ou não subir para o WhatsApp, o botão sai sem ela.
Botões no formato legado (type: “button_legacy”)
Use button_legacy somente quando precisar enviar os botões de resposta do
formato anterior. O formato de choices é:
"texto|id""texto\nid""texto|reply:id""texto"— o próprio texto será usado como ID
Este modo cria apenas botões de resposta. Ações de URL, chamada e cópia e o
a mídia em file continuam disponíveis no formato atual type: "button".
{
"number": "5511999999999",
"type": "button_legacy",
"text": "Deseja continuar?",
"choices": [
"Sim|confirmar",
"Não|reply:cancelar"
],
"footerText": "Escolha uma opção"
}
Exemplo Completo
{
"number": "5511999999999",
"type": "button",
"text": "Como podemos ajudar?",
"choices": [
"Suporte Técnico|suporte",
"Fazer Pedido|pedido",
"Nosso Site|https://exemplo.com",
"Falar Conosco|call:+5511999999999"
],
"footerText": "Escolha uma das opções abaixo"
}
Limitações e Compatibilidade
Importante: Ao combinar botões de resposta com outros tipos (call, url, copy) na mesma mensagem, será exibido o aviso: “Não é possível exibir esta mensagem no WhatsApp Web. Abra o WhatsApp no seu celular para visualizá-la.”
2. Listas (type: “list”)
Cria menus organizados em seções com itens selecionáveis.
Campos Específicos
listButton: Texto do botão que abre a listafooterText: Texto opcional do rodapéchoices: Array com seções e itens da lista
Formato das Choices
"[Título da Seção]": Inicia uma nova seção"texto|id|descrição": Item da lista com:- texto: Label do item
- id: Identificador único, opcional
- descrição: Texto descritivo adicional e opcional
Exemplo Completo
{
"number": "5511999999999",
"type": "list",
"text": "Catálogo de Produtos",
"choices": [
"[Eletrônicos]",
"Smartphones|phones|Últimos lançamentos",
"Notebooks|notes|Modelos 2024",
"[Acessórios]",
"Fones|fones|Bluetooth e com fio",
"Capas|cases|Proteção para seu device"
],
"listButton": "Ver Catálogo",
"footerText": "Preços sujeitos a alteração"
}
3. Enquetes (type: “poll”)
Cria enquetes interativas para votação.
Campos Específicos
selectableCount: Número de opções que podem ser selecionadas (padrão: 1)choices: Array simples com as opções de voto
Exemplo Completo
{
"number": "5511999999999",
"type": "poll",
"text": "Qual horário prefere para atendimento?",
"choices": [
"Manhã (8h-12h)",
"Tarde (13h-17h)",
"Noite (18h-22h)"
],
"selectableCount": 1
}
4. Carousel (type: “carousel”)
Cria um carrossel de cartões com imagens e botões interativos.
Campos Específicos
choices: Array com elementos do carrossel na seguinte ordem:[Texto do cartão]: Texto do cartão entre colchetes{URL ou base64 da imagem}: Imagem entre chaves- Botões do cartão (um por linha):
"texto|copy:código"para botão de copiar"texto|https://url"para botão de link"texto|call:+número"para botão de ligação
Exemplo Completo
{
"number": "5511999999999",
"type": "carousel",
"text": "Conheça nossos produtos",
"choices": [
"[Smartphone XYZ\nO mais avançado smartphone da linha]",
"{https://exemplo.com/produto1.jpg}",
"Copiar Código|copy:PROD123",
"Ver no Site|https://exemplo.com/xyz",
"Fale Conosco|call:+5511999999999",
"[Notebook ABC\nO notebook ideal para profissionais]",
"{https://exemplo.com/produto2.jpg}",
"Copiar Código|copy:NOTE456",
"Comprar Online|https://exemplo.com/abc",
"Suporte|call:+5511988888888"
]
}
Nota: Criamos outro endpoint para carrossel:
/send/carousel, funciona da mesma forma, mas com outro formato de payload. Veja o que é mais fácil para você.
Termos de uso
Os recursos de botões interativos e listas podem ser descontinuados a qualquer momento sem aviso prévio. Não nos responsabilizamos por quaisquer alterações ou indisponibilidade destes recursos.
Alternativas e Compatibilidade
Considerando a natureza dinâmica destes recursos, nosso endpoint foi projetado para facilitar a migração entre diferentes tipos de mensagens (botões, listas e enquetes).
Recomendamos criar seus fluxos de forma flexível, preparados para alternar entre os diferentes tipos.
Em caso de descontinuidade de algum recurso, você poderá facilmente migrar para outro tipo de mensagem apenas alterando o campo “type” no payload, mantendo a mesma estrutura de choices.
curl --request POST \
--url https://api.wppfy.com/send/menu \
--header 'Content-Type: application/json' \
--header 'token: <api-key>' \
--data '
{
"number": "5511999999999",
"type": "button",
"text": "Como podemos ajudar?",
"choices": [
"Suporte|suporte",
"Fazer pedido|pedido"
]
}
'{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"messageid": "<string>",
"chatid": "<string>",
"sender": "<string>",
"senderName": "<string>",
"isGroup": false,
"fromMe": false,
"messageType": "<string>",
"source": "<string>",
"messageTimestamp": 0,
"status": "<string>",
"text": "",
"quoted": "",
"edited": "",
"reaction": "",
"vote": "",
"convertOptions": "",
"buttonOrListid": "",
"owner": "",
"error": "",
"content": {},
"wasSentByApi": true,
"pinned": true,
"sendFunction": "<string>",
"sendPayload": {},
"fileURL": "<string>",
"callPeer": {
"jid": "<string>",
"name": "<string>",
"imagePreviewUrl": "<string>"
},
"send_folder_id": "<string>",
"track_source": "<string>",
"track_id": "<string>",
"ai_metadata": {
"agent_id": "<string>",
"turn": "<string>",
"flow_id": "<string>",
"request": {
"messages": "<array>",
"tools": "<array>",
"options": {
"model": "<string>",
"temperature": 123,
"maxTokens": 123,
"topP": 123,
"frequencyPenalty": 123,
"presencePenalty": 123
}
},
"response": {
"choices": "<array>",
"toolResults": "<array>",
"error": "<string>"
},
"outcome": {
"status": "sent",
"texts": 123,
"audio": true,
"menus": 123,
"files": 123,
"handoff": "<string>",
"lead": [
"<string>"
],
"detail": "<string>"
}
},
"sender_pn": "<string>",
"sender_lid": "<string>",
"sender_image_preview_url": "<string>",
"response": {
"status": "success",
"message": "Menu sent successfully"
}
}{
"error": "Missing required fields or invalid menu type"
}{
"error": "Invalid token"
}{
"error": "Rate limit exceeded"
}{
"error": "Failed to send menu"
}Autorizações
Corpo
ID do chat para o qual a mensagem será enviada. Pode ser um número de telefone em formato internacional, um ID de grupo (@g.us), um ID de usuário (com @s.whatsapp.net ou @lid).
"5511999999999"
Tipo do menu. Use button para o formato atual e button_legacy apenas para botões de resposta no formato anterior.
button, button_legacy, list, poll, carousel "list"
Texto principal (aceita placeholders)
"Escolha uma opção:"
Lista de opções. Use [Título] para seções em listas
[
"[Eletrônicos]",
"Smartphones|phones|Últimos lançamentos",
"Notebooks|notes|Modelos 2024",
"[Acessórios]",
"Fones|fones|Bluetooth e com fio",
"Capas|cases|Proteção para seu device"
]
Texto do rodapé (opcional)
"Menu de serviços"
Texto do botão principal
"Ver opções"
Número máximo de opções selecionáveis (para enquetes)
1
Mídia do cabeçalho (type: button): imagem, vídeo ou documento, por URL ou base64, como no /send/media. Áudio retorna 400.
"https://exemplo.com/produto1.jpg"
Força o tipo do file (opcional): image, video, document ou o MIME type do arquivo, como video/mp4. Sem ele, o tipo sai do arquivo; outro valor responde 400.
"video/mp4"
Nome do arquivo quando o file é documento. Sem ele, o nome do arquivo.
"Tabela de preços.pdf"
ID da mensagem para responder
"3EB0538DA65A59F6D8A251"
Números para mencionar (separados por vírgula)
"5511999999999,5511888888888"
Marca conversa como lida após envio
true
Marca últimas mensagens recebidas como lidas
true
Atraso em milissegundos antes do envio, durante o atraso apacerá 'Digitando...'
1000
Origem do rastreamento da mensagem
"chatwoot"
ID para rastreamento da mensagem (aceita valores duplicados)
"msg_123456789"
Se true, envia a mensagem de forma assíncrona via fila interna
false
Resposta
Menu enviado com sucesso
Representa uma mensagem trocada no sistema
ID único interno da mensagem (formato r + 7 caracteres hex aleatórios)
ID original da mensagem no provedor
ID da conversa relacionada
ID do remetente da mensagem
Nome exibido do remetente
Indica se é uma mensagem de grupo
Indica se a mensagem foi enviada pelo usuário
Tipo de conteúdo da mensagem
Plataforma de origem da mensagem
Timestamp original da mensagem em milissegundos
Status do ciclo de vida da mensagem.
Exemplos comuns: Queued, Canceled, Failed, Sent, Delivered, Read.
Em mensagem de grupo, segue o participante mais adiantado: Delivered quando pelo menos um recebeu, Read quando pelo menos um leu e Played quando pelo menos um ouviu.
Texto original da mensagem
ID da mensagem citada/respondida
Histórico de edições da mensagem
ID da mensagem reagida
Dados de votação de enquete e listas
Conversão de opções da mensagem, lista, enquete e botões
ID do botão ou item de lista selecionado
Dono da mensagem
Mensagem de erro caso o envio tenha falhado
Conteúdo bruto da mensagem (JSON serializado ou texto)
Indica se a mensagem foi enviada via API
Mensagem fixada na conversa (fixar e desafixar chegam também em messages_update, tipos Pinned e Unpinned)
Função usada para enviar a mensagem (quando enviada via API)
Payload usado no envio quando disponível. Dados de mídia em base64 são omitidos.
URL ou referência de arquivo da mensagem
Contato conhecido associado a uma ligação, quando disponível em messageType: call.
Show child attributes
Show child attributes
Pasta associada ao envio (quando aplicável)
Origem de rastreamento
ID de rastreamento (pode repetir)
Registro de uma rodada da IA. O completo (pedido ao modelo, resposta e outcome) fica uma vez, na última mensagem do contato que a rodada respondeu, também quando nada saiu (erro, resposta descartada). Cada mensagem enviada pela IA leva só agent_id e turn (o id dessa mensagem do contato).
Show child attributes
Show child attributes
JID PN resolvido do remetente (quando disponível)
LID original do remetente (quando disponível)
URL temporária de preview do remetente, quando conhecida. A hidratação desta versão preenche mensagens recebidas em grupos; o campo pode ser omitido. Não provoca consulta de foto ao WhatsApp na listagem.
Show child attributes
Show child attributes
