Skip to content
WhatIsUp.dev

Webhooks

Webhooks são como o WhatIsUp.dev avisa você sobre coisas — mensagens recebidas, mudanças de estado do canal, acks de entrega. Você registra uma URL HTTPS, a gente faz um POST de um corpo JSON assinado sempre que algo acontece.

Como flui

Mensagens de WhatsApp recebidas e mudanças de estado fluem de volta para o seu endpoint.

Todo evento é registrado no nosso log de entregas antes de a gente tentar enviar. Esse registro carrega o payload completo, a contagem de tentativas e o status da última resposta. É consultável pelo dashboard ou por GET /v1/webhook-deliveries.

Assinatura

Todo webhook de saída carrega um header X-WhatIsUp-Signature no mesmo formato que a Stripe usa:

X-WhatIsUp-Signature: t=1700000000,v1=<hex_hmac>

O HMAC é computado sobre <timestamp>.<raw_body> com o segredo de assinatura do seu endpoint. Você o verifica recomputando e comparando em tempo constante. O passo a passo completo está em Webhooks → Verificação de assinatura.

Retentativas e backoff

Entregas que falham (qualquer coisa que não seja 2xx, incluindo timeouts) são retentadas com backoff exponencial + jitter:

TentativaAtraso
1 (imediata)0s
2~10s
3~60s
4~5m
5~30m
6~2h
Finaldesiste após a tentativa 6

O jitter aleatório evita retentativas em manada quando você publica um fix e um backlog drena. O orçamento total de retentativas é de ~2,5 horas.

Idempotência

Todo evento carrega um event_id (ULID) que é estável entre retentativas. Use-o como sua chave de deduplicação:

async function handleWebhook(req) {
  const eventId = req.body.event_id;
  if (await alreadyProcessed(eventId)) return res.status(200);
  // ... faça o trabalho ...
  await markProcessed(eventId);
}

Sem deduplicação, um ack lento do seu lado pode fazer o mesmo evento ser processado várias vezes depois de uma retentativa.

Concorrência por host

O gateway limita quantas requisições podem estar em voo para um único host. Se você tem 50 canais entregando para webhooks.example.com, só um punhado dispara de cada vez; o resto fica na fila. Isso impede que um endpoint lento sature a entrega globalmente — seus outros endpoints continuam fluindo.

Retenção de payload

Os payloads de entrega são mantidos por 7 dias para entregas bem-sucedidas e 30 dias para as que falharam/estão retentando, depois são zerados por um sweeper. Os metadados (status, contagem de tentativas, última resposta) ficam para consultas forenses. Se você quer reter o payload por mais tempo, registre do seu lado.

IDs de correlação

Todo webhook carrega um X-WhatIsUp-Correlation-Id que você pode usar para rastreá-lo até o que o disparou — geralmente a requisição da API que produziu o evento, ou um id gerado para eventos espontâneos (mensagens recebidas, mudanças de estado). Útil quando você está tentando descobrir qual das suas execuções de teste causou o pico nos seus logs.