Webhooks
Visão Geral
Um webhook é uma chamada HTTP que você faz para o servidor de outra pessoa quando algo acontece.
É a forma dominante de integração assíncrona entre organizações, porque não exige que o parceiro consuma seu intermediário de mensagens nem adote sua tecnologia — basta ele expor uma URL.
A diferença que organiza tudo: o destino é um servidor que você não controla, com disponibilidade que você não conhece e correção que você não pode assumir.
Problema
Sem webhook, quem precisa saber de uma mudança consulta periodicamente.
Consultar é ineficiente dos dois lados: a maioria das consultas não traz novidade, e a latência é metade do intervalo. Um parceiro consultando a cada minuto gera 1.440 requisições por dia para talvez três eventos.
Webhook inverte: o publicador avisa quando há o que avisar.
E, ao inverter, transfere para o publicador um problema que a consulta não tinha — entregar para um endpoint que pode estar fora, lento, ou responder errado.
Conceitos Centrais
Do lado de quem envia
Retentativa com espera crescente. O destino vai estar fora. Sem repetição, o evento se perde. Ver backoff.
Prazo curto e agressivo. O receptor precisa responder rápido; se ele demora 30 segundos, sua fila de entregas trava. Cinco a dez segundos é o usual, e precisa estar no contrato.
Assinatura. O receptor precisa provar que a requisição veio de você. Um cabeçalho com assinatura sobre o corpo, usando um segredo compartilhado, é o padrão. Sem isso, qualquer um pode forjar eventos.
Marca de tempo na assinatura. Permite ao receptor rejeitar requisição antiga — a marca sozinha não impede nada; quem impede é a checagem do outro lado.
Identificador único do evento. Permite ao receptor deduplicar — o que ele vai precisar fazer, porque sua retentativa vai duplicar.
Desativação após falhas persistentes. Um endpoint morto há semanas não deve consumir sua capacidade indefinidamente. E a desativação precisa ser comunicada, ou o parceiro descobre pela ausência.
Painel de reentrega. O parceiro precisa poder reprocessar o que perdeu.
Do lado de quem recebe
Responda rápido, processe depois. Aceite, enfileire, devolva 200. Processar
de forma síncrona dentro do webhook é a causa mais comum de timeout e reentrega.
Verifique a assinatura antes de qualquer coisa — e, junto dela, a marca de tempo: recuse o que estiver fora de uma janela de tolerância, na ordem de minutos. Sem essa checagem, uma requisição capturada continua válida para sempre, e a assinatura passa a atestar apenas que ela um dia foi legítima. Dentro da janela, quem barra a repetição é o identificador único do evento.
Seja idempotente. Vai chegar duplicado. Ver idempotência.
Não confie na ordem. Retentativas embaralham. Um evento de cancelamento pode chegar antes do de criação.
Não confie no conteúdo. Vários provedores recomendam usar o webhook apenas como gatilho e consultar a API para obter o estado real — o que elimina de uma vez os problemas de ordem e de conteúdo defasado.
Devolva erro quando falhar. Responder 200 para o que você não processou faz o
provedor considerar entregue: o evento sai da fila de entregas e só volta se houver painel de
reentrega — e ainda assim depende de você perceber que perdeu.
Notificação ou estado
O mesmo trade-off de eventos de integração, com um peso extra: o corpo do webhook trafega para fora da sua organização.
Um webhook gordo com dados sensíveis os replica no ambiente do parceiro. Um webhook fino — identificador e tipo — mantém o dado na origem, sob controle de acesso.
Para dados regulados, o fino costuma ser a única opção defensável.
A URL do receptor é um risco de segurança
Permitir que um usuário cadastre uma URL arbitrária para a qual seu servidor fará requisições é, literalmente, pedir ao seu servidor que acesse um endereço escolhido por terceiros.
Sem restrição, isso permite alcançar endereços internos da sua rede — serviços de metadados da nuvem, bancos, painéis administrativos.
As defesas: recusar endereços privados e locais, resolver o nome e validar o IP resolvido, não seguir redirecionamentos, e enviar de uma rede isolada.
Este é o problema de segurança característico de webhooks e o mais frequentemente esquecido.
Modelo Mental
Webhook é uma entrega, não uma publicação. Você é responsável por ela chegar, num destino que não é seu.
Quando Usar
- Notificar sistemas fora da sua organização.
- O parceiro não vai consumir seu intermediário de mensagens.
- Consulta periódica é ineficiente para o volume de eventos.
- O receptor precisa reagir com baixa latência.
- Integração com plataformas que já esperam esse modelo.
Quando Não Usar
Internamente, quando já existe mensageria. Ver integração por mensageria — ali o intermediário resolve entrega, ordem e reprocessamento melhor.
Quando o volume é muito alto. Milhares de eventos por segundo por parceiro não cabem em requisições individuais; ver integração em lote.
Sem assinatura. Endpoint forjável.
Sem retentativa. Eventos se perdem na primeira instabilidade.
Sem validação da URL de destino. Risco de acesso à rede interna.
Quando o receptor precisa responder com dados. Webhook é notificação, não consulta.
Alternativas
- Consulta periódica — simples, sem entrega a garantir, e frequentemente suficiente. Não descarte cedo.
- Fluxo de eventos por assinatura — o parceiro consome um endpoint que mantém a conexão aberta, com posição controlada por ele. Elimina o problema de entrega.
- Mensageria compartilhada — quando há confiança e tecnologia comum.
- Arquivo periódico — ver integração por arquivo.
A segunda opção merece consideração: deixar o consumidor puxar no ritmo dele, com posição controlada, remove retentativa, desativação e reentrega do seu lado.
Trade-offs
| Webhook | Consulta periódica |
|---|---|
| Latência baixa | Metade do intervalo |
| Requisições só quando há evento | Muitas vazias |
| Você garante a entrega | O consumidor busca |
| Receptor precisa de endpoint público | Não precisa |
| Retentativa e reentrega a operar | Nada |
| Risco de acesso à rede interna | Nenhum |
Modos de Falha
Receptor lento travando a fila de entregas.
200 sem processar. Evento perdido silenciosamente.
Duplicata processada.
Ordem invertida. Cancelamento antes da criação.
Endpoint desativado sem aviso. O parceiro para de receber e não sabe.
Assinatura não verificada. Eventos forjados aceitos.
URL apontando para rede interna.
Processamento síncrono no webhook. Timeout, reentrega, e o efeito acontece duas vezes.
Erros Comuns
Processar de forma síncrona dentro do webhook. O emissor tem um prazo curto e considera falha o que passar dele — então ele reenvia, e o trabalho lento executa de novo enquanto o primeiro ainda roda. Receber, persistir e responder rápido resolve.
Não verificar assinatura. O endpoint é público por natureza; sem verificar a assinatura, qualquer um pode declarar que um pagamento foi aprovado.
Não validar a URL de destino. Quem emite webhooks para URLs fornecidas por usuários vira um cliente HTTP que alcança endereços internos — é a via clássica de falsificação de requisição no servidor.
Não deduplicar. Reentrega é comportamento normal, não excepcional. Sem chave de idempotência, cada reenvio repete o efeito.
Assumir ordem. Entregas paralelas e retentativas fazem o evento de cancelamento chegar antes do de criação. O processamento precisa tolerar isso, tipicamente por carimbo de versão.
Não oferecer reentrega ao parceiro. Quando o consumidor fica indisponível, sem um meio de pedir os eventos perdidos a única saída é reconciliação manual — de ambos os lados.
Exemplo Real
Uma plataforma de pagamentos notificava lojistas por webhook a cada mudança de status de transação.
Cinco problemas ao longo de dois anos, três do lado do provedor e dois do lado dos receptores:
Receptor lento. Um lojista com endpoint que levava 25 segundos ocupava trabalhadores de entrega. Isso atrasou as entregas de todos os lojistas em até 8 minutos num pico. Corrigido com prazo de 8 segundos, isolamento por lojista e fila separada para endpoints lentos.
Ordem invertida. Retentativas faziam pagamento.aprovado chegar depois de
pagamento.estornado. Lojistas marcavam pedidos como pagos após o estorno.
Corrigido documentando que a ordem não é garantida, incluindo o instante do evento
no corpo, e recomendando consulta à API para o estado atual.
Endpoint desativado em silêncio. Após 7 dias de falhas, a plataforma desativava. Um lojista ficou 3 semanas sem receber e sem saber — descobriu ao conciliar. Passou a haver e-mail no primeiro dia de falha, alerta no painel e desativação só após 14 dias.
Assinatura ignorada. Uma auditoria revelou que cerca de 30% dos lojistas não verificavam a assinatura. A plataforma passou a exigir verificação para credenciais novas, e a oferecer bibliotecas prontas — a razão da não verificação era quase sempre "dava trabalho".
Acesso à rede interna. Um pesquisador de segurança cadastrou uma URL apontando para o serviço de metadados da nuvem e recebeu, no corpo da resposta que a plataforma registrava em log, credenciais temporárias da instância. Corrigido com lista de bloqueio de faixas privadas, validação do IP resolvido, proibição de redirecionamentos e envio a partir de rede isolada.
O último foi classificado como o incidente mais grave da história da plataforma, e a equipe registra que ele era conhecido na literatura de segurança havia anos — faltou alguém fazer a pergunta "para onde exatamente nosso servidor está fazendo requisições?".
Conceitos Relacionados
- Integração por Mensageria — a alternativa interna.
- Integração Orientada a Eventos.
- Idempotência.
- Backoff — a espera entre tentativas.
Exercício Prático
Se você envia webhooks: o que acontece hoje se alguém cadastrar
http://169.254.169.254/ como destino?
Se você recebe: o processamento acontece dentro da requisição ou você enfileira? E o que seu código faz se o mesmo evento chegar duas vezes?
Perguntas de Entrevista
- Por que responder
200sem processar é perigoso? - Que risco de segurança uma URL de destino arbitrária cria?
- Por que um receptor lento afeta outros receptores?
Para Aprofundar
- Documentação de webhooks do Stripe — referência prática do padrão.
- OWASP. Server Side Request Forgery Prevention Cheat Sheet.
- Hohpe, Gregor; Woolf, Bobby. Enterprise Integration Patterns, 2003.