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

# Ambiente local com túnel

> Rode a jornada inteira na sua máquina, com o webhook chegando no seu localhost.

O webhook precisa de um endereço público em HTTPS, e a sua máquina não tem um. Um túnel resolve, e
é o que separa "integrei" de "vi funcionar".

|               |                                                                          |
| ------------- | ------------------------------------------------------------------------ |
| **Stack**     | qualquer backend · um túnel HTTP                                         |
| **Você terá** | a jornada inteira rodando local, com o desfecho chegando no seu terminal |

<Card title="Confira o exemplo" icon="brand-github" href="https://github.com/Legitimuz-Tech/legitimuz-examples/tree/master/pocs/local-tunnel" horizontal>
  Os arquivos desta POC, com o destino de cada um.
</Card>

## Levantar o túnel

```bash theme={null}
# Escolha um. Os dois expõem a sua porta local num endereço HTTPS público.
npx untun@latest tunnel http://localhost:3000
ngrok http 3000
```

Anote o endereço que ele devolve, como `https://algo-aleatorio.trycloudflare.com`.

## Apontar o webhook para ele

Em **Integrações → Segurança → Webhooks**, crie um endpoint com
`https://<seu-tunel>/api/webhooks/legitimuz` e marque **Verificação decidida**. Copie o
`signing_secret` antes de fechar o diálogo.

<Warning>
  O endereço do túnel muda a cada reinício na maioria das ferramentas. Quando parar de chegar
  entrega, confira primeiro se o endpoint cadastrado ainda aponta para o túnel de agora.
</Warning>

## Cadastrar o domínio do widget

O túnel serve o webhook. O **widget** abre na sua página local, então o domínio autorizado precisa
cobrir ela. Em **Domínios Autorizados**, cadastre o host onde você abre o navegador.

<Info>
  Abra o painel em `localhost`, não em `127.0.0.1`. São origens diferentes para o browser, e só uma
  delas vai estar na sua lista.
</Info>

## Confirmar que fechou o ciclo

<Steps>
  <Step title="Dispare a entrega de teste">
    Pelo botão **Testar** do endpoint. O seu terminal deve registrar um `POST` e responder `200`.
  </Step>

  <Step title="Crie uma verificação de verdade">
    ```bash theme={null}
    curl -X POST https://api.legitimuz.com/public/verifications \
      -H "X-API-Key: $LEGITIMUZ_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "schema_version": "1.0",
        "ref_id": "local-0001",
        "document": { "type": "cpf", "number": "<CPF_DE_TESTE>" },
        "flow_public_id": "'"$LEGITIMUZ_FLOW_ID"'"
      }'
    ```
  </Step>

  <Step title="Percorra a jornada">
    Abra a `entry.url` no navegador e vá até o fim.
  </Step>

  <Step title="Veja o desfecho chegar">
    O seu handler recebe `verification.decided` com o `ref_id` que você mandou.
  </Step>
</Steps>

## Quando a entrega não chega

| Sintoma no dashboard           | Causa provável                                                   |
| ------------------------------ | ---------------------------------------------------------------- |
| Entrega com erro de transporte | o túnel caiu, ou a URL cadastrada é a de outro dia               |
| `401` no seu servidor          | o segredo do `.env` não é o do endpoint que disparou             |
| `419` ou `403`                 | middleware de CSRF na rota de webhook                            |
| `200` mas nada acontece        | o corpo foi parseado antes da conferência, e o handler saiu cedo |

A aba **Webhooks** da integração mostra cada tentativa com o código que o seu servidor devolveu. É
o primeiro lugar a olhar, antes do seu log.

## Antes de rodar

```bash title=".env" theme={null}
LEGITIMUZ_API_KEY=<SUA_CHAVE>
LEGITIMUZ_WEBHOOK_SECRET=<SEGREDO_DO_ENDPOINT>
LEGITIMUZ_FLOW_ID=<FLOW_PUBLIC_ID>
```

| Variável                   | Onde achar                                                                       |
| -------------------------- | -------------------------------------------------------------------------------- |
| `LEGITIMUZ_API_KEY`        | Integrações → Segurança → [Chaves de API](/platform/tokens). Aparece uma vez     |
| `LEGITIMUZ_WEBHOOK_SECRET` | Integrações → Segurança → [Webhooks](/platform/webhooks), na criação do endpoint |
| `LEGITIMUZ_FLOW_ID`        | Solução KYC → Fluxos, no menu da linha, em **Copiar ID do fluxo**                |

Use uma integração **sandbox**. Nenhum dos três valores vai para o browser ou para o app.

## O que esta POC não faz

<Warning>
  POC é código para entender o fluxo, não para copiar em produção. Em todas elas, `authenticate()` é
  um stub, `db` é um objeto de mentira e não há migration, observabilidade nem retentativa própria.
</Warning>

* Túnel gratuito costuma ter teto de requisição e latência alta.
* Sem endereço fixo: cada reinício pede recadastro do endpoint.
* Não substitui um ambiente de homologação de verdade antes de produção.

## Próximo passo

<Columns cols={2}>
  <Card title="Primeira verificação" icon="player-play" href="/guides/first-verification">
    O passo a passo completo em sandbox.
  </Card>

  <Card title="Ir para produção" icon="rocket" href="/start/production">
    O checklist antes do primeiro titular real.
  </Card>
</Columns>
