Voltar para CRM

Integrações

Webhooks de saída

Avise o seu ERP, planilha ou automação quando um negócio for ganho, mudar de etapa ou for pago.

Quem pode: Administrador do workspace.

  1. Em CRM > Configurar > Integrações, vá até Webhooks de saída e clique em Novo webhook.
  2. Dê um nome e o endereço (https público, porta padrão).
  3. Marque os eventos (por exemplo Ganho, Mudou de etapa, Pagamento recebido).
  4. Se quiser só uma parte dos negócios, marque Funis, Etapas ou Equipes. Sem marcar nada, vale para todos. A etapa vale para o negócio que está nela ou acabou de entrar; a equipe é a do responsável ou a do próprio negócio.
  5. Clique em Criar webhook. Copie o segredo (whsec_...), que aparece uma vez, e clique em Já guardei.
  6. Clique em Testar para mandar um evento de exemplo e veja o resultado em Entregas.

O que chega

  • O evento (id, tipo, quando, quem fez) e um retrato curto do negócio (número, título, situação, funil, etapa, valor, responsável).
  • Nenhum dado pessoal do contato vai no corpo. Quem recebe busca pela API, com uma chave de escopo próprio.
  • Cabeçalhos: x-crm-signature, x-crm-timestamp, x-crm-event e x-crm-delivery.
Verificar a assinatura (Node.js)
// Node.js (Express). Leia o corpo cru, antes de qualquer JSON.parse.
import crypto from "node:crypto";
import express from "express";

const SEGREDO = process.env.CRM_WEBHOOK_SECRET; // whsec_... mostrado ao criar o webhook
const app = express();

app.post("/crm", express.raw({ type: "application/json" }), (req, res) => {
  const timestamp = req.header("x-crm-timestamp");
  const assinatura = req.header("x-crm-signature") ?? "";
  const corpo = req.body.toString("utf8");

  // 1. Recuse avisos com mais de 5 minutos de diferença.
  if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
    return res.status(400).send("timestamp fora do prazo");
  }

  // 2. Calcule a assinatura esperada: v1= + HMAC-SHA256 em hexadecimal de "timestamp.corpo".
  const esperada = "v1=" + crypto.createHmac("sha256", SEGREDO).update(timestamp + "." + corpo).digest("hex");
  const ok = esperada.length === assinatura.length &&
    crypto.timingSafeEqual(Buffer.from(esperada), Buffer.from(assinatura));
  if (!ok) return res.status(401).send("assinatura inválida");

  // 3. Descarte repetição pelo id da entrega (x-crm-delivery) e responda rápido com 2xx.
  const evento = JSON.parse(corpo);
  console.log(req.header("x-crm-event"), req.header("x-crm-delivery"), evento);
  res.sendStatus(204);
});

Falhas e novas tentativas

  • Se o destino não responde 2xx, tenta de novo em 1 min, 5 min, 30 min, 2 h e 6 h. Depois disso, a entrega fica como falhou e pode ser reenviada com Reenviar.
  • Vinte falhas seguidas desligam o webhook com o motivo. Reativar liga de novo e zera o contador.
  • Para trocar o segredo, edite o webhook e marque Gerar um segredo novo ao salvar.

Ir para a tela

Veja também