Skip to main content
POST
Embedded Biometric Session

Overview

Embedded Biometric lets you re-verify that the person completing a flow is the same individual who passed KYC earlier. Unlike the synchronous Biometric Check (where your app uploads a selfie), this flow uses a hosted capture UI that Gu1 returns as sessionUrl. Your app embeds that URL in an iframe (or opens a redirect) so liveness and face capture run in a controlled environment.
Use status from the API or webhook as the biometric result. Gu1 runs the full session lifecycle and may set rejected after organization policies (cross-entity checks, face-match score thresholds).

Prerequisites

  1. Approved KYC in Gu1 for the person entity (status: approved on a session-based validation).
  2. Reference portrait available from that KYC (selfie stored when the validation was approved). Required for session create (NO_PORTRAIT if missing).
  3. KYC enabled for your organization (same API key and permissions as session-based validation). Gu1 provisions the internal hosted-capture configuration; integrators do not set workflows or extra secrets. If your org is not provisioned yet, create may return BIOMETRIC_WORKFLOW_NOT_CONFIGURED (400) β€” contact your Gu1 account team.
  4. Gu1 Biometric active for your organization (global_gueno_biometric_kyc). If not enabled, create returns NOT_ENABLED (403) β€” request activation from Gu1.

Flow

Create Session

Body

Provide exactly one entity identifier:
string
UUID of the person entity with approved KYC.
string
Your external ID for the entity (entities.externalId in Gu1).
string
Tax or document number (CUIT, CPF, DNI, etc.). Gu1 resolves it with normalized match on entities.tax_id. The entity must exist in Gu1 (404 if not found).
Sandbox entity preview: GET /api/entities/by-tax-id/{taxId} may return a synthetic person (sandboxMock: true, id: null) for catalog test document numbers when no real row exists. That preview is read-only β€” you still need a persisted entity before POST /sessions.
string
Optional HTTPS endpoint Gu1 POSTs to on terminal statuses (approved, rejected, abandoned, expired). Signed with your KYC webhook secret when configured.
string
Optional redirect URL after the user finishes in the hosted UI.
string
UI language, e.g. es, en, pt.
string
Optional override for the biometric workflow ID (otherwise from org KYC settings).

Response 201

In sandbox mock, status may be approved or rejected immediately (no iframe). See Sandbox mock β€” Embedded biometric.
  1. Ensure the person entity has KYC approved (session-based validation).
  2. Call POST /api/kyc/biometric/sessions once per user intent. Store id, sessionUrl, and hostedSessionId.
  3. If the response is 409 ACTIVE_SESSION_EXISTS, cancel with POST .../sessions/{activeSessionId}/cancel, then create again (do not retry in a loop without handling 409).
  4. If status is pending, embed sessionUrl in an iframe (or redirect).
  5. Wait for biometric.session_* webhooks (or poll GET .../sessions/:id / POST .../sync if needed).
  6. Use status and optional rejectionCode as the final biometric result.
Do not treat repeated POST /sessions as the normal path. Retries after timeouts or double-clicks can hit idempotency edge cases. Always handle 409, cancel active sessions explicitly, and prefer webhooks over aggressive polling.

Create Errors (POST /sessions)

Example 409 ACTIVE_SESSION_EXISTS (additive β€” existing clients that ignore extra fields are unchanged):
Repeated POST /sessions while a session is still open always returns this 409. Gu1 does not return 201 with the same pending session.

Prior Sessions and β€œCurrent” Biometric

An entity may have many biometric sessions over time (approved, rejected, cancelled, etc.). A previous approved session does not block creating a new one. Only a non-terminal latest session (pending / in_progress) triggers 409 ACTIVE_SESSION_EXISTS.

hostedSessionId, Cancel, and Retries

hostedSessionId is the hosted capture session reference returned at create. Gu1 stores it uniquely and uses it for webhooks and sync. Correct recovery:
After cancel: you may create a new session. Idempotent persistence (reusing an existing terminal row when the same hostedSessionId is seen again) applies only after cancel or other terminal outcomes β€” not while a session is still pending or in_progress. Sandbox mock: hostedSessionId is prefixed with sandbox-mock-bio- and each mock create gets a new ID.

Embed in Your App

Alternatives: full-page redirect to sessionUrl, or a compatible Web SDK initialized with the same URL.

Poll or Sync Status

  • GET /api/kyc/biometric/sessions/:id β€” one session by ID
  • GET /api/kyc/biometric/entities/:entityId/current β€” current session = most recent by createdAt (any status). Returns 200 with null if none.
  • GET /api/kyc/biometric/entities/by-tax-id/:taxId/current β€” same, resolved by tax ID
  • GET /api/kyc/biometric/entities/by-external-id/:externalId/current β€” same, resolved by external ID
  • GET /api/kyc/biometric/sessions?entityId=... β€” list; also accepts entityTaxId or entityExternalId (one at a time). currentSessionId is the latest approved session.
  • POST /api/kyc/biometric/sessions/:id/sync β€” refresh session state from Gu1 if webhooks are delayed.
  • POST /api/kyc/biometric/sessions/:id/cancel β€” manually cancel pending or in_progress sessions (marks cancelled in Gu1).
If POST /sessions returns 409 ACTIVE_SESSION_EXISTS, the body includes activeSessionId so you can cancel without calling /current.
The platform may report In Review while capture is reviewed; Gu1 maps that to in_progress until the final verdict (approved or rejected). Only terminal outcome states define the entity current session.

Webhooks

Two channels:
  1. Per-request webhookUrl β€” only if you sent it in POST /sessions; fires on terminal status.
  2. Organization webhooks β€” subscribe to biometric.session_* events in Webhook configuration. See Biometric webhook events.

Comparison with Synchronous Biometric

For step-up authentication and login flows, prefer embedded sessions.

Sandbox Mock Sessions

In sandbox, when the entity has an approved KYC mock (test taxId such as 99990001, or KYC with metadata.sandboxMock: true), POST /api/kyc/biometric/sessions can return an immediate mock result (approved or rejected) without hosted capture.
  • Default: 99990001 β†’ biometric approved; 99990011 β†’ biometric rejected (KYC still approved).
  • Override on any eligible entity: "metadata": { "sandboxMockOutcome": "rejected" }.
  • Mock responses use hostedSessionId prefixed with sandbox-mock-bio- and may return status: approved or rejected in the create response (not only pending).
Full tables and examples: Sandbox mock data β€” Embedded biometric.