Visão Geral
Webhooks de eventos do CRM
O campo id_evento identifica o evento nas novas entregas. Guarde-o para ignorar repetições: a entrega é pelo menos uma vez, e retentativas mantêm o mesmo payload. Entregas antigas podem não conter esse campo. O destino precisa ser HTTPS público; endereços internos e redirecionamentos não são aceitos.
A API é você perguntando ao LeadCNPJ. O webhook é o inverso: o LeadCNPJ avisa o seu sistema assim que algo acontece no CRM — um negócio ganho, um lead convertido — sem que você precise ficar consultando. É o caminho para manter ERP, planilha, Zapier, n8n ou Make em dia sem polling.
Disponível a partir do plano Scale. Não entra no teste grátis.
Como ativar
- Abra Configurações › API e vá até Avisos automáticos do CRM (webhooks).
- Clique em Novo aviso, informe o endereço que recebe o aviso
(precisa ser
https://) e marque os eventos que ela deve receber. - Salve. Use Testar para disparar um evento de exemplo e confirmar que a
sua URL responde
2xx.
Você pode cadastrar mais de uma URL — cada uma assina os eventos que quiser. O webhook é da conta: em contas com equipe, os eventos de qualquer membro saem pela mesma URL.
Eventos
| Evento | Quando dispara | Campos em dados |
|---|---|---|
negocio.ganho |
Oportunidade marcada como ganha (pela ficha ou arrastando no Kanban) | id_oportunidade, titulo, valor_previsto, id_lead, status |
negocio.perdido |
Oportunidade marcada como perdida | os mesmos de negocio.ganho |
negocio.movido |
Oportunidade muda de estágio no funil | id_oportunidade, titulo, estagio_anterior, estagio_novo, estagio_nome, status |
lead.criado |
Lead novo no CRM | id_lead, nome, nome_empresa, cnpj_empresa, origem |
lead.convertido |
Lead passa para o status convertido | id_lead, nome, nome_empresa, status_anterior |
O que chega na sua URL
POST com Content-Type: application/json e
User-Agent: LeadCNPJ-Webhooks/1.0. O corpo tem sempre a mesma forma — o que muda é
dados:
{
"evento": "negocio.ganho",
"disparado_em": "2026-09-14T19:42:11-03:00",
"dados": {
"id_oportunidade": 4821,
"titulo": "Implantação — Metalúrgica Exemplo",
"valor_previsto": 18500.00,
"id_lead": 9013,
"status": "ganho"
}
}
Assinatura — confira antes de confiar
Cada entrega leva o header X-LeadCNPJ-Signature com o HMAC-SHA256 do
corpo exato da requisição, usando o secret que aparece no cadastro do
webhook:
X-LeadCNPJ-Signature: sha256=2f1c…
Sua URL é pública: sem conferir a assinatura, qualquer um que descubra o endereço consegue inventar um “negócio ganho” no seu sistema. Compare em tempo constante — comparação comum de string vaza o segredo pelo tempo de resposta:
# PHP
$corpo = file_get_contents('php://input');
$esperado = 'sha256=' . hash_hmac('sha256', $corpo, $SEU_SECRET);
if (!hash_equals($esperado, $_SERVER['HTTP_X_LEADCNPJ_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
# Python
import hmac, hashlib
esperado = 'sha256=' + hmac.new(SECRET.encode(), corpo, hashlib.sha256).hexdigest()
if not hmac.compare_digest(esperado, request.headers.get('X-LeadCNPJ-Signature', '')):
return '', 401
Calcule sobre os bytes crus do corpo, nunca sobre o JSON reserializado: um espaço a mais e a assinatura não bate.
Entrega, retentativa e desativação
- Responda rápido. O timeout é de 10s (5s para conectar).
Responda
2xxprimeiro e processe depois — se o seu processamento demorar, a entrega conta como falha. - At least once. A mesma entrega pode chegar mais de uma vez; trate o
recebimento como idempotente (por exemplo, guardando o
id_oportunidade+eventojá processados). - Retentativa exponencial: 10, 20, 40 e 80 minutos. Na 5ª falha a entrega é marcada como falhada e não é mais tentada.
- Redirecionamento não é seguido. Informe a URL final.
- A ordem não é garantida. Use
disparado_empara ordenar.
O histórico das últimas entregas — status HTTP, tentativas e erro — fica no próprio cartão do webhook em Configurações › API.
Antes de colocar em produção
- Assine só os eventos que você usa: cada evento a mais é uma entrega a mais para o seu servidor responder.
- Guarde o corpo recebido antes de processar — é o que permite reprocessar sem pedir nada de volta.
- Se a sua URL ficar fora do ar, os eventos daquele período não são reenviados depois da 5ª tentativa. Para reconciliar, consulte a API.