> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gu1.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Sessão biométrica incorporada

> Inicie uma sessão de reautenticação biométrica hospedada após um KYC aprovado: URL pronta para iframe, webhooks e veredito final Gu1.

## Visão geral

A **biometria incorporada** revalida se quem conclui o fluxo é a mesma pessoa do KYC aprovado. Diferente do [check biométrico síncrono](/pt/use-cases/kyc/biometric), a Gu1 devolve `sessionUrl` com UI hospedada. Incorpore em iframe (ou redirecione) para captura com liveness controlado.

<Warning>
  **Use `status`** da API ou do webhook como resultado biométrico. A Gu1 gere o ciclo completo da sessão e pode definir `rejected` após políticas da organização (cruzamento entre entidades, limiares de face match).
</Warning>

## Pré-requisitos

1. **KYC aprovado** na Gu1 para a entidade pessoa.
2. **Retrato de referência** disponível a partir desse KYC.
3. **KYC habilitado** na organização (mesma API key e permissões da validação por sessão). A Gu1 provisiona a configuração interna de captura incorporada; integradores não definem workflows nem credenciais extras. Se a org ainda não foi habilitada, o create pode retornar `BIOMETRIC_WORKFLOW_NOT_CONFIGURED` (400) — contate a equipe Gu1.
4. **Gu1 Biometria** ativo na organização (`global_gueno_biometric_kyc`). Se não estiver habilitado, o create retorna `NOT_ENABLED` (403) — solicite ativação à Gu1.

## Criar sessão

`POST /api/kyc/biometric/sessions` — **`entityId`**, **`entityExternalId`** ou **`entityTaxId`** (exatamente um obrigatório), `webhookUrl` opcional, `callback`, `language`. Fluxo **face match** (liveness + comparação com retrato do KYC aprovado; `NO_PORTRAIT` se faltar selfie).

<Info>
  **Prévia sandbox (somente GET):** `GET /api/entities/by-tax-id/{taxId}` pode retornar pessoa **sintética** (`sandboxMock: true`, `id: null`) para números de teste do catálogo quando não há linha real. É **somente leitura** — para `POST /sessions` é necessária entidade persistida.
</Info>

