---
title: "Webhook da API de WhatsApp: guia prático | D-API"
description: "Como funciona o webhook da API de WhatsApp: configuração, eventos, payload de mensagem recebida, política de reenvio e como montar um receptor confiável."
url: https://d-api.cloud/webhook-api-whatsapp
---

Guia da API de WhatsApp

# Webhook na API de WhatsApp: como receber mensagens e eventos

O webhook é a URL do seu sistema que a API chama sempre que algo acontece no WhatsApp: mensagem nova, mensagem lida, conexão que caiu. Sem ele, sua aplicação só fala; com ele, ela também escuta e reage.

Por Time de engenharia D-APIAtualizado em 24 de set de 20266 min de leitura

## O papel do webhook numa integração de WhatsApp

Enviar mensagem é a parte simples. O difícil é saber o que aconteceu depois: o cliente respondeu? Leu? O número desconectou no meio da madrugada? Numa [API de WhatsApp](https://d-api.cloud/), quem responde a essas perguntas é o webhook. A cada evento, a API faz um `POST` para uma URL que você controla, com um JSON descrevendo o ocorrido.

Isso inverte a lógica de integração. Em vez de o seu backend ficar perguntando "chegou algo?" a cada poucos segundos, ele só trabalha quando existe trabalho. Para um produto com centenas de conexões, é a diferença entre uma fila tranquila e milhares de requisições inúteis por minuto.

## Como configurar: uma URL ou uma URL por evento

O caminho mais curto é informar a URL ao criar a conexão (campo `webhookUrl`) ou depois, com `POST /api/v1/sessions/{sessionId}/webhook`. Quando você quer escolher quais eventos recebe, use o endpoint de configuração completa:

```
curl -X POST https://api.d-api.cloud/api/v1/sessions/minha-sessao/webhook-config \
  -H "Authorization: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "type": "per_event",
    "events": {
      "messages.received": { "enabled": true, "webhookUrl": "https://app.suaempresa.com/wa/k7f2q9/mensagens" },
      "connection.status": { "enabled": true, "webhookUrl": "https://app.suaempresa.com/wa/k7f2q9/conexao" }
    }
  }'
```

Os dois modos atendem necessidades diferentes:

-   **`single`:** todos os eventos habilitados vão para a mesma URL. Bom para começar ou quando um único serviço recebe tudo e distribui internamente.
-   **`per_event`:** cada evento tem seu destino. Útil quando atendimento, monitoramento e analytics são serviços separados.

Evento desabilitado não é enviado, então ligue só o que você vai processar.

## Envelope e eventos que você vai usar primeiro

Todo evento chega no mesmo envelope: `event` (nome do evento), `sessionId` (qual conexão gerou), `data` (o conteúdo específico), `timestamp` em ISO 8601 e `traceId`, que vale guardar nos logs para cruzar com o suporte. Os headers são `Content-Type: application/json` e `User-Agent: Deliverify-Webhook/1.0`.

| Evento | Quando dispara | Uso típico |
| --- | --- | --- |
| `messages.received` | Chegou mensagem (ou você mandou pelo celular) | Caixa de entrada, chatbot, CRM |
| `messages.sent` | Mensagem enviada pela API | Registrar histórico do envio |
| `message.delivered` / `message.read` | Entregue e lida pelo destinatário | Status de entrega na interface |
| `connection.status` | Status mudou para `connected`, `disconnected` ou `logged_out` | Alertar o cliente antes que ele perceba |
| `groups_participants.join` e afins | Entrada, saída ou promoção em grupo | Controle de membros |

Um detalhe que pega muita gente: não existe evento de edição separado. Mensagem editada chega como `messages.received` com `type: "edited_message"`.

## O payload de uma mensagem recebida

É o evento que mais importa. O `data` traz o `id` da mensagem, o `type` (texto, imagem, áudio, resposta de lista e outros), o conteúdo em `message`, quem mandou em `from`, se veio de grupo em `is_group` e, para mídia, o link em `media_url`:

```
{
  "event": "messages.received",
  "sessionId": "cliente-042",
  "timestamp": "2026-01-24T22:51:32.601Z",
  "traceId": "c17dee440402792623e3ad6d925cb000",
  "data": {
    "id": "AC9831DDA691236BA3CE4909A187B703",
    "type": "text",
    "message": "Quero remarcar para sexta",
    "timestamp": 1769295092000,
    "fromMe": false,
    "is_group": false,
    "from": { "jid": "5511999999999@s.whatsapp.net", "name": "Marina" },
    "from_name": "Marina",
    "media_url": null
  }
}
```

Repare em `fromMe`: ele vem `true` quando alguém respondeu pelo próprio celular do número conectado. Se o seu robô reage a toda mensagem, filtre esse caso para não responder a si mesmo.

## Política de entrega: o que a API garante e o que fica com você

Na D-API, se o seu endpoint falhar, a entrega é repetida até **7 vezes** com backoff exponencial, com intervalos de aproximadamente 5s, 10s, 20s, 40s, 80s e 160s. Cada tentativa espera no máximo **30 segundos** pela resposta. Respostas **404** e **410** são tratadas como falha permanente e encerram as tentativas. Há também um circuit breaker por URL e deduplicação de eventos com janela de 5 minutos.

Na prática, uma queda curta do seu servidor ou um deploy demorado não faz você perder mensagens. Uma rota apagada por engano, que devolve 404, faz. Por isso vale monitorar a taxa de erro do endpoint de webhook como qualquer rota crítica.

## Checklist do receptor de webhook

1.  **Responda 2xx em milissegundos.** Grave o evento numa fila e devolva `200`. Chamar LLM, CRM ou banco pesado antes de responder estoura os 30 segundos e gera reenvio.
2.  **Seja idempotente pelo `data.id`.** A deduplicação da API cobre janelas curtas; um reenvio pode chegar depois. Guarde os IDs processados e ignore repetidos.
3.  **Proteja a URL.** Como não há HMAC, coloque um token longo e aleatório no caminho, confira o `User-Agent` e rejeite `sessionId` que não existe na sua base.
4.  **Não devolva 404 durante deploy.** Se a rota some por alguns segundos, as tentativas param. Prefira 503, que entra no ciclo de reenvio.
5.  **Logue o `traceId`.** Sem dado pessoal no log, só o identificador do evento.

```
app.post('/wa/:token/mensagens', async (req, res) => {
  if (req.params.token !== process.env.WA_WEBHOOK_TOKEN) return res.sendStatus(401)
  const { event, sessionId, data, traceId } = req.body
  await queue.add('wa-event', { event, sessionId, data, traceId }, { jobId: data.id })
  res.sendStatus(200)
})
```

O `jobId` igual ao ID da mensagem faz a própria fila descartar duplicados. O processamento real (responder, salvar, chamar a IA) acontece no worker. Esse é o mesmo desenho usado num [chatbot de WhatsApp com IA](https://d-api.cloud/api-whatsapp-chatbot-com-ia).

## Quando trocar HTTP por RabbitMQ

Se o seu volume é alto ou você já opera um broker, a D-API pode publicar os eventos direto num RabbitMQ seu, configurado por conexão em `/sessions/{sessionId}/rabbitmq-config`. Alguns eventos de sincronização de histórico só existem nesse canal. Veja a página da [integração com RabbitMQ](https://d-api.cloud/integrations/rabbitmq).

Para entender o caminho completo, da conexão do número ao primeiro evento, leia [como funciona a API de WhatsApp](https://d-api.cloud/como-funciona-api-de-whatsapp). Se o seu produto vai receber eventos de muitos clientes ao mesmo tempo, o desenho por conexão está em [múltiplos números](https://d-api.cloud/api-whatsapp-multiplos-numeros) e na página de [API de WhatsApp para SaaS](https://d-api.cloud/api-whatsapp-para-saas).

## Perguntas frequentes

### Qual a diferença entre webhook e consultar a API de tempos em tempos?

Consultar periodicamente (polling) obriga seu sistema a perguntar se há novidade, gastando requisições e chegando atrasado. Com webhook, a API avisa sua URL no momento em que o evento acontece, e você só processa o que realmente mudou.

### O webhook de WhatsApp da D-API tem assinatura HMAC?

Não. Os eventos de WhatsApp chegam sem assinatura. A recomendação é usar uma URL secreta, com um token longo no caminho, e conferir no receptor o User-Agent e se o sessionId pertence a uma conexão sua.

### O que acontece se meu servidor ficar fora do ar?

A entrega é repetida até 7 vezes com intervalos crescentes, de cerca de 5 segundos até 160 segundos. Se o servidor voltar dentro dessa janela, o evento chega. Respostas 404 ou 410 encerram as tentativas para aquela URL.

### Posso mandar eventos diferentes para URLs diferentes?

Sim. No modo per\_event cada evento tem a própria URL, o que permite, por exemplo, mandar mensagens recebidas para o serviço de atendimento e mudanças de conexão para o serviço de monitoramento.

### Como testar o webhook localmente?

A API precisa alcançar sua URL pela internet. Durante o desenvolvimento, use um túnel que exponha a porta local com HTTPS e cadastre essa URL temporária na conexão de teste. Em produção, troque pela URL definitiva.

Teste a API de WhatsApp da D-API3 dias grátis, sem cartão.[Começar trial grátis](https://app.d-api.cloud/register)

## Continue lendo

-   [Guia da API de WhatsAppEnviar imagem, áudio e documento](https://d-api.cloud/api-whatsapp-enviar-midia)
-   [Guia da API de WhatsAppBotões e listas no WhatsApp](https://d-api.cloud/api-whatsapp-botoes-e-listas)
-   [Guia da API de WhatsAppAPI de grupos do WhatsApp](https://d-api.cloud/api-whatsapp-grupos)
-   [Guia da API de WhatsAppChatbot de WhatsApp com IA](https://d-api.cloud/api-whatsapp-chatbot-com-ia)

## Teste a API de WhatsApp da D-API

Trial de 3 dias com acesso completo. Sem cartão, sem fidelidade.

[Começar trial grátis](https://app.d-api.cloud/register)[Ver documentação](https://docs.d-api.cloud/)
