← Webhooks

Política de reenvio

Quando uma entrega de webhook falha, reprocessamos automaticamente com backoff exponencial para maximizar a confiabilidade de entrega.

O que conta como falha?

Uma entrega é considerada falha quando seu endpoint responde com qualquer código diferente de 200, 201, 202 ou 204, ou quando a conexão expira (timeout de 30s por tentativa, configurável por webhook).

Cronograma de reenvio

Entregas com falha são retentadas até 5 vezes no total por padrão (configurável por webhook), usando backoff exponencial: o atraso aproximadamente dobra antes de cada nova tentativa, começando em ~2s. Com as configurações padrão, as 5 tentativas acontecem em cerca de 30 segundos a partir da primeira — uma pequena variação aleatória (jitter) é somada a cada atraso para evitar que as tentativas cheguem todas no mesmo instante.

TentativaEspera antes desta tentativa
#10s
#2~2s
#3~4s
#4~8s
#5~16s

A tentativa #1 é o envio original, feito imediatamente. Os delays mostrados são aproximados — os valores reais variam um pouco por causa do jitter.

Falha permanente: Quando o número de tentativas configurado se esgota (5 por padrão), essa entrega é marcada como permanentemente falha. Você pode inspecionar entregas falhadas nos logs do webhook nas configurações do CRM.

Pausa automática do webhook: Isso é diferente dos retries de uma única entrega: se um webhook acumular 10 tentativas de entrega consecutivas com falha (contadas por tentativa, incluindo retries do mesmo evento — não só eventos distintos), ele é pausado automaticamente e para de receber novos eventos até ser reativado manualmente nas configurações do CRM.

Idempotência

Como retries podem entregar o mesmo evento mais de uma vez, seu endpoint deve ser idempotente. Use o header X-Webhook-Event-Id para deduplicar: ele permanece igual em todas as tentativas de entrega de um mesmo evento, diferente do X-Webhook-Delivery-Attempt, que incrementa a cada retry.

Node.js — Idempotency check
const processedDeliveries = new Set(); // Use Redis in production

app.post('/webhook', (req, res) => {
  const eventId = req.headers['x-webhook-event-id'];

  if (processedDeliveries.has(eventId)) {
    // Already processed — acknowledge and skip
    return res.sendStatus(200);
  }

  // Process the event
  handleEvent(req.body);

  processedDeliveries.add(eventId);
  res.sendStatus(200);
});

Boas práticas

  • Responda com 200 OK o mais rápido possível. Enfileire processamento pesado de forma assíncrona (SQS, BullMQ, etc.).
  • Nunca retorne 5xx para erros de lógica de negócio — responda 200 e logue localmente. Apenas 200, 201, 202 e 204 contam como sucesso; qualquer outro código (principalmente 5xx) dispara um retry.
  • Sempre valide a assinatura HMAC antes de processar (veja a página de Segurança).
  • Armazene o event ID (X-Webhook-Event-Id) em um banco de dados para tratar eventos duplicados com segurança.
  • Monitore os tempos de resposta do seu endpoint — mantenha-os abaixo de 5s para evitar timeouts.