Resposta `201`: `id`, `sessionUrl`, `iframeAllow`, `hostedSessionId`, `status` (`pending` no fluxo real; `approved` / `rejected` imediato no mock sandbox). Ver [mock sandbox](/pt/use-cases/kyc/sandbox-mock-data#biometria-incorporada-mock-sandbox).

## Fluxo recomendado de integração

1. Entidade pessoa com **KYC `approved`**.
2. **`POST /api/kyc/biometric/sessions` uma vez** por intenção do usuário. Guarde `id`, `sessionUrl` e `hostedSessionId`.
3. Se **`409 ACTIVE_SESSION_EXISTS`**, cancele com `POST .../sessions/{activeSessionId}/cancel` e só então crie de novo (não reintentar em loop sem tratar o 409).
4. Se `status` for **`pending`**, incorpore `sessionUrl` em iframe (ou redirecione).
5. Aguarde webhooks **`biometric.session_*`** (ou `GET .../sessions/:id` / `POST .../sync` se necessário).
6. Use **`status`** e `rejectionCode` como resultado final.

<Warning>
  **Não** use reintentos repetidos de `POST /sessions` como fluxo normal. Após timeout ou duplo clique podem ocorrer casos de borda de idempotência. Sempre trate `409`, cancele sessões ativas explicitamente e prefira webhooks a polling agressivo.
</Warning>

## Erros ao criar (`POST /sessions`)

| HTTP | `error`                        | Quando                                             | O que fazer                                         |
| ---- | ------------------------------ | -------------------------------------------------- | --------------------------------------------------- |
| 400  | `NO_KYC`                       | Sem KYC aprovado                                   | Concluir KYC primeiro                               |
| 400  | `NO_PORTRAIT`                  | KYC aprovado sem selfie de referência (fluxo real) | Refazer KYC com captura válida ou usar mock sandbox |
| 400  | `KYC_NOT_CONFIGURED`           | Credenciais KYC ausentes                           | Configurar KYC na org                               |
| 400  | `ENTITY_NOT_FOUND`             | `entityId` inválido ou org errada                  | Corrigir entidade / `X-Organization-ID`             |
| 400  | `INVALID_ENTITY_TYPE`          | Entidade não é `person`                            | Usar entidade pessoa                                |
| 403  | `NOT_ENABLED`                  | Biometria não ativa no marketplace                 | Solicitar ativação à Gu1                            |
| 402  | `INSUFFICIENT_CREDITS_FOR_KYC` | Sem créditos/pack                                  | Recarregar billing                                  |
| 409  | `ACTIVE_SESSION_EXISTS`        | Última sessão `pending` / `in_progress`            | Cancelar `activeSessionId` e criar de novo          |
| 502  | `PROVIDER_ERROR`               | A Gu1 não pôde iniciar a captura hospedada         | Tentar depois; usar código `error` e HTTP status    |
| 500  | `CREATION_FAILED`              | Falha inesperada ao persistir                      | Ver logs; cancelar sessão presa; um reintento       |

Exemplo **`409 ACTIVE_SESSION_EXISTS`** (aditivo — clientes que ignoram campos extras não mudam):

```json theme={null}
{
  "error": "ACTIVE_SESSION_EXISTS",
  "message": "Cannot create new biometric session. There is already a pending session for this entity. Please cancel or complete the existing session first.",
  "activeSessionId": "7618e10c-b1b1-408b-b361-1901077ced73"
}
```

Repetir `POST /sessions` com sessão ainda aberta **sempre** retorna este `409`. A Gu1 **não** responde `201` com a mesma sessão `pending`.

## Sessões anteriores e “atual”

Uma entidade pode ter **várias** sessões biométricas (aprovadas, rejeitadas, canceladas).

| API                                                                                          | Significado                                                     |
| -------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `GET .../entities/:entityId/current`                                                         | **Última criada** (qualquer status) — recuperar iframe pendente |
| `GET .../entities/by-tax-id/:taxId/current`                                                  | Igual, resolvido por `entityTaxId`                              |
| `GET .../entities/by-external-id/:externalId/current`                                        | Igual, resolvido por `entityExternalId`                         |
| `GET .../sessions?entityId=...` (ou `entityTaxId` / `entityExternalId`) → `currentSessionId` | Última sessão **`approved`** — verificação vigente              |
| Listagem `data[]`                                                                            | Histórico por `createdAt`                                       |

Uma sessão **aprovada anterior** **não** impede criar outra. Só bloqueia sessão **ativa** (`pending` / `in_progress`) → `409`.

## `hostedSessionId`, cancelamento e reintentos

`hostedSessionId` é a **referência de sessão de captura hospedada** retornada na criação. A Gu1 armazena de forma única para webhooks e sync.

**Recuperação correta:** `409` → cancelar `activeSessionId` → um único `POST` novo.

Após cancelar, você pode criar uma nova sessão. Persistência idempotente (reutilizar linha **terminal** existente se o mesmo `hostedSessionId` aparecer de novo) aplica-se só após cancel ou outros outcomes terminais — **não** enquanto a sessão ainda estiver `pending` ou `in_progress`.

**Mock sandbox:** prefixo `sandbox-mock-bio-`; cada create mock gera um ID novo.

## Incorporar

```html theme={null}
<iframe src="{{ sessionUrl }}" allow="{{ iframeAllow }}" style="width:100%;height:700px;border:none;"></iframe>
```

## Status e webhooks

* `GET /api/kyc/biometric/sessions/:id` — uma sessão por ID
* `GET /api/kyc/biometric/entities/:entityId/current` — **sessão atual** = a mais recente por `createdAt`. Responde `200` com `null` se não houver sessões.
* `GET /api/kyc/biometric/entities/by-tax-id/:taxId/current` — igual, resolvido por tax ID
* `GET /api/kyc/biometric/entities/by-external-id/:externalId/current` — igual, resolvido por external ID
* `GET /api/kyc/biometric/sessions?entityId=...` — listagem; também aceita `entityTaxId` ou `entityExternalId` (um por vez). `currentSessionId` é a última sessão **`approved`**.
* `POST /api/kyc/biometric/sessions/:id/sync`, `POST .../cancel` (`pending`/`in_progress` → `cancelled`), `GET .../media?key=`.

Se `POST /sessions` retornar `409 ACTIVE_SESSION_EXISTS`, o corpo inclui `activeSessionId` para cancelar sem consultar `/current`. **In Review** aparece como `in_progress` até o veredito final. Eventos `biometric.session_*` — [eventos biométricos](/pt/webhooks/events/biometric-events).

## Sessões mock no sandbox

No **sandbox**, quando a entidade tem **KYC mock aprovado** (`taxId` de teste como `99990001`, ou KYC com `metadata.sandboxMock: true`), `POST /api/kyc/biometric/sessions` pode retornar um **resultado mock imediato** (`approved` ou `rejected`) sem captura hospedada.

* Padrão: `99990001` → biometria **approved**; `99990011` → biometria **rejected** (KYC continua approved).
* Override: `"metadata": { "sandboxMockOutcome": "rejected" }` em qualquer entidade elegível.
* Respostas mock usam `hostedSessionId` com prefixo `sandbox-mock-bio-` e podem trazer `status: approved` ou `rejected` no create (não só `pending`).

Tabelas e exemplos completos: [Dados mock sandbox — Biometria incorporada](/pt/use-cases/kyc/sandbox-mock-data#biometria-incorporada-mock-sandbox).
