- Webhook é uma URL que seu sistema expõe para receber dados de outros sistemas em tempo real — modelo push, não pull
- O padrão é sempre: evento ocorre → sistema envia HTTP POST → sua URL recebe JSON → você processa → responde 200
- n8n tem nó Webhook nativo que cria URL automaticamente, recebe payload e dispara workflows visuais
- Segurança obrigatória: validar assinatura HMAC, implementar idempotência, responder 200 em <5s
- 8 padrões prontos: pagamento→CRM, formulário→lead, commit→deploy, estoque→alerta, ticket→SLA e mais
- Para >10.000 webhooks/dia: adicionar fila (Redis/SQS) entre o receiver e o processamento
O que é um webhook (e por que não é uma API)
Uma API é como um telefone — você liga quando precisa de informação. Um webhook é como uma campainha — o sistema te avisa quando algo acontece.
Sem webhook, para saber se um pagamento foi aprovado, você precisa perguntar à API a cada X segundos (polling). Com webhook, o sistema de pagamento te avisa assim que o status muda. A diferença é fundamental:
| Característica | Polling (API) | Webhook (Push) |
|---|---|---|
| Modelo | Pull — você pergunta | Push — eles avisam |
| Latência | Depende do intervalo (5s a 5min) | Tempo real (1-3s) |
| Custo de uso | Requests constantes ($$ de API) | 1 request por evento |
| Complexidade | Loop + timer + retries | 1 endpoint que recebe POST |
| Desperdício | 90%+ dos polls retornam "nada mudou" | Zero — só recebe quando há evento |
| Confiabilidade | Você controla quando buscar | Depende do sistema enviar (retry policy) |
O fluxo técnico de um webhook
- Registro: Você informa uma URL sua ao sistema externo ("quando o evento X ocorrer, avise
https://meu-site.com/webhook/pagamento") - Evento: O evento ocorre no sistema externo (pagamento aprovado, formulário enviado, commit realizado)
- Disparo: O sistema faz um
HTTP POSTpara sua URL com um JSON descrevendo o evento - Processamento: Seu servidor recebe, valida a assinatura, processa o payload
- Resposta: Você responde com
HTTP 200 OKem menos de 5 segundos
Webhook não é streaming
Webhook é evento-por-evento (1 POST por evento). Para dados contínuos (chat em tempo real, feeds de preço, GPS tracking), use WebSocket ou Server-Sent Events (SSE). Webhook é para eventos discretos: "pagamento aprovado", "pedido criado", "commit pushed".
A regra de ouro do webhook: responda HTTP 200 em menos de 5 segundos, mesmo que o processamento demore mais. Se não responder a tempo, o sistema reenviará e criará duplicatas. Use fila assíncrona para processamentos longos.
Anatomia de um webhook: headers, payload, assinatura
Todo webhook bem implementado tem três partes:
1. Headers HTTP
POST /webhook/pagamento HTTP/1.1
Host: meu-site.com
Content-Type: application/json
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
X-Webhook-ID: evt_1234567890
X-Webhook-Timestamp: 1719849600
User-Agent: Stripe/1.0- Content-Type: Quase sempre
application/json. Formatos legados usamapplication/x-www-form-urlencoded. - X-Webhook-Signature: HMAC da payload — usado para validar que veio do sistema legítimo.
- X-Webhook-ID: ID único do evento — usado para idempotência (evitar processar duplicatas).
- X-Webhook-Timestamp: Timestamp do envio — usado para rejeitar webhooks muito antigos (replay attack).
2. Payload (body JSON)
{
"id": "evt_1234567890",
"type": "payment_intent.succeeded",
"created": 1719849600,
"data": {
"object": {
"id": "pi_abc123",
"amount": 19900,
"currency": "brl",
"customer": "cus_xyz789",
"metadata": {
"order_id": "ORD-2026-0042"
}
}
}
}O payload contém tudo que você precisa para processar o evento. Não faça chamada de volta à API para buscar mais dados — o payload deve ser auto-suficiente.
3. Retry policy
Se seu endpoint não responder 200, o sistema reenvia. Políticas de retry variam:
| Serviço | Retries | Backoff | Max delay |
|---|---|---|---|
| Stripe | Até 50 em 72h | Exponencial | 2h |
| GitHub | Até 3 | 10min entre retries | 30min |
| Slack | Até 3 em 30min | Linear | 30min |
| PagSeguro | Até 5 em 24h | Exponencial | 4h |
Sistemas de webhook reenviam em caso de falha ou timeout. Seu handler deve ser idempotente — receber o mesmo evento duas vezes não pode criar duplicatas. Use o ID do evento para deduplicação antes de processar.
Recebendo webhooks com n8n: configuração passo a passo
n8n tem um nó Webhook nativo que cria automaticamente uma URL receiver. É a forma mais rápida de receber webhooks sem escrever código.
Passo 1: Criar o workflow
- No n8n, crie um novo workflow
- Adicione o nó Webhook como trigger (primeiro nó)
- Configure: HTTP Method =
POST, Path =pagamento - O n8n gera a URL:
https://seu-n8n.com/webhook/pagamento
Passo 2: Testar com webhook.site ou curl
# Teste local com curl
curl -X POST https://seu-n8n.com/webhook/pagamento \
-H "Content-Type: application/json" \
-d '{"event": "payment.success", "amount": 199.00, "customer": "João"}'O payload aparece no painel do n8n. Cada campo (event, amount, customer) fica disponível via {{ $json.campo }} nos nós seguintes.
Passo 3: Processar e encadear ações
Após o nó Webhook, encadeie ações sem código:
- IF: Roteie por tipo de evento (
{{ $json.event }}=== "payment.success") - Google Sheets: Registre o pagamento em planilha compartilhada
- WhatsApp / Telegram: Notifique a equipe financeira
- HTTP Request: Chame outra API para atualizar status no CRM
- Respond to Webhook: Retorne resposta customizada ao sistema emissor
Ambientes: Test vs. Production
n8n tem duas URLs por webhook:
- Test URL: Funciona apenas quando o workflow está aberto no editor. Ideal para debug e desenvolvimento.
- Production URL: Funciona quando o workflow está ativado. Use esta URL no sistema externo.
Sempre teste com a Test URL primeiro, veja o payload no painel, e só então configure a Production URL no sistema externo.
Uma loja com 500 pedidos/dia usava polling a cada 5 minutos para verificar pagamentos. Com webhook Stripe → n8n → planilha + WhatsApp, a equipe de separação passou a receber notificação em 3 segundos após confirmação — zerou atraso operacional e economizou 2h/dia.
Testando webhooks em desenvolvimento local com ngrok
Sistemas externos precisam de uma URL pública para enviar webhooks. Em desenvolvimento, seu localhost não é acessível pela internet. Solução: ngrok cria um túnel público para seu servidor local.
Setup do ngrok
# Instalar ngrok
brew install ngrok # macOS
# ou: snap install ngrok # Linux
# ou: https://ngrok.com/download
# Cadastre-se (gratuito) e configure o authtoken
ngrok config add-authtoken SEU_TOKEN
# Expor o n8n local (porta 5678)
ngrok http 5678
# Saída:
# Forwarding https://abc123.ngrok-free.app -> http://localhost:5678Alternativas ao ngrok
| Ferramenta | Gratuita | Vantagem | Limitação |
|---|---|---|---|
| ngrok | Sim (1 túnel) | Mais popular, dashboard web | URL muda a cada sessão no free |
| Cloudflare Tunnel | Sim | Estável, URL fixa com domínio | Setup mais complexo |
| localhost.run | Sim | Sem instalação (SSH) | Menos features |
| webhook.site | Sim | Inspecionar payloads sem servidor | Não processa — apenas visualiza |
Fluxo de desenvolvimento recomendado
- Inicie n8n local:
npx n8n(porta 5678) - Inicie ngrok:
ngrok http 5678 - Crie workflow com nó Webhook no n8n
- Configure a URL do ngrok no sistema externo (Stripe, GitHub, etc.)
- Teste enviando eventos reais ou simulados
- Quando satisfeito, deploy o n8n em produção e troque a URL
Antes de programar qualquer handler, use webhook.site para receber e inspecionar o payload real do serviço. Copie o JSON e use como referência para configurar seus nós no n8n.
Segurança: as 5 regras obrigatórias para webhooks em produção
Regra 1: Validar a assinatura HMAC
Qualquer pessoa pode fazer um POST para sua URL. Para garantir que o payload veio do sistema legítimo, valide a assinatura HMAC que a maioria dos serviços inclui no header.
// No nó Function do n8n
const crypto = require('crypto');
const secret = $env.GITHUB_WEBHOOK_SECRET;
const signature = $input.first().headers['x-hub-signature-256'];
const payload = JSON.stringify($input.first().body);
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
if (signature !== expected) {
throw new Error('Assinatura inválida — descartando webhook');
}
return $input.all();Adicione esse nó Function imediatamente após o Webhook Trigger, antes de qualquer processamento.
Regra 2: Implementar idempotência
Sistemas de webhook reenviam quando não recebem 200. Seu handler deve ser idempotente — receber o mesmo evento duas vezes não pode criar duplicatas.
// Verificar se o evento já foi processado
const eventId = $json.id; // ID único do evento
const processed = await checkIfProcessed(eventId);
if (processed) {
return []; // Ignora — já processado
}
// Processar e registrar
await markAsProcessed(eventId);
return $input.all();Na prática com n8n: use um nó Google Sheets ou PostgreSQL para registrar IDs processados e verificar antes de continuar.
Regra 3: Responder 200 imediatamente
Responda HTTP 200 OK em menos de 5 segundos, independente de quanto o processamento demore. Se não responder a tempo, o sistema reenvia — criando duplicatas.
Para processamentos longos (>5s): aceite o webhook, responda 200, e processe assincronamente via fila.
Regra 4: Rejeitar timestamps antigos
Webhooks com timestamp de mais de 5 minutos atrás podem ser replay attacks. Verifique o header X-Webhook-Timestamp e rejeite se muito antigo:
const timestamp = parseInt($json.headers['x-webhook-timestamp']);
const now = Math.floor(Date.now() / 1000);
if (now - timestamp > 300) { // 5 minutos
throw new Error('Webhook muito antigo — possível replay attack');
}Regra 5: HTTPS obrigatório
Webhooks carregam dados potencialmente sensíveis (pagamentos, dados de clientes). Nunca exponha URLs HTTP em produção — apenas HTTPS com certificado válido. n8n em produção deve estar atrás de reverse proxy (nginx/Caddy) com SSL.
8 padrões de automação com webhooks prontos para produção
1. Pagamento aprovado → atualizar CRM + notificar equipe
Fluxo: Stripe/PagSeguro → n8n Webhook → Pipedrive (marcar deal como pago) + WhatsApp (time financeiro) + Google Sheets (registro)
ROI: Elimina verificação manual de pagamentos. Para 100 pagamentos/dia, economiza 2h/dia do financeiro.
2. Formulário enviado → qualificar lead + criar tarefa
Fluxo: RD Station/Typeform → n8n Webhook → GPT-4o mini (classificar intenção: quente/morno/frio) → CRM (criar lead com score) + Trello (card para SDR se quente)
ROI: SDRs focam em leads quentes em vez de triar todos manualmente.
3. Commit no GitHub → deploy + notificação
Fluxo: GitHub push webhook → n8n → IF (branch === "main") → SSH (script de deploy no servidor) + Slack (equipe engenharia)
ROI: Deploy automático em 30 segundos após merge, sem developer precisar fazer SSH manual.
4. Estoque crítico → alerta + pedido automático
Fluxo: ERP (webhook quando estoque < mínimo) → n8n → E-mail para fornecedor com pedido padrão + planilha de controle + Slack (gerente de compras)
ROI: Elimina rupturas de estoque. Pedidos automáticos 3× mais rápidos que verificação manual.
5. Ticket de suporte criado → classificar + rotear + SLA
Fluxo: Zendesk/Freshdesk webhook → n8n → GPT-4o mini (classificar: bug/dúvida/feature/urgente) → Atribuir para equipe correta → Iniciar timer de SLA
ROI: Tempo médio de primeira resposta cai 60% com roteamento automatizado.
6. Novo usuário cadastrado → onboarding automático
Fluxo: SaaS (webhook de signup) → n8n → E-mail de boas-vindas (Mailgun) + CRM (criar contato) + Slack (notificar CS) + After 3 days: e-mail de follow-up
ROI: Ativação de usuários aumenta 25-40% com onboarding automatizado vs. manual.
7. Nota fiscal emitida → enviar ao cliente + registrar
Fluxo: Sistema fiscal (webhook de NF emitida) → n8n → Download PDF da NF → E-mail para cliente com PDF + Google Drive (backup) + planilha fiscal
ROI: Elimina envio manual de NFs. Para 200 NFs/mês, economiza 1 dia inteiro.
8. Monitoramento de uptime → alerta escalonado
Fluxo: UptimeRobot/Better Stack (webhook de downtime) → n8n → IF (>5min) → Slack (time dev) → IF (>15min) → SMS/WhatsApp (CTO) → IF (>30min) → PagerDuty (on-call)
ROI: MTTR (tempo médio de recuperação) reduzido com escalonamento automático.
Debug e troubleshooting de webhooks
Problema: "O webhook não chega"
| Causa | Como verificar | Solução |
|---|---|---|
| Firewall bloqueando | Teste com webhook.site (URL externa) | Libere IPs do serviço emissor no firewall |
| URL errada | Verifique logs do n8n | Confirme: Production URL, não Test URL |
| Workflow desativado | Painel do n8n → toggle | Ative o workflow (Production URL só funciona ativado) |
| SSL inválido | Teste com curl -v | Verifique certificado Let's Encrypt |
| Serviço não configurou | Dashboard do serviço emissor | Verifique se o webhook foi registrado e ativado |
Problema: "O webhook chega mas o processamento falha"
- Payload diferente do esperado: Salve o raw payload em Google Sheets antes de processar. Compare com a documentação da API.
- Campo ausente: Nem todo evento tem todos os campos. Adicione nó IF para verificar existência antes de acessar.
- Timeout (>30s): n8n tem timeout de execução. Para processamentos longos, divida em 2 workflows: um recebe e salva, outro processa via Schedule Trigger.
Ferramentas de debug
- webhook.site: URL descartável que captura e exibe webhooks recebidos — ideal para inspecionar payload antes de programar.
- Requestbin (Pipedream): Similar ao webhook.site mas com mais features de inspeção.
- n8n Execution Log: Painel de execuções mostra payload recebido, saída de cada nó, e erros com stack trace.
- curl + jq: Simule webhooks manualmente:
curl -X POST URL -d '{"test": true}' | jq
Escalando webhooks: de 100 para 50.000 eventos/dia
Até 1.000 webhooks/dia: n8n direto
n8n processa webhooks em série (um por vez por workflow). Para até 1.000 webhooks/dia, a latência é aceitável e não precisa de fila. Configure:
- n8n com PostgreSQL como backend (não SQLite)
- Servidor com 2 vCPU / 4GB RAM
- Processamento rápido (cada webhook < 10s)
1.000 - 10.000 webhooks/dia: n8n com workers
n8n suporta modo queue com workers separados. O main process recebe webhooks e enfileira; workers processam em paralelo.
# Main (recebe webhooks)
N8N_EXECUTIONS_MODE=queue n8n start
# Worker 1 (processa)
n8n worker
# Worker 2 (processa em paralelo)
n8n workerCom 3 workers: capacidade de ~3.000-5.000 webhooks/dia sem degradação.
10.000 - 50.000 webhooks/dia: fila dedicada
Para volume alto, o receiver de webhook deve ser mínimo — aceita o payload, salva em fila, responde 200. O processamento é separado:
- Receiver: API minimalista (Express.js, 10 linhas) que recebe POST, valida assinatura, salva em Redis/SQS, responde 200
- Fila: Redis (Bull) ou AWS SQS para buffer de eventos
- Worker: n8n ou script Node/Python que consome a fila e processa
Essa arquitetura garante: resposta em <100ms, zero perda de webhook (fila persiste), processamento paralelo com N workers.
Monitoramento em produção
Métricas que você deve acompanhar:
- Webhooks recebidos/dia: Baseline para detectar anomalias (queda = sistema emissor com problema)
- Taxa de falha: % de webhooks que geraram erro no processamento. Meta: <1%
- Latência de processamento: Tempo entre receber e completar. Meta: <5s para 95% dos webhooks
- Duplicatas descartadas: Quantos webhooks foram ignorados por idempotência. Se alto (>10%), investigue retry excessivo
Conclusão: webhooks são a cola entre sistemas modernos
Webhooks transformaram a integração entre sistemas de "pergunte periodicamente" para "me avise quando acontecer". É o mecanismo padrão que conecta Stripe, GitHub, Slack, Zendesk, ERPs, CRMs e praticamente todo SaaS moderno.
Checklist para sua primeira integração webhook
- Escolha o evento: Identifique qual evento do sistema externo é o gatilho (pagamento, formulário, commit, ticket)
- Instale n8n:
docker run -d -p 5678:5678 n8nio/n8n - Crie o receiver: Nó Webhook como trigger do workflow
- Valide a segurança: HMAC, idempotência, HTTPS
- Encadeie as ações: CRM, planilha, notificação, API — tudo visual no n8n
- Monitore: Log de execuções, taxa de erro, latência
A regra de ouro: responda 200 rápido, valide antes de processar, e seja idempotente. Com essas três regras, seus webhooks funcionam de forma confiável e escalável.
Mapa Mental
Use ← → para navegar · Espaço para expandir