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.
| Tentativa | Espera antes desta tentativa |
|---|---|
| #1 | 0s |
| #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.
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.