Visão geral
Quando uma sessão processa uma mensagem, o WhataBot envia uma requisição POST para a URL de callback configurada na sua Chave de API. É assim que seu sistema recebe as respostas do bot — mensagens de texto, mídia, menus interativos, transferências e finalização de sessão.
Configuração
A URL do webhook é definida por Chave de API através do campo callbackUrl. Consulte Criar Chave de API ou Atualizar Chave de API.
A URL de callback deve usar HTTPS e não pode apontar para localhost, endereços de loopback ou faixas de IP privadas (10.x.x.x, 192.168.x.x, etc.).
Estrutura do Payload
Todo webhook é uma requisição POST com o seguinte corpo JSON:
{
"sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"messageId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"changes": [
{
"field": "messages",
"value": {
"messages": [
{
"type": "text",
"text": {
"body": "Hello! How can I help you today?"
}
},
{
"type": "interactive",
"interactive": {
"type": "button",
"body": { "text": "Choose an option:" },
"action": {
"buttons": [
{ "id": "btn-1", "title": "Track Order" },
{ "id": "btn-2", "title": "Talk to Agent" }
]
}
}
}
]
}
},
{
"field": "function",
"value": {
"functions": [
{
"type": "transfer",
"targetType": "sector",
"targetId": "sector-uuid"
}
]
}
}
]
}
Campos de Nível Superior
| Campo | Tipo | Descrição |
|---|
sessionId | string | UUID da sessão. |
messageId | string | UUID da mensagem de entrada que disparou esta etapa do fluxo. |
changes | array | Uma ou mais mudanças produzidas pelo fluxo. Cada mudança tem um field e um value. |
O Array changes
O array changes informa ao seu sistema o que aconteceu durante esta etapa do fluxo. Existem dois tipos possíveis de mudança:
field | Quando aparece | O que value contém |
|---|
"messages" | O fluxo produziu mensagens para enviar ao usuário. | { "messages": [...] } — um array de mensagens de saída. |
"function" | O fluxo disparou uma ação (transferência ou finalização). | { "functions": [...] } — um array de chamadas de função. |
Um único webhook pode conter ambos os tipos de mudança — por exemplo, quando um nó envia uma mensagem e depois transfere a conversa na mesma etapa.
Tipos de Mensagem
Quando field é "messages", o array value.messages contém uma ou mais mensagens. Cada mensagem tem um type que determina sua estrutura.
Texto
Uma mensagem de texto simples.
{
"type": "text",
"text": {
"body": "Your order #12345 has been shipped!"
}
}
| Campo | Tipo | Descrição |
|---|
text.body | string | O conteúdo de texto. |
Mídia
Um anexo de arquivo (imagem, vídeo, áudio ou documento).
{
"type": "media",
"media": {
"type": "image",
"mimeType": "image/png",
"url": "https://example.com/catalog.png",
"caption": "Our latest catalog"
}
}
| Campo | Tipo | Descrição |
|---|
media.type | string | image, video, audio ou document. |
media.mimeType | string | Tipo MIME (ex: image/png, application/pdf). |
media.url | string | URL pública do arquivo. |
media.caption | string? | Texto opcional exibido com a mídia. |
Interativo — Botão
Uma mensagem com botões clicáveis (até 3).
{
"type": "interactive",
"interactive": {
"type": "button",
"body": {
"text": "How can we help you?"
},
"footer": {
"text": "Choose an option"
},
"action": {
"buttons": [
{ "id": "btn-1", "title": "Track Order" },
{ "id": "btn-2", "title": "New Purchase" },
{ "id": "btn-3", "title": "Talk to Agent" }
]
}
}
}
| Campo | Tipo | Descrição |
|---|
interactive.type | string | Sempre "button". |
interactive.body.text | string | Texto principal da mensagem. |
interactive.footer.text | string? | Texto opcional do rodapé. |
interactive.action.buttons | array | Array de objetos de botão com id e title. |
Interativo — Lista
Uma lista rolável com seções e linhas.
{
"type": "interactive",
"interactive": {
"type": "list",
"body": {
"text": "Browse our departments:"
},
"footer": {
"text": "Tap to see options"
},
"action": {
"button": "View Departments",
"sections": [
{
"title": "Sales",
"rows": [
{ "id": "row-1", "title": "New Orders", "description": "Place a new order" },
{ "id": "row-2", "title": "Promotions", "description": "Current deals" }
]
}
]
}
}
}
| Campo | Tipo | Descrição |
|---|
interactive.type | string | Sempre "list". |
interactive.body.text | string | Texto principal da mensagem. |
interactive.footer.text | string? | Texto opcional do rodapé. |
interactive.action.button | string | Rótulo do botão que abre a lista. |
interactive.action.sections | array | Array de seções, cada uma com title e rows. |
rows[].id | string | Identificador da linha. |
rows[].title | string | Rótulo da linha. |
rows[].description | string? | Texto secundário opcional. |
Interativo — CTA URL
Uma mensagem com um botão de link.
{
"type": "interactive",
"interactive": {
"type": "cta_url",
"body": {
"text": "Visit our website for more details"
},
"action": {
"name": "cta_url",
"parameters": {
"display_text": "Open Website",
"url": "https://example.com"
}
}
}
}
| Campo | Tipo | Descrição |
|---|
interactive.type | string | Sempre "cta_url". |
interactive.body.text | string | Texto principal da mensagem. |
interactive.action.parameters.display_text | string | Rótulo do botão. |
interactive.action.parameters.url | string | URL que o botão abre. |
Tipos de Função
Quando field é "function", o array value.functions contém uma ou mais ações disparadas pelo fluxo.
Transferência
A conversa foi transferida para um agente humano ou setor.
{
"type": "transfer",
"targetType": "sector",
"targetId": "sector-uuid"
}
| Campo | Tipo | Descrição |
|---|
type | string | Sempre "transfer". |
targetType | string | "sector" ou "agent". |
targetId | string | UUID do setor ou agente de destino. |
Finalização
A sessão foi finalizada.
| Campo | Tipo | Descrição |
|---|
type | string | Sempre "finish". |
Exemplo Completo
Um webhook típico onde o bot envia uma saudação e apresenta botões:
{
"sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"messageId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"changes": [
{
"field": "messages",
"value": {
"messages": [
{
"type": "text",
"text": {
"body": "Welcome to Acme Store! 👋"
}
},
{
"type": "interactive",
"interactive": {
"type": "button",
"body": { "text": "What would you like to do?" },
"footer": { "text": "Select an option" },
"action": {
"buttons": [
{ "id": "btn-track", "title": "Track Order" },
{ "id": "btn-support", "title": "Talk to Support" }
]
}
}
}
]
}
}
]
}
Um webhook onde o bot transfere a conversa:
{
"sessionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"messageId": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"changes": [
{
"field": "messages",
"value": {
"messages": [
{
"type": "text",
"text": {
"body": "Transferring you to our support team..."
}
}
]
}
},
{
"field": "function",
"value": {
"functions": [
{
"type": "transfer",
"targetType": "sector",
"targetId": "550e8400-e29b-41d4-a716-446655440000"
}
]
}
}
]
}
Entrega
| Propriedade | Valor |
|---|
| Método | POST |
| Content-Type | application/json |
| Timeout | 10 segundos por tentativa |
| Tentativas | 3 tentativas com backoff exponencial (1s, 2s, 4s) |
Seu endpoint deve responder com um código de status 2xx. Respostas diferentes de 2xx são tratadas como falhas e serão tentadas novamente até 3 vezes.