Pular para o conteúdo principal

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

EventoVerdictQuando dispara
verification.approvedapprovedScore de confianca acima do threshold de aprovacao, sem flags criticos
verification.rejectedrejectedConfianca abaixo do threshold de rejeicao, ou flag critico disparado
verification.review_requiredreviewConfianca 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:

CampoTipoSempreDescricao
eventstringSimTipo de evento — switch neste no seu handler
verificationIdstringSimID unico de /init (formato: vf_*)
tenantIdstringSimSeu tenant ID (util para routing multi-tenant)
userRefstring | nullSimO userRef que voce passou ao /init, ou null se nao
verdictstringSimapproved, review, ou rejected
confidencenumberSimScore geral ponderado de confianca (0-100)
scoresobjectSimBreakdown de sinais individuais
flagsarraySimFlags de qualidade / risco levantados. Vazio [] quando esta limpo
metadataobjectSimO metadata que voce passou ao /submit, ou {}
submittedAtstringSimTimestamp ISO 8601 quando /submit foi chamado
completedAtstringSimTimestamp 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:

CampoFaixaDescricao
ocrConfidence0-100Confianca VLM auto-reportada na extracao de texto do documento
faceMatch0-100Similaridade biometrica entre selfie e foto do documento
liveness0-100Anti-spoofing — confirma que e uma pessoa viva, nao foto
docQuality0-100Qualidade 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:

NivelSignificado
infoFYI para revisores, nao afeta o veredicto por si so
warnIssue notavel — contribui para confianca abaixada
criticalFalha dura — empurra o veredicto para rejected independente dos outros sinais

Flags comuns que voce pode ver no array flags:

FlagNivelSignificado
heavy_glarewarnDocumento tem reflexo brilhoso obscurecendo o texto
low_face_matchwarn / criticalSelfie e foto do documento nao batem
low_livenesswarnScore anti-spoofing abaixo do threshold
low_doc_qualitywarnImagem do documento muito borrada ou de baixa resolucao
expired_documentcriticalData de expiracao do documento ja passou
mrz_mismatchcriticalChecksum MRZ falhou (passaporte potencialmente alterado)
name_mismatchwarnO nome enviado nao bate via fuzzy-match com o OCR
age_under_minimumcriticalIdade 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 completar
  • verification.refunded — credito refunded devido a erro interno

Proximos passos