Documentação de webhooks

Webhook é o CRM avisando o outro sistema no instante em que algo acontece aqui. Para o caminho contrário — um sistema de fora consultando ou criando registros —, veja a documentação da API.

Nesta página

Como funciona#

Você cadastra um endereço seu e marca os eventos. Quando um deles acontece, enviamos uma requisição assinada para lá.

  1. 1. Algo acontece no CRM (entrou um lead, a venda mudou de etapa, um pagamento foi confirmado).
  2. 2. O Dommu envia um POST com corpo JSON para a sua URL, assinado com o secret daquele webhook.
  3. 3. O outro sistema confere a assinatura e responde 2xx. Qualquer outra resposta (ou silêncio por mais de 10 segundos) conta como falha.
  4. 4. Falhou, tentamos de novo — e o resultado de cada tentativa fica no histórico de entregas do webhook.

Configurar#

Precisa de um endereço público em HTTPS que aceite POST. Endereço interno (localhost, rede privada) é recusado.

  1. 1. Crie o webhook com um nome que diga para onde vai e a URL de destino.
  2. 2. Marque os eventos que aquele destino recebe — dá para mudar depois, a qualquer momento.
  3. 3. Guarde o secret exibido na criação: ele aparece uma vez só e é com ele que você confere a assinatura.
  4. 4. Use o botão Enviar teste na página do webhook: ele dispara um evento de exemplo agora e mostra a resposta do outro sistema.

Se o seu endpoint exige um token próprio, adicione um cabeçalho personalizado na configuração do webhook. Os cabeçalhos de assinatura do Dommu não podem ser sobrescritos.

O que chega#

Todo evento chega no mesmo envelope; só o conteúdo de data muda de um evento para outro.

Corpo da requisição

{
  "id": "9f2c1e04-5b3a-4c8e-9f77-1a2b3c4d5e6f",
  "evento": "LEAD_CREATED",
  "timestamp": "2026-07-25T14:02:11.482Z",
  "organizationId": "cmd6y1a2b0000",
  "data": {
    "leadId": "cmd9x2v4k0001",
    "nome": "Maria Silva",
    "celular": "11999998888"
  }
}
  • · id — identificador da entrega. É o mesmo entre as tentativas do mesmo envio: use-o para não processar duas vezes.
  • · evento — a chave do evento (a mesma da tela de eventos).
  • · timestamp — quando aconteceu, em ISO 8601 com fuso.
  • · data — os dados do recurso. Campos novos podem ser acrescentados com o tempo, então ignore o que não conhece em vez de recusar.

Cabeçalhos#

Toda entrega leva estes cabeçalhos:

  • X-Webhook-SignatureHMAC-SHA256 do corpo cru, assinado com o secret do webhook
  • X-Webhook-DeliveryId da entrega — igual entre as tentativas do mesmo envio
  • X-Webhook-EventChave do evento (ex.: LEAD_CREATED)
  • X-Webhook-TimestampQuando o evento ocorreu
  • X-Webhook-IdId do webhook que originou a entrega
  • User-AgentDommu-Webhook/1.0

Verificar a assinatura#

Sem essa conferência, qualquer um que descubra a sua URL consegue fingir ser o Dommu. É a parte mais importante desta página.

Node.js

import crypto from 'crypto'

function assinaturaValida(corpoCru, header, secret) {
  const esperada = crypto.createHmac('sha256', secret).update(corpoCru).digest('hex')
  const a = Buffer.from(esperada)
  const b = Buffer.from(header ?? '')
  return a.length === b.length && crypto.timingSafeEqual(a, b)
}

Recebendo (Express)

// Express — receba o corpo CRU para conseguir verificar a assinatura
app.post('/webhooks/dommu',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const assinatura = req.header('X-Webhook-Signature')
    if (!assinaturaValida(req.body, assinatura, process.env.DOMMU_WEBHOOK_SECRET)) {
      return res.sendStatus(401)
    }

    // Responda JÁ: processe depois, fora do ciclo da requisição.
    res.sendStatus(200)

    const evento = JSON.parse(req.body.toString('utf8'))
    processarEmSegundoPlano(evento)
  })

Assine o corpo exatamente como recebido, antes de qualquer parse: reserializar o JSON muda os bytes e invalida a comparação. Compare em tempo constante (timingSafeEqual), nunca com ===.

Tentativas e duplicidade#

Cada tentativa espera até 10 segundos pela sua resposta. Sem 2xx, tentamos de novo: 3 tentativas no total, com 1s e 2s de intervalo.

Como o id da entrega é o mesmo em todas as tentativas, guarde os ids já processados e descarte repetidos — é o que evita criar o mesmo registro duas vezes do seu lado quando a sua resposta se perde no caminho.

Depois da última tentativa, a entrega é marcada como falha e fica registrada no histórico do webhook, com o código de resposta e o motivo. Nada é reenviado sozinho depois disso.

Boas práticas#

Faça

  • Responder 2xx imediatamente e processar depois, fora do ciclo da requisição
  • Verificar a assinatura em toda requisição
  • Deduplicar pelo id da entrega
  • Ignorar campos desconhecidos em data
  • Um webhook por destino, com só os eventos daquele destino

Evite

  • Processar tudo antes de responder (estoura os 10 segundos)
  • Confiar na URL como segredo, sem conferir a assinatura
  • Assumir que cada evento chega uma única vez
  • Recusar o corpo por causa de um campo novo
  • Cadastrar um webhook com todos os eventos “por garantia”

Eventos disponíveis#

São 19 avisos, agrupados por assunto. Na tela de eventos você liga cada um aos destinos que quiser.

Leads

  • Lead criadoLEAD_CREATED
  • Lead atualizadoLEAD_UPDATED
  • Etapa do lead alteradaLEAD_STATUS_CHANGED
  • Lead atribuídoLEAD_ASSIGNED

Imóveis

  • Imóvel criadoIMOVEL_CREATED
  • Imóvel atualizadoIMOVEL_UPDATED
  • Status do imóvel alteradoIMOVEL_STATUS_CHANGED

Vendas

  • Proposta criadaVENDA_CREATED
  • Proposta atualizadaVENDA_UPDATED
  • Status da proposta alteradoVENDA_STATUS_CHANGED
  • Etapa da venda alteradaVENDA_ETAPA_CHANGED

Atividades

  • Tarefa criadaTAREFA_CREATED
  • Tarefa concluídaTAREFA_COMPLETED
  • Visita agendadaVISITA_AGENDADA

Financiamento

  • Simulação criadaSIMULACAO_CREATED

Contratos

  • Contrato criadoCONTRATO_CREATED
  • Status do contrato alteradoCONTRATO_STATUS_CHANGED

Financeiro

  • Pagamento registradoPAGAMENTO_REGISTRADO
  • Ocorrência criadaOCORRENCIA_CREATED
Escolher quem recebe cada evento

Zapier, Make e n8n#

Crie a URL na ferramenta, cadastre-a aqui como destino e mande um teste — o evento aparece lá na hora.

Zapier

Gatilho “Webhooks by Zapier” → Catch Hook

Make

Módulo Webhooks → Custom webhook

n8n

Nó Webhook (método POST)

Essas ferramentas não conferem a assinatura sozinhas. Para um fluxo que só move dado interno (planilha, aviso no chat) isso costuma bastar; se o evento vai disparar algo sensível, faça a verificação num passo de código antes de agir. O endereço do CRM, se precisar chamar de volta, é https://api.dommu.app.