Webhooks18 de abril de 20266 min de leitura

Como fazer o replay de um webhook quando seu servidor caiu

Seu servidor caiu por três horas. A Stripe, o GitHub e a Shopify continuaram enviando webhooks. Como fazer o replay do que você perdeu, com e sem um relay.

O LOG COMEÇA NA SUA ORIGEMorigem fora · nada gravadovocê só pode fazer o replay do que sua origem conseguiu receberO LOG COMEÇA NA EDGEorigem fora · eventos armazenadosselecione a janela → replay
Um replay só é tão bom quanto o ponto em que seu log começa.

Seu banco de dados caiu às 2h da manhã. Quando você acordou e consertou, três horas de webhooks já tinham sido enviadas e rejeitadas. Agora você está olhando para o Slack, tentando adivinhar quantos pagamentos da Stripe ficaram sem o pedido liberado e quantos pushes no GitHub não dispararam o job de CI certo.

Este post é o roteiro de verdade para recuperar webhooks perdidos, provedor por provedor, e depois o padrão que transforma isso num problema de um clique em vez de uma tarde de domingo.

TL;DR

  • Stripe: reenvio manual, um evento por vez, pelo Dashboard, ou um script com a Events API. Não existe interface para reenvio em massa.
  • GitHub: um botão de reenvio por entrega. Também um por vez, a não ser que você escreva um script com a Redelivery API.
  • Shopify: tenta de novo 8 vezes ao longo de 4 h; depois, os eventos somem e você consulta de novo a Orders API para conciliar.
  • O replay (um novo envio de um evento armazenado, feito por você) com um clique exige registrar os webhooks antes que cheguem ao seu servidor, e é para isso que um relay de webhooks (um serviço que recebe, guarda e encaminha seus webhooks) é projetado.

Stripe

A Stripe permite reenviar eventos de webhook manualmente pelo Dashboard:

  1. Vá em Developers → Events no Dashboard da Stripe
  2. Clique no evento que você quer reenviar
  3. Role até Webhook attempts (tentativas de webhook) e clique em Reenviar

Isso funciona um evento por vez, e só por 15 dias depois da criação do evento. Se você perdeu 300 eventos, vai clicar em 300 botões. Existe um comando na Stripe CLI (stripe events resend <event_id>), mas ele ainda exige que você saiba o ID de cada evento.

Replay em lote de eventos da Stripe

Não existe uma interface oficial de replay em massa. As alternativas:

  • Escreva um script que use a API da Stripe para listar os eventos da janela da queda, filtrar por status e fazer você mesmo o POST de cada um de volta para seu endpoint. Você está reconstruindo o webhook a partir do objeto do evento, e o formato não é exatamente o mesmo.
  • Ou, se você registrou seus webhooks antes que chegassem ao seu servidor, faça o replay a partir do seu próprio log

A abordagem de registrar antes do servidor é a que as equipes de produção acabam construindo. É também exatamente o que um relay de webhooks faz por você.

GitHub

O GitHub mostra um botão de reenvio por entrega em Settings → Webhooks → (escolha o webhook) → Recent Deliveries (entregas recentes) do repositório. Clique em Redeliver (entregar novamente) ao lado de cada uma.

Mesmo problema: uma por vez. O GitHub só permite reenviar entregas por 3 dias, e um replay em massa continua significando um script chamando a Redelivery API. E esse log é tudo o que você tem, porque o GitHub nunca tenta de novo uma entrega com falha por conta própria.

Shopify

A Shopify tenta de novo 8 vezes numa janela de quatro horas antes de desistir. Depois disso, o único jeito de recuperar é consultar de novo a API da Shopify para buscar o que você perdeu. Os webhooks em si sumiram.

Esse caso é especialmente doloroso porque a janela de recuperação da Shopify é, de longe, a mais curta das três grandes. Se seu servidor cai na sexta à noite e você só percebe na segunda, vai fazer uma conciliação completa pela Orders API.

O padrão geral

