Tipos de eventos
Veridia emite tres tipos de eventos hoje, todos sobre resultados de verificacao. Cada evento tem um shape base consistente com campos especificos por evento sobre ele.
Referencia rapida
| Evento | Verdict | Quando dispara |
|---|---|---|
verification.approved | approved | Score de confianca acima do threshold de aprovacao, sem flags criticos |
verification.rejected | rejected | Confianca abaixo do threshold de rejeicao, ou flag critico disparado |
verification.review_required | review | Confianca na faixa media — revisao manual necessaria |
Os thresholds default sao configuraveis por tenant. Out of the box: rejected <60, review 60-80, approved >=80.
Campos comuns
Cada evento inclui estes campos:
| Campo | Tipo | Sempre | Descricao |
|---|---|---|---|
event | string | Sim | Tipo de evento — switch neste no seu handler |
verificationId | string | Sim | ID unico de /init (formato: vf_*) |
tenantId | string | Sim | Seu tenant ID (util para routing multi-tenant) |
userRef | string | null | Sim | O userRef que voce passou ao /init, ou null se nao |
verdict | string | Sim | approved, review, ou rejected |
confidence | number | Sim | Score geral ponderado de confianca (0-100) |
scores | object | Sim | Breakdown de sinais individuais |
flags | array | Sim | Flags de qualidade / risco levantados. Vazio [] quando esta limpo |
metadata | object | Sim | O metadata que voce passou ao /submit, ou {} |
submittedAt | string | Sim | Timestamp ISO 8601 quando /submit foi chamado |
completedAt | string | Sim | Timestamp ISO 8601 quando o veredicto foi determinado |
O body e sempre JSON compacto com keys ordenadas alfabeticamente — necessario para verificacao reproduzivel da assinatura.
verification.approved
Enviado quando uma verificacao passa todos os thresholds de sinais e nao tem flags criticos. Este e o evento luz-verde para seu fluxo de onboarding.
{
"event": "verification.approved",
"verificationId": "vf_AG07CDWRRFQV4T05ZXG2",
"tenantId": "tn_default_demo",
"userRef": "customer-12345",
"verdict": "approved",
"confidence": 87.4,
"scores": {
"ocrConfidence": 78.0,
"faceMatch": 96.2,
"liveness": 91.5,
"docQuality": 85.0
},
"flags": [],
"metadata": {
"campaign": "spring_2026",
"platform": "web"
},
"submittedAt": "2026-05-01T18:39:05Z",
"completedAt": "2026-05-01T18:39:08Z"
}
Handler tipico:
case 'verification.approved':
await db.users.update(payload.userRef, {
kycStatus: 'verified',
kycCompletedAt: payload.completedAt,
kycVerificationId: payload.verificationId,
});
await sendWelcomeEmail(payload.userRef);
break;
verification.rejected
Enviado quando uma verificacao falha — seja confianca abaixo do threshold de rejeicao, ou um flag critico (documento expirado, mismatch MRZ, idade abaixo do minimo, etc.).
{
"event": "verification.rejected",
"verificationId": "vf_BX18DEXSGFRX5U16YH3",
"tenantId": "tn_default_demo",
"userRef": "customer-67890",
"verdict": "rejected",
"confidence": 42.1,
"scores": {
"ocrConfidence": 65.0,
"faceMatch": 31.4,
"liveness": 88.0,
"docQuality": 50.5
},
"flags": [
{ "level": "critical", "text": "low_face_match" },
{ "level": "warn", "text": "low_doc_quality" }
],
"metadata": {},
"submittedAt": "2026-05-01T19:02:12Z",
"completedAt": "2026-05-01T19:02:15Z"
}
Handler tipico:
case 'verification.rejected':
await db.users.update(payload.userRef, {
kycStatus: 'rejected',
kycRejectionReasons: payload.flags,
});
await sendRejectionEmail(payload.userRef, payload.flags);
// Nao diga ao usuario os flags exatos — risco de seguranca
break;
:::warning Nao exponha flags a usuarios finais Dizer a um fraudador qual sinal o pegou ajuda ele a craftear uma tentativa melhor. Mostre aos usuarios finais um generico "verificacao falhou, por favor contate suporte" — guarde os flags detalhados para sua fila de revisao interna. :::
verification.review_required
Enviado quando a confianca cai na faixa media. O usuario poderia ser legitimo mas o sistema nao esta confiante o suficiente para auto-aprovar. Seus revisores devem olhar.
{
"event": "verification.review_required",
"verificationId": "vf_CY29EFYTGFSZ6V27ZH4",
"tenantId": "tn_default_demo",
"userRef": "customer-11111",
"verdict": "review",
"confidence": 67.3,
"scores": {
"ocrConfidence": 72.0,
"faceMatch": 79.5,
"liveness": 88.0,
"docQuality": 45.0
},
"flags": [
{ "level": "warn", "text": "heavy_glare" },
{ "level": "info", "text": "name_mismatch" }
],
"metadata": {},
"submittedAt": "2026-05-01T20:15:30Z",
"completedAt": "2026-05-01T20:15:33Z"
}
Handler tipico:
case 'verification.review_required':
await db.users.update(payload.userRef, {
kycStatus: 'pending_review',
});
await reviewQueue.add({
verificationId: payload.verificationId,
userRef: payload.userRef,
flags: payload.flags,
priority: payload.flags.some(f => f.level === 'critical') ? 'high' : 'normal',
});
// Opcionalmente pause acoes sensiveis ate o revisor decidir
break;
Breakdown de scores
O objeto scores tem o mesmo shape em todos os eventos:
| Campo | Faixa | Descricao |
|---|---|---|
ocrConfidence | 0-100 | Confianca VLM auto-reportada na extracao de texto do documento |
faceMatch | 0-100 | Similaridade biometrica entre selfie e foto do documento |
liveness | 0-100 | Anti-spoofing — confirma que e uma pessoa viva, nao foto |
docQuality | 0-100 | Qualidade de imagem do documento capturado (nitidez, iluminacao, framing) |
O confidence geral e uma combinacao ponderada — principalmente faceMatch e liveness, com ocrConfidence e docQuality como sinais de suporte.
Referencia de flags
Os flags disparam quando um sinal individual cai abaixo do threshold ou falha um check duro. Cada um tem um level:
| Nivel | Significado |
|---|---|
info | FYI para revisores, nao afeta o veredicto por si so |
warn | Issue notavel — contribui para confianca abaixada |
critical | Falha dura — empurra o veredicto para rejected independente dos outros sinais |
Flags comuns que voce pode ver no array flags:
| Flag | Nivel | Significado |
|---|---|---|
heavy_glare | warn | Documento tem reflexo brilhoso obscurecendo o texto |
low_face_match | warn / critical | Selfie e foto do documento nao batem |
low_liveness | warn | Score anti-spoofing abaixo do threshold |
low_doc_quality | warn | Imagem do documento muito borrada ou de baixa resolucao |
expired_document | critical | Data de expiracao do documento ja passou |
mrz_mismatch | critical | Checksum MRZ falhou (passaporte potencialmente alterado) |
name_mismatch | warn | O nome enviado nao bate via fuzzy-match com o OCR |
age_under_minimum | critical | Idade calculada abaixo do minimo do tenant (default 18) |
Padrao de routing
A maioria dos handlers de producao routeam pelo tipo de evento:
async function handleVeridiaWebhook(payload) {
switch (payload.event) {
case 'verification.approved':
return handleApproved(payload);
case 'verification.rejected':
return handleRejected(payload);
case 'verification.review_required':
return handleReviewRequired(payload);
default:
// Future-proofing: logue eventos desconhecidos mas nao falhe
logger.warn('Tipo de evento Veridia desconhecido', {
event: payload.event,
verificationId: payload.verificationId,
});
}
}
Podemos adicionar tipos de evento novos no futuro (ex: verification.expired, verification.refunded). Gerencie tipos de evento desconhecidos graciosamente — logue e ignore, nao falhe.
Eventos futuros (ainda nao emitidos)
Estes estao documentados para compatibilidade futura. Nao escreva codigo que dependa deles ainda:
verification.expired— verificacao expirou sem completarverification.refunded— credito refunded devido a erro interno
Proximos passos
- Exemplos — implementacoes completas de handler
- Verificacao de assinatura — referencia de algoritmo
- Webhooks overview — voltar ao overview