Resumen
Las sesiones biométricas embebidas las gestiona Gu1 de punta a punta. Cuando el usuario termina la captura en la UI hospedada, Gu1 persiste la sesión, aplica las políticas de tu organización (umbrales de face match, cruces entre entidades, billing) y envía webhooks con el resultado de la sesión.
Tu integración debe usar payload.status como veredicto biométrico — el mismo campo que devuelve GET /api/kyc/biometric/sessions/:id.
Dos canales de entrega:
- Webhooks de organización — suscribite a
biometric.session_* en configuración de webhooks (todas las transiciones de estado).
webhookUrl por request — URL HTTPS opcional en POST /api/kyc/biometric/sessions; Gu1 hace POST en resultados terminales de captura (approved, rejected, abandoned, expired). Un cancel manual por API solo dispara webhooks de organización.
Tipos de evento
| Evento | Cuándo |
|---|
biometric.session_created | Sesión creada (status: pending) |
biometric.session_in_progress | El usuario inició la captura en la UI hospedada |
biometric.session_approved | Sesión biométrica aprobada por Gu1 |
biometric.session_rejected | Sesión biométrica rechazada por Gu1 |
biometric.session_abandoned | El usuario abandonó el flujo sin terminar |
biometric.session_cancelled | Sesión cancelada en Gu1 (solo pending / in_progress) |
biometric.session_expired | Sesión expirada |
Sobre el payload
Misma envoltura externa que eventos KYC:
{
"event": "biometric.session_approved",
"timestamp": "2026-06-11T15:00:00Z",
"organizationId": "org-uuid",
"payload": { }
}
El payload interno es la fila de sesión biométrica en Gu1 (misma forma que la API REST).
Campos del payload
payload.status — Estado de la sesión: pending, in_progress, approved, rejected, abandoned, cancelled, expired.
payload.rejectionCode / payload.rejectionMessage — Cuando status es rejected (p. ej. FACE_MATCH_SCORE_LOW, CROSS_ENTITY, CAPTURE_DECLINED).
payload.mode — face_match (liveness + comparación con retrato del KYC).
payload.sessionUrl — URL de captura mientras la sesión está activa.
payload.decision — Detalle técnico de la captura (scores, claves de media). Imágenes vía GET /api/kyc/biometric/sessions/:id/media?key=.
payload.entity — Snapshot de la entidad persona (id, externalId, name, type).
Ejemplo: sesión creada
{
"event": "biometric.session_created",
"timestamp": "2026-06-11T14:00:00Z",
"organizationId": "org-uuid",
"payload": {
"id": "bio-session-uuid",
"entityId": "entity-uuid",
"status": "pending",
"mode": "face_match",
"sessionUrl": "https://verify.example.com/session/abc",
"hostedSessionId": "hosted-session-id",
"rejectionCode": null,
"rejectionMessage": null,
"createdAt": "2026-06-11T14:00:00.000Z",
"entity": {
"id": "entity-uuid",
"externalId": "cliente-123",
"name": "Jane Doe",
"type": "person"
}
}
}
Ejemplo: en progreso
{
"event": "biometric.session_in_progress",
"timestamp": "2026-06-11T14:05:00Z",
"organizationId": "org-uuid",
"payload": {
"id": "bio-session-uuid",
"entityId": "entity-uuid",
"status": "in_progress",
"mode": "face_match",
"sessionUrl": "https://verify.example.com/session/abc",
"rejectionCode": null
}
}
Ejemplo: aprobada
{
"event": "biometric.session_approved",
"timestamp": "2026-06-11T14:10:00Z",
"organizationId": "org-uuid",
"payload": {
"id": "bio-session-uuid",
"entityId": "entity-uuid",
"status": "approved",
"mode": "face_match",
"rejectionCode": null,
"completedAt": "2026-06-11T14:10:00.000Z",
"decision": {
"face_match": { "status": "Approved", "score": 99.2 },
"liveness": { "status": "Approved", "score": 98.5 }
},
"entity": {
"id": "entity-uuid",
"externalId": "cliente-123",
"name": "Jane Doe",
"type": "person"
}
}
}
Ejemplo: rechazada
{
"event": "biometric.session_rejected",
"timestamp": "2026-06-11T14:12:00Z",
"organizationId": "org-uuid",
"payload": {
"id": "bio-session-uuid",
"entityId": "entity-uuid",
"status": "rejected",
"mode": "face_match",
"rejectionCode": "CROSS_ENTITY",
"rejectionMessage": "Biometric match corresponds to a different entity in this organization",
"completedAt": "2026-06-11T14:12:00.000Z",
"entity": {
"id": "entity-uuid",
"externalId": "cliente-123",
"name": "Jane Doe",
"type": "person"
}
}
}
Códigos frecuentes de rejectionCode
| Código | Significado |
|---|
FACE_MATCH_SCORE_LOW | Score de face match por debajo del umbral (face_match) |
CROSS_ENTITY | La captura coincide con otra entidad de la organización |
CAPTURE_DECLINED | Captura rechazada en el flujo hospedado |
webhookUrl por request
- Mismo
event y forma de payload que los webhooks de organización.
- Firma HMAC en
X-Webhook-Signature con el webhook secret KYC configurado.
- Headers adicionales:
X-Webhook-Event, X-Webhook-ID, X-Webhook-Timestamp.
Ver verificación de firma.
El cancel manual (POST /api/kyc/biometric/sessions/:id/cancel) emite biometric.session_cancelled solo en webhooks de organización; no hace POST al webhookUrl del request.