> ## Documentation Index
> Fetch the complete documentation index at: https://docs-platform.services-valid.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Serviço

> Crie e finalize sessões de liveness FaceTec via API antes de iniciar o SDK

O serviço de sessões FaceTec é a camada HTTP da Plataforma ID que orquestra cada captura de liveness: ele autoriza o seu projeto, minta o token do FaceTec via Apigee e devolve ao seu cliente todos os artefatos que o `LivenessFacetecSDK` precisa para abrir a UI nativa. Sem essa chamada, o SDK não consegue inicializar a captura.

A base URL de produção é `https://facetec.hub-liveness-service.app` e todas as rotas ficam abaixo de `/api/v1`. A autenticação segue o padrão da Plataforma ID via header `x-api-key` — veja [Chaves de API](/plataforma/chaves-de-api)

## Por que essas chamadas existem

O `LivenessFacetecSDK` é apenas um cliente: quem cria a sessão, gerencia o ciclo de vida e fala com o FaceTec é o serviço. O fluxo completo de uma captura passa por duas integrações server-side que você precisa implementar:

* **`POST /api/v1/sessions`** — cria a sessão de liveness e devolve `sessionToken` + `facetecSessionToken`. Sem esses valores o SDK não consegue inicializar a UI do FaceTec.
* **`POST /api/v1/sessions/:sessionId/fail`** — encerra uma sessão ativa quando o fluxo é abortado **fora** do SDK (usuário cancela na sua tela, validação de negócio rejeita antes da captura, timeout do front, etc.). Importante para reconciliação e auditoria.

<Warning>
  **Faça essas chamadas no seu backend, não no app.**

  A `x-api-key` da Plataforma ID identifica o seu projeto e libera acesso à cobrança e às credenciais FaceTec. Embuti-la no binário Android, no IPA ou no bundle JS de uma SPA é equivalente a publicar a chave no repositório — qualquer pessoa consegue extrair, reusar e gerar custo no seu projeto com ferramentas comuns (`jadx`, `Hopper`, DevTools).

  **A única integração segura é proxy-server-side:** o seu cliente fala com o seu backend, o seu backend fala com a Plataforma ID. O cliente nunca toca na `x-api-key`.
</Warning>

## Fluxo recomendado

