Skip to main content

O que são webhooks

Webhooks permitem que a Cordialy notifique seu sistema quando eventos acontecem — sem você precisar fazer polling à API. São ideais para sincronização em tempo real com CRMs, ERPs e automações. Configure em Plataforma → Integrações → Webhooks.

Eventos disponíveis

EventoQuando dispara
lead.createdNovo lead criado (via WhatsApp ou API)
lead.status_changedStatus do lead foi alterado
message.receivedLead enviou uma mensagem via WhatsApp
message.sentIA ou consultor enviou uma mensagem
session.startedNova sessão de atendimento aberta
session.endedSessão de atendimento encerrada
followup.sentFollow-up automático foi disparado

Formato do payload

Todos os eventos seguem a mesma estrutura:
{
  "event": "lead.status_changed",
  "timestamp": "2026-06-20T14:30:00.000Z",
  "store_id": "store-uuid",
  "data": {
    "lead_id": "lead-uuid",
    "previous_status": "pending",
    "new_status": "converted"
  }
}

Payload por evento

{
  "event": "lead.created",
  "data": {
    "lead_id": "...",
    "name": "João Silva",
    "customer_phone": "5511999998888",
    "status": "pending"
  }
}
{
  "event": "message.received",
  "data": {
    "lead_id": "...",
    "message_id": "...",
    "content": "Olá, quero saber o preço",
    "media_type": null
  }
}
{
  "event": "session.ended",
  "data": {
    "lead_id": "...",
    "session_id": "...",
    "status": "converted",
    "started_at": "2026-06-20T09:00:00Z",
    "ended_at": "2026-06-20T14:30:00Z"
  }
}

Validar a assinatura

Cada requisição inclui o header X-Cordialy-Signature com um HMAC-SHA256 do payload assinado com seu Webhook Secret. Valide sempre antes de processar:
import crypto from 'crypto';

function verificarWebhook(payload: string, signature: string, secret: string): boolean {
  const esperado = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(esperado, 'hex')
  );
}

// Em Express:
app.post('/webhook/cordialy', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-cordialy-signature'] as string;
  const valido = verificarWebhook(req.body.toString(), signature, process.env.WEBHOOK_SECRET);

  if (!valido) return res.status(401).json({ error: 'Assinatura inválida' });

  const evento = JSON.parse(req.body.toString());
  // processa evento...

  res.status(200).json({ received: true });
});
Sempre valide a assinatura antes de processar o evento. Sem validação, qualquer pessoa pode enviar dados falsos para seu endpoint.

Retry automático

Se seu endpoint retornar status diferente de 2xx, a Cordialy tentará reenviar com backoff exponencial:
TentativaDelay
Imediato
1 minuto
5 minutos
30 minutos
2 horas
Após 5 tentativas sem sucesso, o evento é descartado.

Boas práticas

Retorne 200 OK imediatamente e processe o evento em background. Endpoints lentos causam timeouts e retries desnecessários.
app.post('/webhook', async (req, res) => {
  res.status(200).json({ received: true }); // responde primeiro
  await processarEvento(req.body);           // processa depois
});
Por causa dos retries, o mesmo evento pode chegar mais de uma vez. Use o message_id ou lead_id + timestamp como chave de deduplicação.
O endpoint precisa ser HTTPS com certificado válido. HTTP ou certificados autoassinados são rejeitados.