> ## 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.

# Implementação

> Inicialize o LivenessFacetecSDK Web e dispare uma verificação de liveness FaceTec

Este guia mostra a API pública do `LivenessFacetecSDK` e o fluxo completo de uma verificação no browser.

O bundle expõe `window.LivenessFacetecSDK` com uma fábrica que cria a instância do SDK. A única interface que você precisa conhecer é a `FaceTecSDKConfig` — o objeto de configuração que você passa para executar uma verificação.

```javascript theme={"theme":"catppuccin-latte"}
const sdk = window.LivenessFacetecSDK.createFaceTecSDK();
const result = await sdk.run(config); // config: FaceTecSDKConfig
```

`sdk.run(config)` orquestra o fluxo completo (preparação, captura, submissão e limpeza) em uma única chamada e resolve com o `LivenessResult` da verificação.

## Configuração

```typescript theme={"theme":"catppuccin-latte"}
interface FaceTecSDKConfig {
  mount: HTMLElement | string;
  onInit: (params: SessionParams) => Promise<SessionTokens>;
  hubOptions?: HubOptions;
  onSuccess?: (result: LivenessResult) => void;
  onFailure?: (error: LivenessFailureError) => void;
  onProgress?: (state: HubState) => void;
}
```

| Parâmetro    | Tipo                                 | Obrigatório | Descrição                                                                                                                                                        |                                                               |   |   |   |   |
| ------------ | ------------------------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | - | - | - | - |
| `mount`      | \`HTMLElement                        | string\`    | Sim                                                                                                                                                              | Elemento (ou seletor CSS) onde a UI da câmera vai renderizar. |   |   |   |   |
| `onInit`     | `(params) => Promise<SessionTokens>` | Sim         | Callback que **seu código** implementa: chama o seu backend, que implementa o serviço de Facetec, e devolve `sessionToken`, `facetecSessionToken` e `sessionId`. |                                                               |   |   |   |   |
| `hubOptions` | `HubOptions`                         | Não         | Personalização de idioma, textos e cores. Veja [Customização](/plataforma/liveness/facetec/sdk/web/customizacao).                                                |                                                               |   |   |   |   |
| `onSuccess`  | `(result) => void`                   | Não         | Disparado quando a captura termina (mesmo quando `livenessCheck = false` — é um resultado biométrico, não um erro técnico).                                      |                                                               |   |   |   |   |
| `onFailure`  | `(error) => void`                    | Não         | Disparado quando o fluxo técnico falha. Veja [Solução de problemas](/plataforma/liveness/facetec/sdk/web/troubleshooting).                                       |                                                               |   |   |   |   |
| `onProgress` | `(state) => void`                    | Não         | Recebe transições de estado (`Uninitialized`, `Initializing`, `Ready`, `Capturing`, `Closing`, `Error`).                                                         |                                                               |   |   |   |   |

## Como o `onInit` funciona

O SDK chama `onInit` **antes** de inicializar a UI, passando metadados de dispositivo coletados pelo `FingerprintJS Pro`:

```typescript theme={"theme":"catppuccin-latte"}
interface SessionParams {
  visitorId?: string;
  eventId?: string;
}
```

Você repassa esses metadados ao seu backend e devolve ao SDK os três tokens da sessão:

```typescript theme={"theme":"catppuccin-latte"}
interface SessionTokens {
  sessionId: string;
  sessionToken: string;
  facetecSessionToken: string;
}
```

<Info>
  Nem sempre o SDK consegue obter o `visitorId` e o `eventId` — depende de conectividade, configurações de privacidade e do ambiente de execução. Repasse-os ao seu backend quando estiverem presentes; quando ausentes, o serviço cria a sessão normalmente. Veja [Serviço](/plataforma/liveness/facetec/servico#sobre-o-visitorid).
</Info>

<Info>
  **`maxAttempts`** — seu backend pode incluir este campo ao chamar `POST /api/v1/sessions`, definindo o número máximo de capturas biométricas permitidas na sessão (1–5, default `3`). Quando uma captura falha e ainda há tentativas disponíveis, o FaceTec exibe a tela de retry automaticamente sem criar nova sessão.
</Info>

## Fluxo de uso

<Steps>
  <Step title="Crie a instância do SDK">
    Logo após o bundle ser carregado, crie a instância. Você pode reaproveitá-la em múltiplas capturas.

    ```javascript theme={"theme":"catppuccin-latte"}
    const sdk = window.LivenessFacetecSDK.createFaceTecSDK();
    ```
  </Step>

  <Step title="Implemente o onInit chamando o seu backend">
    O `onInit` é um `async` que devolve `{ sessionId, sessionToken, facetecSessionToken }`. Encaminhe os `sessionParams` recebidos para o seu endpoint:

    ```javascript theme={"theme":"catppuccin-latte"}
    async function onInit(sessionParams) {
      const r = await fetch('api.client.com/api/create-session', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(sessionParams), // { visitorId?, eventId? }
      });

      if (!r.ok) {
        const err = await r.json().catch(() => ({}));
        throw new Error(`Falha ao criar sessão: ${r.status} ${err.error?.message ?? ''}`);
      }

      return r.json(); // { sessionId, sessionToken, facetecSessionToken }
    }
    ```
  </Step>

  <Step title="Dispare a verificação">
    ```javascript theme={"theme":"catppuccin-latte"}
    document.getElementById('iniciar-verificacao').addEventListener('click', async () => {
      try {
        const result = await sdk.run({
          mount: '#camera-container',
          onInit,
          onSuccess: (data) => console.log('verificado', data),
          onFailure: (error) => console.error('falhou', error.type, error.failureReason),
          onProgress: (state) => console.log('estado', state),
        });

        // result === o mesmo objeto entregue ao onSuccess
        console.log('sessionId', result.sessionId);
      } catch (err) {
        // Erros inesperados não cobertos por onFailure
        console.error('erro inesperado', err);
      }
    });
    ```
  </Step>

  <Step title="Trate o resultado">
    Use `sessionId` e `captureId` para reconciliar a captura no seu backend. Se `verified === false`, exiba mensagem ao usuário e ofereça nova tentativa — não é um erro técnico, é uma reprovação biométrica.
  </Step>
</Steps>

## Campos de `LivenessResult`

Quando a captura termina, o SDK emite o objeto abaixo via `onSuccess` (e também resolve a Promise de `run` com ele):

```typescript theme={"theme":"catppuccin-latte"}
interface LivenessResult {
  sessionId: string;
  captureId: string;
  verified: boolean;
  status: 'completed' | 'failed';
  processingTime: number;
  base64Data?: string;
  failureReason?: string;
  processedAt?: string;
  retryScreen?: number;
  auditTrailCheck?: boolean;
  replayCheck?: boolean;
  sessionTokenCheck?: boolean;
  livenessCheck?: boolean;
  attemptsLeft?: number;
}
```

| Campo               | Tipo          | Descrição                                                      |                               |   |   |   |   |
| ------------------- | ------------- | -------------------------------------------------------------- | ----------------------------- | - | - | - | - |
| `sessionId`         | `string`      | ID da sessão criada na Plataforma ID.                          |                               |   |   |   |   |
| `captureId`         | `string`      | ID único da captura submetida.                                 |                               |   |   |   |   |
| `verified`          | `boolean`     | Resultado consolidado — `true` quando o liveness foi aprovado. |                               |   |   |   |   |
| `status`            | \`'completed' | 'failed'\`                                                     | Estado da captura no backend. |   |   |   |   |
| `processingTime`    | `number`      | Tempo total de processamento em milissegundos.                 |                               |   |   |   |   |
| `livenessCheck`     | `boolean?`    | Resultado isolado da verificação de vivacidade.                |                               |   |   |   |   |
| `auditTrailCheck`   | `boolean?`    | Validação da trilha de auditoria.                              |                               |   |   |   |   |
| `replayCheck`       | `boolean?`    | Resultado da verificação anti-replay.                          |                               |   |   |   |   |
| `sessionTokenCheck` | `boolean?`    | Validação do token de sessão.                                  |                               |   |   |   |   |
| `failureReason`     | `string?`     | Motivo da falha, quando aplicável.                             |                               |   |   |   |   |
| `processedAt`       | `string?`     | Timestamp ISO-8601 do processamento.                           |                               |   |   |   |   |
| `retryScreen`       | `number?`     | Indicador interno de retry do FaceTec.                         |                               |   |   |   |   |
| `base64Data`        | `string?`     | Dado biométrico opcional.                                      |                               |   |   |   |   |
| `attemptsLeft`      | `number?`     | Tentativas restantes no momento da aprovação.                  |                               |   |   |   |   |

<Info>
  Os quatro `*Check` são as garantias de segurança consolidadas pelo backend. Em uma captura legítima, todos devem ser `true`.
</Info>

## Exemplo completo

```html theme={"theme":"catppuccin-latte"}
<!doctype html>
<html lang="pt-BR">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FaceTec Demo</title>
    <script src="https://cdn.hub-liveness-service.app/facetec/latest/prd/facetec-sdk.js"></script>
  </head>
  <body>
    <button id="iniciar">Iniciar Verificação</button>
    <div id="camera-container" style="width: 480px; height: 480px; background: #000;"></div>
    <pre id="resultado"></pre>

    <script>
      const sdk = window.LivenessFacetecSDK.createFaceTecSDK();
      const resultadoEl = document.getElementById('resultado');

      async function onInit(sessionParams) {
        const r = await fetch('/api/create-session', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(sessionParams),
        });
        if (!r.ok) throw new Error(`Sessão falhou: ${r.status}`);
        return r.json();
      }

      document.getElementById('iniciar').addEventListener('click', async () => {
        resultadoEl.textContent = 'Processando…';
        try {
          await sdk.run({
            mount: '#camera-container',
            env: 'production',
            onInit,
            onSuccess: (data) => {
              resultadoEl.textContent = JSON.stringify(data, null, 2);
            },
            onFailure: (error) => {
              resultadoEl.textContent = `Falhou: ${error.type} — ${error.failureReason ?? ''}`;
            },
          });
        } catch (err) {
          resultadoEl.textContent = `Erro: ${err.message}`;
        }
      });
    </script>
  </body>
</html>
```

## Próximos passos

<CardGroup cols={2}>
  <Card title="Customização" icon="palette" href="/plataforma/liveness/facetec/sdk/web/customizacao">
    Locales, textos e paleta de cores da UI
  </Card>

  <Card title="Solução de problemas" icon="wrench" href="/plataforma/liveness/facetec/sdk/web/troubleshooting">
    Hierarquia de erros e diagnóstico
  </Card>
</CardGroup>
