Pular para o conteúdo

Webhooks

Webhooks entregam eventos do WhatsApp ao seu servidor em tempo real. Em vez de ficar consultando a API, a ZapDev faz um POST na sua URL sempre que algo acontece, com entrega assíncrona, assinada e com retry.

Você registra uma URL pública HTTPS na instância. A cada evento, mensagem recebida, status de entrega, conexão alterada, a ZapDev envia um POST com corpo JSON. Sua aplicação responde 2xx para confirmar.

Todo payload traz event, instanceId, timestamp e data.

Evento Quando
message.received Mensagem recebida na instância
message.sent Mensagem enviada
message.delivered Entregue ao destinatário
message.read Lida pelo destinatário
message.failed Falha no envio
instance.connected Instância conectada
instance.disconnected Instância desconectada
instance.qr_updated Novo QR Code disponível

Payload · message.received

POST /webhook
{
"event": "message.received",
"instanceId": "ins_8f2a91",
"timestamp": "2026-07-11T14:35:11Z",
"data": {
"messageId": "msg_9Kp2",
"from": "5511988887777",
"pushName": "Marina Costa",
"type": "text",
"text": "Oi! Qual o horário de vocês?"
}
}

O campo type indica o que chegou: text, image, video, audio, document, sticker, location, reaction ou contact. Mensagens de mídia trazem um objeto media (com mimetype, fileName e, se o webhook estiver com base64 ligado, o conteúdo em base64); a legenda vem em text.

message.received · imagem
{
"event": "message.received",
"instanceId": "ins_8f2a91",
"data": {
"messageId": "msg_9Kp2",
"from": "5511988887777",
"type": "image",
"text": "Chegou o catálogo",
"media": { "mimetype": "image/jpeg", "base64": "..." }
}
}

Toda requisição traz o header X-ZapDev-Signature: sha256=<hash>, um HMAC-SHA256 do corpo bruto, assinado com o segredo do webhook da instância. Valide-o para garantir que o evento veio da ZapDev.

Validação

Verificação (Node.js)
import crypto from 'node:crypto'
function verify(rawBody, signature, secret) {
const hmac = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(hmac),
Buffer.from(signature),
)
}

Se sua URL não responder 2xx, a ZapDev reenvia com backoff:

  • Até 5 tentativas.
  • Intervalos: 1s, 5s, 30s, 2min, 10min.
  • Sucesso em 2xx; falha em 4xx (sem retry, exceto 408 e 429) ou 5xx.