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

# Emitir a credencial

> Crie a verificação no seu backend e entregue ao cliente só o que ele pode ter.

A verificação nasce no seu servidor. É ali que a chave de API vive, e é de lá que sai a credencial
de curta duração que o cliente usa.

## Chamada

<CodeGroup>
  ```ts title="Node.js" theme={null}
  const resposta = await fetch("https://api.legitimuz.com/public/verifications", {
    method: "POST",
    headers: {
      "X-API-Key": process.env.LEGITIMUZ_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      schema_version: "1.0",
      ref_id: "pedido-4471",
      document: { type: "cpf", number: cadastro.cpf },
      integration_origin_public_id: process.env.LEGITIMUZ_ORIGIN_ID!,
    }),
  });

  if (!resposta.ok) {
    const erro = await resposta.json();
    throw new Error(`Legitimuz respondeu ${resposta.status}: ${erro.message}`);
  }

  const { verification, entry } = await resposta.json();
  ```

  ```python title="Python" theme={null}
  import os
  import httpx

  resposta = httpx.post(
      "https://api.legitimuz.com/public/verifications",
      headers={
          "X-API-Key": os.environ["LEGITIMUZ_API_KEY"],
          "Content-Type": "application/json",
      },
      json={
          "schema_version": "1.0",
          "ref_id": "pedido-4471",
          "document": {"type": "cpf", "number": cadastro.cpf},
          "integration_origin_public_id": os.environ["LEGITIMUZ_ORIGIN_ID"],
      },
      timeout=10,
  )

  if resposta.is_error:
      raise RuntimeError(f"Legitimuz respondeu {resposta.status_code}: {resposta.json()['message']}")

  dados = resposta.json()
  verification, entry = dados["verification"], dados["entry"]
  ```

  ```php title="PHP" theme={null}
  <?php

  $resposta = $client->post('https://api.legitimuz.com/public/verifications', [
      'headers' => [
          'X-API-Key' => getenv('LEGITIMUZ_API_KEY'),
          'Content-Type' => 'application/json',
      ],
      'json' => [
          'schema_version' => '1.0',
          'ref_id' => 'pedido-4471',
          'document' => ['type' => 'cpf', 'number' => $cadastro->cpf],
          'integration_origin_public_id' => getenv('LEGITIMUZ_ORIGIN_ID'),
      ],
      'http_errors' => false,
  ]);

  $dados = json_decode((string) $resposta->getBody(), true);

  if ($resposta->getStatusCode() >= 400) {
      throw new RuntimeException("Legitimuz respondeu {$resposta->getStatusCode()}: {$dados['message']}");
  }
  ```

  ```go title="Go" theme={null}
  corpo, _ := json.Marshal(map[string]any{
  	"schema_version": "1.0",
  	"ref_id":         "pedido-4471",
  	"document":       map[string]string{"type": "cpf", "number": cadastro.CPF},
  	"integration_origin_public_id": os.Getenv("LEGITIMUZ_ORIGIN_ID"),
  })

  req, _ := http.NewRequestWithContext(ctx, http.MethodPost,
  	"https://api.legitimuz.com/public/verifications", bytes.NewReader(corpo))
  req.Header.Set("X-API-Key", os.Getenv("LEGITIMUZ_API_KEY"))
  req.Header.Set("Content-Type", "application/json")

  resposta, err := http.DefaultClient.Do(req)
  if err != nil {
  	return err
  }
  defer resposta.Body.Close()

  if resposta.StatusCode >= 400 {
  	return fmt.Errorf("legitimuz respondeu %d", resposta.StatusCode)
  }
  ```
</CodeGroup>

<Card title="Referência completa" icon="terminal" href="/api/create-verification" horizontal>
  Todos os campos e os onze códigos de resposta.
</Card>

## O que devolver ao cliente

Só a `entry`. Nada mais.

| Campo                                    |                Vai para o cliente               |
| ---------------------------------------- | :---------------------------------------------: |
| `entry.url` ou `entry.access_credential` |                       sim                       |
| `verification.public_id`                 |      não é necessário, guarde no seu banco      |
| `verification.expires_at`                | opcional, se a sua interface mostra um contador |

```ts title="A resposta da sua rota" theme={null}
// Guarde o vínculo antes de responder: sem ele, o webhook chega e você não sabe de quem é.
await db.cadastros.vincularVerificacao(cadastro.id, verification.public_id);

res.json({ entry });
```

<Warning>
  Nunca devolva a chave de API, e nunca deixe o cliente escolher o CPF. O documento vem do seu
  cadastro; se ele vier do corpo da requisição, qualquer um cria verificação para qualquer pessoa
  na sua conta.
</Warning>

## Retentativa

A criação é idempotente por `ref_id`. Repetir com o mesmo `ref_id` e o mesmo corpo devolve a
verificação existente com `200`, em vez de criar uma segunda.

Isso torna o retry seguro depois de um timeout de rede.

```ts title="Repetir sem duplicar" theme={null}
async function criarComRetry(corpo: CriarVerificacao, tentativa = 0): Promise<Resposta> {
  const resposta = await chamarLegitimuz(corpo);

  const recuperavel = resposta.status === 429 || resposta.status >= 500;
  if (!recuperavel || tentativa >= 4) return resposta;

  const retryAfter = Number(resposta.headers.get("Retry-After"));
  const espera = Number.isFinite(retryAfter) ? retryAfter * 1000 : 2 ** tentativa * 500;
  await new Promise((r) => setTimeout(r, espera + Math.random() * 250));

  return criarComRetry(corpo, tentativa + 1);
}
```

| Código                                   | Repetir                            |
| ---------------------------------------- | ---------------------------------- |
| `429`, `500`, `503`                      | sim, com backoff                   |
| `400`, `403`, `404`, `409`, `415`, `422` | não, a mesma chamada falha de novo |
| `401`                                    | não, até corrigir a chave          |

<Card title="Erros da API" icon="alert-triangle" href="/api/errors" horizontal>
  O envelope e o catálogo completo.
</Card>

## Onde guardar a chave

| Ambiente          | Onde                                                   |
| ----------------- | ------------------------------------------------------ |
| Desenvolvimento   | `.env` fora do controle de versão                      |
| Produção          | cofre de segredos do seu provedor                      |
| Em qualquer lugar | **nunca** no repositório, no bundle do front ou em log |

## Próximo passo

<Columns cols={2}>
  <Card title="Abrir na web" icon="browser" href="/guides/web/vanilla-js">
    O que fazer com a `entry` no browser.
  </Card>

  <Card title="Receber a decisão" icon="webhook" href="/webhooks/introduction">
    O outro lado do ciclo.
  </Card>
</Columns>