Seja qual for o provedor, o procedimento de recuperação sem um relay é mais ou menos este:

  1. Identifique a janela da queda. Quando seu servidor parou de responder 2xx?
  2. Puxe os eventos afetados, normalmente com uma chamada de API paginada por provedor
  3. Dispare de novo cada evento fazendo POST no seu próprio endpoint, ou consulte de novo a fonte da verdade e sincronize o estado à mão
  4. Deduplique, porque seu handler precisa ser idempotente e alguns eventos podem ter sido entregues parcialmente

Isso leva horas. E você só tem uma chance: se perder eventos além da janela de novas tentativas (retries), eles somem.

A versão com um clique

O AnyHook existe para transformar isso num clique. Quando você aponta seus webhooks para in.anyhook.net/you/app:

  • O AnyHook armazena cada evento antes da entrega, com criptografia em repouso
  • Se seu servidor responde 5xx, o AnyHook tenta de novo com backoff exponencial (Free=3, Pro=5, Scale=10 tentativas)
  • Se seu servidor fica fora do ar tempo suficiente para esgotar as novas tentativas, o evento é marcado como falha, mas o payload continua no seu log
  • Abra a página do app, escolha a janela no banner de eventos com falha (última hora, últimas 24 horas ou a janela de replay inteira) e clique em Replay. Ele envia 100 por vez, dos mais antigos para os mais novos. É só isso.

Replays de eventos com falha não consomem sua cota mensal, mas usam a franquia de computação do seu plano. Cada plano tem um limite diário de replays (100 no Free, 500 no Pro, 1.000 no Scale), e um evento retido por ter passado da cota conta como novo quando você faz o replay dele. Os replays saem de novo para seu endpoint com uma assinatura nova, enquanto o corpo e os cabeçalhos originais de entrada são preservados, então seu handler vê o evento exatamente como o provedor o enviou.

O equivalente na API é um único POST:

curl -X POST https://anyhook.net/api/v1/apps/stripe-prod/replay-failed \
  -H "Authorization: Bearer $ANYHOOK_KEY" \
  -H "Content-Type: application/json" \
  -d '{"since": "2026-04-18T02:00:00Z", "limit": 100}'

Uma chamada, replay de até 100 eventos, nenhum clique no painel.

A implicação de design

O que torna o replay barato é a persistência na edge, antes da entrega. Se seu log de webhooks começa no seu servidor, você só consegue fazer o replay do que seu servidor recebeu. Se seu log começa na edge da rede, antes que seu servidor tenha chance de falhar, você consegue fazer o replay de qualquer coisa que já tenha chegado.

O cronograma que roda entre essas tentativas é um problema de design à parte. O do AnyHook é uma escada fixa, sem jitter, e Retry de webhooks: backoff exponencial e jitter explica por que uma escada assim faz todos os clientes marcharem para o mesmo segundo depois de uma queda e por que, de todo modo, um replay barato é melhor do que novas tentativas agressivas. E, se você se pega recorrendo ao replay com frequência, a pergunta anterior é se essa fronteira deveria mesmo usar um webhook, que é o tema de Webhooks vs. polling.

O LOG COMEÇA NA SUA ORIGEMorigem fora · nada gravadovocê só pode fazer o replay do que sua origem conseguiu receberO LOG COMEÇA NA EDGEorigem fora · eventos armazenadosselecione a janela → replay

Registre os webhooks antes que cheguem ao seu servidor, torne o replay idempotente, e sua pior queda de webhooks vira uma recuperação de um minuto em vez de um fim de semana.

Duas leituras complementares que valem antes de você precisar delas. "Torne o replay idempotente" é a metade que sustenta tudo, e é mais difícil do que uma tabela de deduplicação quando as novas tentativas chegam em paralelo: Você recebeu o mesmo webhook duas vezes. E, se a Stripe já desistiu e desativou seu endpoint, ela parou de tentar de novo, e você vai preencher a lacuna (backfill) pela Events API dentro de uma janela de 30 dias: A Stripe desativou seu endpoint de webhook.

Experimente: anyhook.net.

Todos os posts18 de abril de 2026 · 6 min

Pare de perder webhooks.

Troque uma URL. Tenha novas tentativas, um log de eventos e replay com um clique. Ou veja antes: crie uma conta, rode a simulação de queda de 30 segundos e veja um evento sobreviver ao seu servidor fora do ar. Não precisa de servidor.