Skip to main content

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:
  1. Webhooks de organización — suscribite a biometric.session_* en configuración de webhooks (todas las transiciones de estado).
  2. 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

EventoCuándo
biometric.session_createdSesión creada (status: pending)
biometric.session_in_progressEl usuario inició la captura en la UI hospedada
biometric.session_approvedSesión biométrica aprobada por Gu1
biometric.session_rejectedSesión biométrica rechazada por Gu1
biometric.session_abandonedEl usuario abandonó el flujo sin terminar
biometric.session_cancelledSesión cancelada en Gu1 (solo pending / in_progress)
biometric.session_expiredSesió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.modeface_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ódigoSignificado
FACE_MATCH_SCORE_LOWScore de face match por debajo del umbral (face_match)
CROSS_ENTITYLa captura coincide con otra entidad de la organización
CAPTURE_DECLINEDCaptura 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.