Receber eventos por webhook
Cadastre um webhook, entenda o formato de cada entrega, confira a assinatura HMAC e trate as novas tentativas.
Atualizado em 12 de novembro de 2026
Com um webhook, o Cognizy avisa o seu sistema na hora em que algo acontece: conversa nova, contato criado, negócio ganho, pagamento confirmado. Você não precisa ficar consultando a API.
1. Cadastre o webhook
Pela tela: Configurações › Integrações › API e webhooks, aba Webhooks, botão Novo webhook. Informe a URL (https) e marque os eventos.
Pela API (permissão webhooks:manage):
curl -X POST https://api.cognizy.ai/api/v1/public/webhooks \
-H "Authorization: Bearer $COGNIZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/webhooks/cognizy","events":["contact.created","deal.won"],"description":"CRM interno"}'A resposta traz o secret do webhook uma vez só. Guarde: é com ele que você confere a assinatura.
2. O que chega no seu sistema
Cada entrega é um POST com corpo JSON:
{
"id": "dlv_8f2c1a",
"event": "deal.won",
"timestamp": "2026-11-12T14:03:22.418Z",
"data": {
"id": "deal_123",
"title": "Plano anual",
"value": 4800,
"stage": "WON",
"contactId": "contact_456"
}
}E estes cabeçalhos:
Content-Type: application/json
User-Agent: Cognizy-Webhook/1.0
X-Cognizy-Event: deal.won
X-Cognizy-Delivery: dlv_8f2c1a
X-Cognizy-Webhook-Id: wh_123
X-Cognizy-Signature: t=1762956202,v1=5f0c…O data é o registro do evento (o negócio, o contato, a conversa…), no mesmo formato da API. Os campos acima são um exemplo.
3. Confira a assinatura
A assinatura é HMAC-SHA256(secret, t + "." + corpo), em hexadecimal, no v1. Sempre confira antes de usar o evento: sem isso, qualquer um que descubra a URL consegue mandar eventos falsos.
- Use o corpo cru, exatamente como chegou. Se o seu framework já transformou em objeto, a assinatura não bate.
- Recuse se o
ttiver mais de 5 minutos (evita reenvio de uma entrega antiga). - Durante a troca do segredo, o cabeçalho traz dois
v1por 24 h: aceite se qualquer um bater.
Com o SDK (Node e Express):
import express from 'express'
import { verifyWebhookSignature } from '@cognizy/sdk'
const app = express()
app.post('/webhooks/cognizy', express.raw({ type: 'application/json' }), (req, res) => {
const ok = verifyWebhookSignature({
secret: process.env.COGNIZY_WEBHOOK_SECRET!,
body: req.body, // Buffer cru
header: req.header('x-cognizy-signature'),
})
if (!ok) return res.status(400).send('assinatura inválida')
const event = JSON.parse(req.body.toString('utf8'))
// trate o evento (em fila, se for demorado)
res.status(200).send('ok')
})Sem o SDK, em Python:
import hashlib, hmac, time
def assinatura_valida(secret: str, corpo: bytes, cabecalho: str, tolerancia=300) -> bool:
partes = [p.split("=", 1) for p in cabecalho.split(",") if "=" in p]
t = next((v for k, v in partes if k == "t"), None)
assinaturas = [v for k, v in partes if k == "v1"]
if not t or not assinaturas or abs(time.time() - int(t)) > tolerancia:
return False
esperado = hmac.new(secret.encode(), f"{t}.".encode() + corpo, hashlib.sha256).hexdigest()
return any(hmac.compare_digest(esperado, v) for v in assinaturas)4. Responda rápido e trate repetições
- Responda com um código 2xx em até 15 segundos. Se a tarefa for longa, coloque o evento numa fila e responda logo.
- Sem 2xx, o Cognizy tenta de novo, até 5 tentativas no total: depois de 10 s, 1 min, 5 min e 30 min.
- A mesma entrega pode chegar mais de uma vez. Use o
id(ou o cabeçalhoX-Cognizy-Delivery) para não processar duas vezes.
Para ver as entregas e reenviar uma que falhou: GET /v1/public/webhooks/{id}/deliveries e POST /v1/public/webhooks/deliveries/{deliveryId}/replay. Para testar a URL, POST /v1/public/webhooks/{id}/test manda um evento webhook.test.
Trocar o segredo
POST /v1/public/webhooks/{id}/rotate-secret gera um segredo novo. O antigo continua valendo por 24 h, então dá tempo de atualizar o seu sistema sem perder evento.
Eventos
| Área | Eventos |
|---|---|
| Conversas | conversation.created, conversation.updated, conversation.closed, conversation.assigned, conversation.unassigned, conversation.ai_handoff, conversation.sla_breached, conversation.tag.added, conversation.tag.removed, csat.received |
| Mensagens | message.created, message.received |
| Contatos | contact.created, contact.updated, contact.deleted, contact.tag.added, contact.tag.removed, contact.scored, contacts.imported |
| Vendas | deal.created, deal.updated, deal.stage_changed, deal.won, deal.lost, deal.deleted, proposal.sent, proposal.viewed, proposal.accepted, proposal.rejected |
| Pagamentos | payment.created, payment.completed, payment.receipt_received |
| Agenda | appointment.created, appointment.rescheduled, appointment.cancelled |
| Chamados | ticket.created, ticket.assigned, ticket.updated, ticket.resolved, ticket.closed, ticket.reopened, ticket.sla_breached |
| Tarefas | task.created, task.moved, task.completed, task.updated, task.assigned |
| Envios diretos | whatsapp.message.status, email.message.status |
A lista completa, sempre atualizada, aparece na janela Novo webhook e na rota de webhooks da referência.