<Steps>
  <Step title="Cliente solicita sessão ao seu backend">
    O app/web invoca um endpoint do seu próprio backend (com a sua autenticação de usuário), repassando opcionalmente o `visitorId` e `eventId` que o SDK já obteve durante a inicialização — veja [Metadados Complementares](#metadados-complementares).
  </Step>

  <Step title="Seu backend chama POST /api/v1/sessions">
    Servidor para servidor, com o header `x-api-key`. A Plataforma ID retorna `sessionId`, `sessionToken`, `facetecSessionToken` e metadados complementares.
  </Step>

  <Step title="Seu backend devolve os tokens ao cliente">
    Envie ao cliente apenas o que ele precisa: `sessionId`, `sessionToken`, `facetecSessionToken` e `expiresAt`.
  </Step>

  <Step title="Cliente inicializa o Liveness com esses tokens">
    O `LivenessFacetecSDK` consome os tokens e abre a UI nativa do FaceTec. Veja [Implementação Android](/plataforma/liveness/facetec/sdk/android/implementacao) ou [Implementação iOS](/plataforma/liveness/facetec/sdk/ios/implementacao).
  </Step>

  <Step title="Se o fluxo for abortado, falhe a sessão">
    Caso o usuário cancele ou o seu backend rejeite o fluxo antes da captura terminar, chame `POST /api/v1/sessions/:sessionId/fail` para marcar a sessão como falha.
  </Step>
</Steps>

## POST /api/v1/sessions

Cria uma nova sessão de liveness FaceTec e retorna os tokens que o SDK precisa para inicializar a captura.

**Endpoint:** `POST https://facetec.hub-liveness-service.app/api/v1/sessions`

### Headers

| Header         | Valor                                                                   |
| -------------- | ----------------------------------------------------------------------- |
| `x-api-key`    | Chave da Plataforma ID — ver [Chaves de API](/plataforma/chaves-de-api) |
| `Content-Type` | `application/json`                                                      |

### Body

<ParamField body="clientRequestId" type="string (uuid)" required>
  UUID gerado pelo seu backend para esta tentativa. Funciona como chave de idempotência: reenvios com o mesmo `(projeto, clientRequestId)` retornam a mesma sessão em vez de criar uma nova.
</ParamField>

<ParamField body="visitorId" type="string">
  Identificador de dispositivo obtido pelo SDK durante a inicialização.
</ParamField>

<ParamField body="eventId" type="string">
  Identificador do evento de inicialização do SDK, usado para correlacionar sinais de risco do dispositivo. Quando informado, o serviço enriquece a resposta com `deviceSignals` e `geolocation`. Veja [Metadados Complementares](#metadados-complementares).
</ParamField>

<ParamField body="maxAttempts" type="integer">
  Número máximo de capturas biométricas permitidas na sessão. Quando uma captura falha e ainda há tentativas disponíveis, o FaceTec exibe a tela de retry automaticamente sem criar nova sessão. **Mínimo: 1 · Máximo: 5 · Default: 3**
</ParamField>

### Resposta 201

<ResponseField name="sessionId" type="string (uuid)">
  ID da sessão criada. Use-o no SDK e em chamadas subsequentes ao serviço.
</ResponseField>

<ResponseField name="sessionToken" type="string (jwt)">
  JWT HS256 emitido pelo serviço (TTL de 600s). O SDK utiliza este token ao submeter a captura.
</ResponseField>

<ResponseField name="facetecSessionToken" type="string">
  Token do FaceTec necessário para inicializar a UI nativa da captura.
</ResponseField>

<ResponseField name="createdAt" type="string (iso-8601)">
  Data/hora de criação da sessão.
</ResponseField>

<ResponseField name="expiresAt" type="string (iso-8601)">
  Data/hora de expiração. Após esse instante a sessão é marcada como `expired` e não aceita mais captura.
</ResponseField>

<ResponseField name="notice" type="string">
  Texto de consentimento / aviso legal. Exiba ao usuário antes de iniciar a captura.
</ResponseField>

<ResponseField name="deviceSignals" type="object">
  Sinais de risco do dispositivo. Presente quando o `eventId` é informado e o enriquecimento é bem-sucedido. Inclui `suspectScore`, flags como `emulator`, `simulator`, `root`, `jailbroken`, `frida`, `mitm`, `tampering`, `bot`, `antiDetectBrowser`, `developerTools`, `locationSpoofing`, `incognito`, `clonedApp`, `factoryReset`, `replayed`, `tor`, `blocklist`, `emailSpam`, além de `vpnConfidence` (`low` | `medium` | `high` | `null`) e `proxyType` (`residential` | `data_center` | `null`).
</ResponseField>

<ResponseField name="geolocation" type="object">
  Geolocalização derivada do `visitorId`: `latitude`, `longitude`, `city`, `region`, `country` e `timezone`. Também opcional.
</ResponseField>

### Códigos de erro

| Status | Quando ocorre                                                     |
| ------ | ----------------------------------------------------------------- |
| `400`  | `clientRequestId` ausente ou fora do formato UUID                 |
| `401`  | Header `x-api-key` ausente ou inválido                            |
| `403`  | Chave válida, mas o projeto não tem o produto Liveness habilitado |
| `500`  | Falha ao mintar o token FaceTec via Apigee                        |

## POST /api/v1/sessions/:sessionId/fail

Encerra explicitamente uma sessão ativa sem captura submetida. Use sempre que o fluxo for abortado fora do SDK — cancelamento do usuário antes de iniciar, falha de validação no seu backend, timeout do front, etc.

**Endpoint:** `POST https://facetec.hub-liveness-service.app/api/v1/sessions/:sessionId/fail`

### Headers

| Header         | Valor                                                                                                              |
| :------------- | :----------------------------------------------------------------------------------------------------------------- |
| `x-api-key`    | Chave da Plataforma ID — ver [Chaves de API](https://docs-platform.services-valid.com.br/plataforma/chaves-de-api) |
| `Content-Type` | `application/json`                                                                                                 |

### Path params

| Param       | Tipo | Descrição                                          |
| ----------- | ---- | -------------------------------------------------- |
| `sessionId` | UUID | `sessionId` retornado pelo `POST /api/v1/sessions` |

### Body

<ParamField body="reason" type="string" required>
  Motivo do encerramento (1 a 500 caracteres). Persistido para auditoria — não inclua dados sensíveis do usuário aqui.
</ParamField>

### Resposta 200

<ResponseField name="sessionId" type="string (uuid)">
  ID da sessão finalizada.
</ResponseField>

<ResponseField name="status" type="string">
  Sempre `"failed"`.
</ResponseField>

<ResponseField name="failureReason" type="string">
  Eco do `reason` enviado.
</ResponseField>

<ResponseField name="finalizedAt" type="string (iso-8601)">
  Data/hora em que a sessão foi marcada como falha.
</ResponseField>

### Códigos de erro

| Status | Quando ocorre                                                        |
| ------ | -------------------------------------------------------------------- |
| `400`  | `sessionId` não é UUID ou `reason` ausente/fora do tamanho permitido |
| `401`  | `x-api-key` ausente ou inválido                                      |
| `404`  | Sessão não encontrada para o projeto                                 |
| `409`  | Sessão já está finalizada (`completed`, `failed` ou `expired`)       |

## Metadados Complementares

O `eventId` é um identificador do evento que o `LivenessFacetecSDK` obtém **durante a inicialização**, antes de qualquer chamada ao serviço de sessão. Quando você o repassa em `POST /api/v1/sessions`, o serviço enriquece a resposta com dois objetos opcionais:

* `deviceSignals` — flags de risco do dispositivo (emulador, root, MITM, bot, VPN, etc.).
* `geolocation` — localização aproximada derivada do dispositivo.

<Info>
  **Nem sempre o SDK consegue obter o `eventId`.** A coleta depende de conectividade no momento do `init`, das permissões do dispositivo, das configurações de privacidade do usuário e do ambiente de execução — alguns simuladores e dispositivos com privacidade agressiva bloqueiam a coleta. Por isso o campo é **opcional**: quando ausente, o serviço cria a sessão normalmente, apenas sem o enriquecimento de `deviceSignals` e `geolocation`.
</Info>

O app/web deve repassar o `eventId` ao seu backend no mesmo request em que pede a sessão. O SDK expõe esse valor depois que `init` retorna com sucesso — consulte a documentação de implementação da sua plataforma para detalhes do acesso.

## Boas práticas

<AccordionGroup>
  <Accordion title="Nunca embuta a x-api-key no cliente">
    Mesmo ofuscada, qualquer chave embarcada no binário Android/iOS ou no bundle JS pode ser extraída com ferramentas comuns (`jadx`, `Hopper`, DevTools). Mantenha a chave **apenas** no seu backend, idealmente em um Secret Manager. O cliente só deve receber `sessionToken` e `facetecSessionToken`.
  </Accordion>

  <Accordion title="Use clientRequestId para idempotência">
    Gere o UUID no início do fluxo e reutilize-o em retries de rede do seu backend. Reenvios com o mesmo `(projeto, clientRequestId)` retornam a mesma sessão, evitando duplicar consumo e tokens.
  </Accordion>

  <Accordion title="Falhe sessões abandonadas explicitamente">
    Sessões não finalizadas expiram sozinhas por TTL, mas chamar `/fail` com um `reason` significativo melhora auditoria, reconciliação de métricas e investigação de incidentes.
  </Accordion>

  <Accordion title="Repasse o eventId quando disponível">
    Quando o SDK conseguir obter o `eventId`, repasse-o ao seu backend e inclua-o no `POST /api/v1/sessions`. Você recebe `deviceSignals` e `geolocation` em troca — úteis para regras antifraude.
  </Accordion>
</AccordionGroup>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Implementação Android" icon="android" href="/plataforma/liveness/facetec/sdk/android/implementacao">
    Inicialize o SDK com o token de sessão emitido pelo serviço
  </Card>

  <Card title="Implementação iOS" icon="apple" href="/plataforma/liveness/facetec/sdk/ios/implementacao">
    Inicialize o SDK com o token de sessão emitido pelo serviço
  </Card>

  <Card title="Chaves de API" icon="key" href="/plataforma/chaves-de-api">
    Gere e gerencie a sua chave da Plataforma ID
  </Card>

  <Card title="Autenticação" icon="lock" href="/plataforma/autenticacao-api">
    Como o header x-api-key funciona em todas as APIs
  </Card>
</CardGroup>
