"Webhooks de eventos: avise seus sistemas quando algo acontece no CRM"
Cadastre endereços que recebem um aviso automático quando um lead entra, muda de etapa no funil ou fecha uma venda — para montar automações no n8n, no Make ou no seu próprio sistema.
A API de integrações é o caminho de entrada: o seu sistema fala com o CRM. Os webhooks são o caminho de saída: o CRM avisa o seu sistema quando algo acontece.
É o que permite montar automações que reagem ao que a sua equipe faz — lead novo entra numa planilha, venda concluída dispara a nota fiscal, mudança de etapa avisa o gestor.
Como cadastrar
Em Configurações → Integrações, no card Webhooks de eventos:
- Adicionar webhook
- Dê um nome (para você diferenciar depois) e cole o endereço do seu fluxo — por exemplo, a URL de um nó Webhook do n8n.
- Marque os eventos que esse endereço deve receber.
- Clique em Enviar teste (o ícone de avião no card) para confirmar que o endereço responde.
Você pode ter até 5 webhooks, cada um com a sua própria lista de eventos. Serve para separar automações: um endereço só para vendas, outro só para o funil.
Quais eventos existem
Contatos
| Evento | Quando dispara |
|---|---|
contact.created | Lead novo entra na base, por qualquer caminho |
contact.qualified | Marcado como qualificado |
contact.owner_assigned | Lead ganhou um responsável |
contact.tag_added | Etiqueta aplicada |
contact.tag_removed | Etiqueta retirada |
Funil
| Evento | Quando dispara |
|---|---|
card.created | Card criado no funil |
card.stage_changed | Card mudou de etapa (transição de verdade — criar o card não conta) |
card.won | Chegou na etapa de Ganho |
card.lost | Chegou na etapa de Perdido |
Conversas e mensagens
| Evento | Quando dispara |
|---|---|
conversation.opened | Conversa aberta com o contato |
conversation.closed | Conversa marcada como resolvida |
message.received | O lead escreveu |
message.sent | Saiu uma mensagem para o lead |
Vendas, agenda e tarefas
| Evento | Quando dispara |
|---|---|
sale.completed | Venda concluída |
sale.reverted | Venda que estava concluída saiu desse estado |
appointment.created | Novo horário na agenda |
appointment.status_changed | Concluído, cancelado ou falta |
task.created | Nova tarefa |
task.completed | Tarefa concluída |
⚠️ Eventos de mensagem são muito mais frequentes que os outros — várias vezes por conversa, contra uma vez por lead. Assine se o seu fluxo realmente precisa acompanhar cada mensagem (é o caso de quem orquestra um agente de IA pelo n8n). Para reagir a fatos do funil, os outros eventos bastam e o histórico fica bem mais legível.
O que chega no seu endereço
Um POST com JSON neste formato:
{
"event": "card.stage_changed",
"event_id": "8f3c…",
"tenant_id": "1a2b…",
"timestamp": "2026-08-04T18:12:03.120Z",
"data": {
"card_id": "…",
"contact_id": "…",
"from_stage": { "id": "…", "nome": "Em conversa" },
"to_stage": { "id": "…", "nome": "Negociação" },
"movido_por": "usuario",
"entered_at": "2026-08-04T18:12:03.101Z"
},
"contact": {
"id": "…",
"nome": "João Silva",
"telefone": "5566999998888",
"email": "joao@exemplo.com",
"origem": "ads",
"lead_de_anuncio": true,
"utm": { "utm_source": "adwords", "utm_campaign": "22596778714" },
"click_ids": { "gclid": "Cj0KCQ…" },
"etiquetas": ["Orçamento enviado"],
"criado_em": "2026-08-01T10:00:00.000Z"
}
}
datamuda conforme o evento e descreve o fato, do jeito que ele era quando aconteceu.contacté o estado do contato no momento do envio, e vem em todo evento ligado a um lead. Vemnullquando o evento não tem contato.movido_porvale"usuario"quando uma pessoa fez a ação e"sistema"quando foi automação, IA, cron ou API.
Nos eventos de mensagem o data traz ainda conversation.janela_24h_aberta, conversation.ia_ativa e, quando há anexo, um link temporário em data.media.url — ele vale 1 hora, então baixe o arquivo assim que receber.
Cabeçalhos
| Cabeçalho | Para quê |
|---|---|
X-Scala-Event | O tipo do evento, para rotear sem abrir o corpo |
X-Scala-Delivery | Identificador da entrega — use para ignorar repetição |
X-Scala-Timestamp | Quando o envio foi feito |
X-Scala-Signature | A assinatura (abaixo) |
Conferindo a assinatura
Cada webhook tem um segredo próprio, visível ao editar. O X-Scala-Signature é sha256= seguido do HMAC-SHA256 do corpo cru da requisição com esse segredo.
Em Node:
const crypto = require("crypto");
function assinaturaConfere(corpoCru, cabecalho, segredo) {
const esperado =
"sha256=" + crypto.createHmac("sha256", segredo).update(corpoCru).digest("hex");
return crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(cabecalho));
}
Compare com o corpo exatamente como chegou — se o seu framework converter para objeto e você serializar de novo, a assinatura não bate.
Esse segredo é diferente da chave de API. Girar um não afeta o outro: a chave dá acesso de entrada ao CRM, o segredo só serve para você confirmar que o POST veio mesmo daqui.
Se der errado
O CRM tenta 5 vezes, esperando cada vez mais entre elas (1, 5, 15 e 60 minutos). Qualquer resposta fora da faixa 2xx conta como falha.
Clique no ícone de lista no card para ver as Entregas: as 50 mais recentes com evento, horário, código HTTP, mensagem de erro e o conteúdo enviado. Cada uma tem um botão Reenviar — útil depois de consertar a URL ou o fluxo. O histórico guarda 30 dias.
Se um endereço falhar 20 vezes seguidas, ele é desativado automaticamente e os administradores recebem um aviso no sino. É proteção: um endereço fora do ar acumularia entregas indefinidamente. Corrija a URL e ligue a chavinha de novo.
Perguntas comuns
Responder rápido importa? Sim. O CRM espera até 10 segundos. Se o seu fluxo demora, responda 200 imediatamente e processe depois — é o padrão em qualquer webhook.
O mesmo evento pode chegar duas vezes? Pode, em situações de rede. Use o X-Scala-Delivery para ignorar repetição: a mesma entrega mantém o identificador entre as tentativas.
Vários webhooks recebem o mesmo evento? Sim, se os dois assinarem. As entregas compartilham o event_id, então dá para saber que se trata do mesmo acontecimento.
Preciso de endereço público? Sim, e com https. Endereço interno, localhost ou IP de rede privada são recusados por segurança.
Já uso o n8n para o agente de IA. Mudou alguma coisa? Não — aquele caminho continua igual, agora dentro do card API de integrações. Mas dá para fazer o mesmo com um webhook assinando message.received e message.sent, com a vantagem de escolher os eventos e ter o histórico de entregas.
