O que são webhooks e como integrar eventos entre sistemas
Entenda o que são webhooks, como diferem de uma API e como integrar eventos entre sistemas com segurança, retry e idempotência.
Você integrou dois sistemas e tudo funciona — mas só porque a cada minuto um cron dispara uma requisição perguntando "tem novidade?". Na esmagadora maioria das vezes a resposta é "não". Você está pagando banda, CPU e latência para descobrir que nada mudou. E quando algo de fato muda, o usuário espera até 60 segundos para ver o reflexo. Esse desperdício tem nome: polling. E o jeito de matá-lo é inverter a direção da conversa. É exatamente isso que um webhook faz.
O que é um webhook, em uma frase
Um webhook é uma requisição HTTP que um sistema envia automaticamente para uma URL sua quando um evento acontece. Em vez de você ficar perguntando "já chegou o pagamento?", o gateway de pagamento avisa você no instante em que o pagamento entra. A lógica se inverte: em vez de pull (você puxa o dado), você recebe um push (o dado é empurrado para você).
Por isso webhooks às vezes são chamados de "reverse API" ou "callback HTTP". Você não chama o serviço — o serviço chama você.
Polling versus webhook na prática
A diferença fica clara com números. Suponha que você queira saber quando um pedido muda de status.
Com polling, seu código roda em loop:
// A cada 30 segundos, pergunte se mudou algo
setInterval(async () => {
const pedido = await fetch('https://api.loja.com/pedidos/123');
const data = await pedido.json();
if (data.status === 'enviado') notificarCliente();
}, 30_000);
Isso são 2.880 requisições por dia para um único pedido — e o status muda talvez uma vez. Multiplique por 10 mil pedidos e você tem um problema de escala.
Com webhook, você registra um endpoint uma vez e espera. O servidor da loja faz o trabalho:
// Você só recebe quando algo de fato acontece
app.post('/webhooks/pedidos', (req, res) => {
const { evento, pedido } = req.body;
if (evento === 'pedido.enviado') notificarCliente(pedido);
res.sendStatus(200); // confirme rápido
});
Uma requisição, no momento certo. Zero desperdício.
Como o fluxo funciona de ponta a ponta
O ciclo de vida de um webhook tem três atores e quatro passos:
- Registro. Você informa ao provedor (Stripe, GitHub, Mercado Pago) qual URL deve receber as notificações e em quais eventos tem interesse. Isso costuma ser feito no painel do serviço ou via API.
- Evento. Algo acontece do lado do provedor — um pagamento é aprovado, um push chega ao repositório, um e-mail é aberto.
- Entrega. O provedor monta um payload (quase sempre JSON) e dispara um
POSTpara a sua URL. - Processamento. Seu endpoint recebe, valida, faz o que precisa e responde
2xxpara confirmar.
O detalhe que separa uma integração amadora de uma robusta está no passo 4. Webhooks são fire-and-forget do ponto de vista do provedor, mas com garantias: se você não responder 2xx rápido, ele vai tentar de novo.
Os três erros que derrubam integrações de webhook
1. Processar tudo de forma síncrona antes de responder
A maioria dos provedores espera uma resposta em poucos segundos (Stripe corta em torno de 20s, GitHub em 10s). Se seu handler chama um banco lento, gera um PDF e dispara um e-mail antes de responder 200, você vai estourar o timeout — e o provedor vai reenviar o mesmo evento, gerando duplicatas.
A regra de ouro: responda primeiro, processe depois. Enfileire o trabalho pesado.
app.post('/webhooks/pagamentos', async (req, res) => {
await fila.enqueue('processar-pagamento', req.body); // milissegundos
res.sendStatus(200); // confirma na hora
});
2. Confiar no payload sem verificar a assinatura
Sua URL de webhook é pública. Qualquer um que a descubra pode mandar um POST falso dizendo "pagamento aprovado". Por isso provedores sérios assinam cada requisição com um HMAC, geralmente em um header como X-Signature. Você recalcula o hash com seu segredo compartilhado e compara.
import crypto from 'crypto';
function assinaturaValida(corpoBruto, assinatura, segredo) {
const esperada = crypto
.createHmac('sha256', segredo)
.update(corpoBruto)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(esperada),
Buffer.from(assinatura)
);
}
Use sempre timingSafeEqual (comparação de tempo constante) para não vazar informação por timing attack. E valide sobre o corpo bruto, não sobre o JSON já parseado e re-serializado — a ordem das chaves muda e a assinatura quebra.
3. Não lidar com reentrega e ordem
Webhooks oferecem garantia de entrega at-least-once, não exactly-once. O mesmo evento pode chegar duas vezes (porque sua resposta 200 se perdeu, por exemplo). E nada garante que os eventos cheguem na ordem em que aconteceram. A solução é tornar seu handler idempotente: cada evento traz um ID único, e você guarda os IDs já processados.
if (await jaProcessado(evento.id)) return res.sendStatus(200);
await processar(evento);
await marcarProcessado(evento.id);
Onde webhooks brilham (e onde não)
Webhooks são a escolha certa quando: pagamentos (confirmação assíncrona), CI/CD (um push dispara o pipeline), comunicação entre microsserviços, integrações no-code via Zapier/Make, e notificações em chat (deploy concluído avisa o Slack).
Mas não são bala de prata. Se você precisa de uma resposta imediata e bidirecional — como um chat em tempo real ou um dashboard que atualiza a cada tick — WebSockets ou Server-Sent Events servem melhor. E se o consumidor não consegue expor um endpoint público (um app mobile, por exemplo), webhook não se aplica; aí você cai em polling ou push notifications.
Vale notar que webhook e REST não competem: webhooks normalmente são implementados sobre os mesmos princípios de uma boa API HTTP. Se você ainda está modelando seus endpoints, os mesmos cuidados com verbos, status codes e versionamento que descrevo em REST API: princípios e boas práticas se aplicam ao endpoint que recebe o webhook.
Como testar webhooks sem virar a noite
O problema clássico: o provedor precisa de uma URL pública, mas seu código roda em localhost. Três caminhos resolvem:
- Túnel local: ferramentas como
ngrokoucloudflaredexpõem sua porta local com uma URL HTTPS temporária. Você cola essa URL no painel do provedor e os eventos chegam direto na sua máquina. - CLI do próprio provedor: Stripe e GitHub têm CLIs (
stripe listen,gh webhook forward) que repassam eventos reais para o localhost sem túnel. - Inspetores de requisição: sites como webhook.site dão uma URL descartável que mostra exatamente o payload e os headers recebidos — ótimo para entender o formato antes de escrever uma linha de código.
Comece pelo inspetor para ver o formato, depois passe para o túnel quando for codar o handler de verdade.
Perguntas frequentes
Qual a diferença entre webhook e API?
Uma API (REST) é você quem chama: faz uma requisição e recebe a resposta na hora (pull). Um webhook é o contrário: o servidor é quem chama você quando um evento ocorre (push). Na prática um webhook é entregue através de uma API HTTP, mas a direção da iniciativa é invertida. Use API quando precisa do dado agora; use webhook quando quer ser avisado quando o dado mudar.
Webhook é seguro?
Pode ser, desde que você faça três coisas: sirva o endpoint só por HTTPS, verifique a assinatura HMAC de cada requisição (para confirmar que veio mesmo do provedor) e trate o handler como idempotente. Sem verificação de assinatura, qualquer um que descubra sua URL pode forjar eventos — então essa etapa não é opcional.
O que acontece se meu servidor estiver fora do ar quando o evento dispara?
A maioria dos provedores tem política de retry: se você não responder 2xx, eles reenviam o evento com backoff exponencial por horas ou dias. Mesmo assim, projete para falhas — registre eventos perdidos e, se o provedor oferecer, use a API de "reenviar evento" ou um endpoint de listagem para reconciliar o que ficou para trás.
Posso usar webhooks entre meus próprios microsserviços internos?
Sim, e é um padrão comum. Mas internamente, onde você controla os dois lados, costuma valer mais a pena uma fila de mensagens (RabbitMQ, Kafka, SQS) ou um event bus — eles dão garantias de ordem, retry e persistência sem você reimplementar tudo. Webhooks HTTP fazem mais sentido quando uma das pontas é um sistema externo que você não controla.
O que levar deste guia
Webhook não é uma tecnologia nova nem complicada: é só um POST HTTP no momento certo, em vez de mil GET no escuro. O que separa uma integração que aguenta produção de uma que vai te acordar de madrugada não é o protocolo — é a disciplina nos três pontos críticos: responda rápido e processe em background, verifique a assinatura de toda requisição, e torne o handler idempotente. Acerte esses três e você terá um pipeline de eventos confiável entre quaisquer sistemas.
- 01 UTF-8 e problemas de encoding: por que acentos quebram e como resolver O que é UTF-8, code points, mojibake e por que "configuração" vira "configuração" — o mecanismo explicado ponta a ponta.
- 02 Calendário do INSS 2026: datas de pagamento da aposentadoria por final do benefício Veja quando cai a aposentadoria e os benefícios do INSS em agosto de 2026, pelo final do número do benefício. Tem tabela para quem recebe até 1 salário mínimo e para quem recebe acima, o reajuste do ano e o teto.