Webhooks
BetaReceba notificações em tempo real quando eventos importantes acontecem na Riskora — sem precisar fazer polling. Ideal para integrações transacionais com ERP, sistemas de checkout, CRM e ferramentas de comunicação interna.
Funcionalidade em Beta
O catálogo de eventos abaixo é o contrato público que vamos entregar. A implementação está sendo finalizada — o lançamento para clientes acontece ao longo do trimestre. O formato dos payloads e eventos documentados aqui é estável e não sofrerá breaking changes no lançamento.
Quer participar do beta e integrar antes do lançamento geral? Fale com nossa equipe.
Quando usar webhooks
A API REST da Riskora permite consultar o estado de qualquer análise a qualquer momento. Mas consultar em loop (polling) é caro, lento e pouco elegante quando você precisa reagir no segundo que algo muda. Webhook é o mecanismo canônico para:
- Checkout transacional: cliente esperando aprovação — cada segundo importa. Receba
analysis.finalizede libere o pedido automaticamente. - Alerta de equipe: análise caiu em revisão manual — notifique o analista de plantão via Slack, Teams ou sistema de tickets.
- Sincronização de ERP: mantenha o limite de crédito do cliente no seu ERP sempre atualizado — sem cron diário, sem polling.
- Notificação ao vendedor: vendedor recebe aviso imediato quando sua análise é aprovada, rejeitada ou precisa de reenvio de documentos.
Catálogo de eventos
analysis.finalized
A análise transitou para um estado final: aprovada, rejeitada, cancelada ou expirada. Este é o evento mais importante — provavelmente o único que a maioria das integrações precisa consumir.
{
"event": "analysis.finalized",
"event_id": "evt_01hxyza1b2c3d4e5f6g7h8j9k0",
"timestamp": "2026-04-08T14:22:10.123Z",
"version": "1",
"data": {
"analysis_value": "RK-PJ_AVANCADA_IC943",
"analysis_id": 1000156,
"reference_no": "PED-2026-1234",
"evaluee": {
"value": "13823508000131",
"reference_no": "CLI-0042",
"type": "PJ",
"name": "Grupo Mundo do Café S/A"
},
"policy": { "id": 1000001, "value": "PJ_AVANCADA" },
"status": "AP",
"status_label": "Aprovado",
"final_score": 782,
"tier": "B",
"risk_level": "L",
"requested_amount": 50000,
"approved_limit": 45000,
"calculated_limit": 50000,
"ai_recommendation": "APROVAR",
"ai_opinion_short": "Empresa com bom histórico e faturamento estável",
"requires_approval": false,
"approved_at": "2026-04-08T14:22:08.456Z",
"approved_by": "analista@cliente.com.br"
}
}analysis.manual_review_required
A análise precisa de decisão humana. Pode ser por tier, alçada, hard stop de warning, ou divergência detectada pela IA. Carrega o motivo estruturado e link direto para o cockpit.
{
"event": "analysis.manual_review_required",
"event_id": "evt_...",
"timestamp": "2026-04-08T14:22:10.123Z",
"version": "1",
"data": {
"analysis_value": "RK-PJ_AVANCADA_IC944",
"reference_no": "PED-2026-1235",
"evaluee": { "value": "13823508000131", "type": "PJ" },
"reason": "TIER_REQUIRES_APPROVAL",
"reason_label": "Tier C exige aprovação manual",
"final_score": 612,
"tier": "C",
"risk_level": "M",
"requested_amount": 80000,
"calculated_limit": 30000,
"required_approval_level": 2,
"cockpit_link": "https://app.riskora.ai/cockpit/analysis/1000157",
"pending_since": "2026-04-08T14:22:08.456Z"
}
}analysis.parameter_rejected
O analista rejeitou um ou mais parâmetros e solicitou reenvio. Útil para que seu ERP abra ticket de pendência ou dispare notificação própria ao avaliado, além da comunicação padrão da Riskora.
{
"event": "analysis.parameter_rejected",
"event_id": "evt_...",
"timestamp": "2026-04-08T14:22:10.123Z",
"version": "1",
"data": {
"analysis_value": "RK-PJ_AVANCADA_IC943",
"reference_no": "PED-2026-1234",
"evaluee": { "value": "13823508000131" },
"rejected_parameters": [
{
"value": "CONTRATO_SOCIAL",
"name": "Contrato Social",
"rejection_reason": "Documento ilegível — favor reenviar"
}
],
"rejected_by": "analista@cliente.com.br",
"rejected_at": "2026-04-08T14:22:10.123Z",
"resubmission_link": "https://riskora.ai/eval/collect/a1b2c3d4...",
"resubmission_expires_at": "2026-04-15T14:22:10.123Z"
}
}evaluee.score_changed
O score, limite, tier ou nível de risco de um avaliado mudou como resultado de uma análise aprovada. Ideal para manter um cache local no ERP sem precisar fazer polling periódico.
{
"event": "evaluee.score_changed",
"event_id": "evt_...",
"timestamp": "2026-04-08T14:22:10.123Z",
"version": "1",
"data": {
"evaluee_value": "13823508000131",
"reference_no": "CLI-0042",
"name": "Grupo Mundo do Café S/A",
"type": "PJ",
"previous": { "score": 720, "limit": 30000, "tier": "C", "risk_level": "M" },
"current": { "score": 782, "limit": 45000, "tier": "B", "risk_level": "L" },
"delta": {
"score": 62,
"limit": 15000,
"tier_changed": true,
"risk_level_changed": true
},
"triggered_by_analysis": {
"value": "RK-PJ_AVANCADA_IC943",
"id": 1000156
},
"changed_at": "2026-04-08T14:22:08.456Z"
}
}analysis.created
Dispara imediatamente após uma análise ser criada (via API ou cockpit). Opcional — a maioria das integrações já tem essa informação pela resposta síncrona da criação. Útil para auditoria centralizada.
analysis.hard_stop_triggered
Um hard stop crítico bloqueou a análise automaticamente (por exemplo, score de bureau abaixo do mínimo, CNPJ com restrição). Evento silenciado por padrão — ative explicitamente se sua organização precisar monitorar tentativas bloqueadas.
Envelope comum
Todo evento segue a mesma estrutura base, com campos fixos no envelope e payload específico em data.
interface WebhookEnvelope<T> {
/** Nome do evento, dot-namespaced. Ex: "analysis.finalized" */
event: string;
/** ID único do evento. Use como chave de idempotência. */
event_id: string;
/** Timestamp ISO 8601 UTC com milissegundos */
timestamp: string;
/** Versão do schema. Breaking changes => bump. */
version: "1";
/** Payload específico do evento */
data: T;
}Segurança — HMAC Signature
Toda requisição enviada pela Riskora é assinada com HMAC-SHA256 usando um secret compartilhado. O consumidor deve validar a assinatura antes de processar o evento — sem isso, qualquer um que descobrir sua URL pode forjar eventos.
Headers enviados
POST /webhooks/riskora HTTP/1.1
Host: erp.cliente.com
Content-Type: application/json
User-Agent: Riskora-Webhooks/1.0
X-Riskora-Event: analysis.finalized
X-Riskora-Event-Id: evt_01hxyza...
X-Riskora-Timestamp: 1712587330
X-Riskora-Signature: sha256=a591a6d40bf42040...
X-Riskora-Delivery-Attempt: 1Como validar
// 1. Recebe o raw body ANTES de JSON.parse
const rawBody = await req.text();
// 2. Verifica janela de 5 minutos contra replay
const timestamp = req.headers.get('x-riskora-timestamp');
const age = Math.floor(Date.now() / 1000) - Number(timestamp);
if (age > 300) throw new Error('Timestamp expirado');
// 3. Calcula HMAC esperado
const signed = `${timestamp}.${rawBody}`;
const expected = 'sha256=' + crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(signed)
.digest('hex');
// 4. Comparação timing-safe
const received = req.headers.get('x-riskora-signature');
if (!crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(received)
)) {
throw new Error('Assinatura inválida');
}
// 5. OK — processar o evento
const payload = JSON.parse(rawBody);Retry e idempotência
A Riskora entrega cada evento com garantia at-least-once: em caso de falha (timeout, erro HTTP 5xx), reenviamos com backoff exponencial. Sucesso é considerado quando seu endpoint retorna HTTP 2xx.
| Tentativa | Delay | Janela acumulada |
|---|---|---|
| 1 | imediato | 0s |
| 2 | +30s | 30s |
| 3 | +2min | 2min 30s |
| 4 | +15min | 17min 30s |
| 5 | +1h | 1h 17min |
| 6 | +6h | 7h 17min |
| — | desiste | marca delivery_failed |
Idempotência é responsabilidade do consumidor: como o mesmo evento pode chegar mais de uma vez, sempre armazene o event_id e rejeite eventos já processados. Esta é a garantia mais forte que webhooks conseguem oferecer sem sacrificar disponibilidade.
Quero integrar. E agora?
- 1.Entre em contato com nossa equipe pelo formulário de contato informando seu interesse em consumir webhooks.
- 2.Receba suas credenciais (URL do ambiente de homologação + webhook secret) e documentação de endpoint para teste.
- 3.Configure o endpoint de destino no seu sistema seguindo o guia de validação HMAC acima.
- 4.Testamos juntos com eventos sintéticos em sandbox antes de habilitar em produção.
- 5.Após validação, ativação em produção e monitoramento conjunto da primeira semana.
Ainda com dúvidas?
Nossa equipe técnica pode revisar seu caso de uso e recomendar a melhor estratégia de integração (API, webhook, ou ambos).
Falar com a equipe