# Autenticação

URL: https://staging.pagpolar.com/docs/guias/fundamentos/autenticacao

> Troque a chave de API pelo token de acesso, envie o token em Authorization e entenda cada resposta 401 e 403.

A API usa dois valores diferentes, e cada um tem um lugar só:

| Valor           | Onde vai                                                         | Para que serve           |
| --------------- | ---------------------------------------------------------------- | ------------------------ |
| Chave de API    | Header `X-API-Key`, apenas em `POST /auth/token`                 | Obter o token de acesso. |
| Token de acesso | Header `Authorization: Bearer <token>`, em todas as outras rotas | Autenticar cada chamada. |

A chave é criada junto com a credencial, no painel. Veja [Credenciais da API](/docs/guias/fundamentos/credenciais).

> **A chave só entra em POST /auth/token**
>
> As demais rotas, como `GET /me` e `POST /payments/pix`, esperam o token de acesso no header `Authorization`. Enviar `X-API-Key` nelas responde `401`.

## Troque a chave pelo token

`POST /auth/token` é a única rota que recebe a chave. Ela não tem corpo e não usa `Idempotency-Key`.

#### cURL

```bash
    curl -X POST "https://api.pagpolar.com/v1/auth/token" \
      -H "X-API-Key: <SUA_CHAVE_DE_API>"
    ```

#### Node.js

```js
    const response = await fetch('https://api.pagpolar.com/v1/auth/token', {
      method: 'POST',
      headers: { 'X-API-Key': '<SUA_CHAVE_DE_API>' },
    });

    console.log(response.status, await response.json());
    ```

A URL base da API é `https://api.pagpolar.com/v1`. Veja [Ambientes e URL base](/docs/guias/fundamentos/ambientes#url-base).

Resposta `200`:

```json
{
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 86400
  }
}
```

| Campo          | O que significa                                                                   |
| -------------- | --------------------------------------------------------------------------------- |
| `access_token` | O token que vai no header `Authorization` das outras rotas.                       |
| `token_type`   | Sempre `Bearer`.                                                                  |
| `expires_in`   | Segundos até o token expirar, contados a partir da emissão. `86400` são 24 horas. |

Contrato completo: [`POST /auth/token`](/docs/referencia/autenticacao/create-access-token).

## Envie o token em `Authorization`

Todas as outras rotas exigem o header `Authorization` no formato `Bearer <token>`. O jeito mais rápido de testar é chamar `GET /me`:

#### cURL

```bash
    curl "https://api.pagpolar.com/v1/me" \
      -H "Authorization: Bearer <SEU_TOKEN_DE_ACESSO>"
    ```

#### Node.js

```js
    const response = await fetch('https://api.pagpolar.com/v1/me', {
      headers: { Authorization: `Bearer ${accessToken}` },
    });

    console.log(response.status, await response.json());
    ```

Se o token estiver certo, a resposta é `200`:

```json
{
  "data": {
    "credential_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "environment": "PRODUCTION",
    "rate_limit_per_minute": 120
  }
}
```

| Campo                   | O que significa                                                                                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `credential_id`         | Id da credencial dona da chave que gerou o token.                                                                                                                    |
| `environment`           | Ambiente da credencial: `PRODUCTION` ou `STAGING`. Com `STAGING`, as chamadas vão para o [ambiente de testes](/docs/guias/fundamentos/ambientes#ambiente-de-testes). |
| `rate_limit_per_minute` | Quantas requisições por minuto a credencial pode fazer.                                                                                                              |

Contrato completo: [`GET /me`](/docs/referencia/autenticacao/get-current-credential).

## Validade do token

O token vale **24 horas** a partir da emissão (`expires_in: 86400`).

**Não existe rota de renovação nem refresh token.** Quando o token expirar, chame `POST /auth/token` de novo com a mesma chave.

Guarde o token em memória e reaproveite enquanto ele valer. Pedir um token por requisição gasta uma chamada a mais em cada operação, sem nenhum ganho.

## Renove o token quando receber `401`

O padrão que funciona: guardar o token em memória, usar enquanto valer e, ao receber `401`, pegar um token novo e repetir a chamada uma vez.

```js
const apiUrl = 'https://api.pagpolar.com/v1';

let accessToken = null;

async function obterToken() {
  const response = await fetch(`${apiUrl}/auth/token`, {
    method: 'POST',
    headers: { 'X-API-Key': process.env.PAGPOLAR_API_KEY },
  });

  if (!response.ok) {
    throw new Error(`Falha ao obter o token: ${response.status}`);
  }

  const { data } = await response.json();
  accessToken = data.access_token;

  return accessToken;
}

export async function chamarApi(caminho, options = {}) {
  if (!accessToken) await obterToken();

  const enviar = () =>
    fetch(`${apiUrl}${caminho}`, {
      ...options,
      headers: {
        ...options.headers,
        Authorization: `Bearer ${accessToken}`,
      },
    });

  let response = await enviar();

  if (response.status === 401) {
    await obterToken();
    response = await enviar();
  }

  return response;
}
```

> **Repita a chamada no máximo uma vez**
>
> Um `401` que continua depois do token novo não é expiração: é credencial revogada, credencial expirada ou chave errada. Repetir de novo devolve o mesmo `401`. Confira a tabela de erros abaixo.

Em rotas com `Idempotency-Key`, mantenha a **mesma** chave de idempotência ao repetir a chamada. Assim a cobrança não acontece duas vezes. Veja [Idempotência](/docs/guias/fundamentos/idempotencia).

## A credencial é conferida em toda requisição

O token não é uma autorização isolada. A cada requisição, a API lê a credencial que está por trás do token e confere status, data de expiração e IPs autorizados.

Na prática:

* Revogar a credencial, editar a credencial ou mudar os IPs autorizados vale a partir da próxima requisição, inclusive para os tokens já emitidos, mesmo dentro das 24 horas.
* Uma credencial revogada ou expirada responde `401` mesmo com um token dentro da validade.

Não existe como revogar um token específico. Para cortar o acesso, revogue a credencial. Como fazer no painel: [Revogar uma credencial](/docs/guias/fundamentos/credenciais#revogar) e [Restringir por IP](/docs/guias/fundamentos/credenciais#ips).

## Formato da chave

A chave tem quatro partes separadas por `_`. O segundo pedaço mostra o ambiente:

| Ambiente    | Começa com  | Formato                                          |
| ----------- | ----------- | ------------------------------------------------ |
| Produção    | `pgp_live_` | `pgp_live_` + 8 caracteres + `_` + 48 caracteres |
| Homologação | `pgp_test_` | `pgp_test_` + 8 caracteres + `_` + 48 caracteres |

Os caracteres são hexadecimais: números de 0 a 9 e letras de `a` a `f`.

Chaves antigas não têm o pedaço `live` ou `test` (`pgp_` + 8 caracteres + `_` + segredo). Elas continuam válidas em `POST /auth/token`.

## Restrição por IP

Se a credencial tem **IPs autorizados**, a API só aceita requisições que venham de um desses IPs. A conferência acontece nos dois lugares: em `POST /auth/token` e em todas as rotas que usam o token.

A API descobre o IP da requisição nesta ordem:

1. o valor do header `X-Real-IP`;
2. o **último** IP do header `X-Forwarded-For`;
3. o IP da conexão.

Cadastre cada IP de saída do seu servidor, um por um. A comparação é exata: o IP da requisição precisa ser igual a um item da lista. Uma faixa de IPs, como `203.0.113.0/24`, não é tratada como faixa.

## Respostas de erro de autenticação

Todas seguem o [formato de erro](/docs/guias/fundamentos/erros). O `code` é `unauthorized` no 401 e `forbidden` no 403.

| Status | `message`                                                                                                       | Onde               | Causa                                                                                                                                                                  | O que fazer                                                                                                     |
| ------ | --------------------------------------------------------------------------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| 401    | `Header X-API-Key é obrigatório`                                                                                | `POST /auth/token` | O header não foi enviado ou está vazio.                                                                                                                                | Envie a chave no header `X-API-Key`.                                                                            |
| 401    | `Header Authorization é obrigatório. Envie "Authorization: Bearer <token>" com o token de POST /v1/auth/token.` | Demais rotas       | O header não foi enviado ou está vazio.                                                                                                                                | Envie o token em `Authorization`.                                                                               |
| 401    | `Header Authorization inválido. Use o formato "Bearer <token>".`                                                | Demais rotas       | O header veio sem `Bearer`, com outro esquema ou sem o token depois do espaço.                                                                                         | Monte o header como `Bearer ` seguido do `access_token`.                                                        |
| 401    | `Token expirado`                                                                                                | Demais rotas       | Passaram-se mais de 24 horas desde a emissão.                                                                                                                          | Chame `POST /auth/token` de novo com a mesma chave.                                                             |
| 401    | `Token inválido`                                                                                                | Demais rotas       | O token foi adulterado, foi assinado por outra origem ou não é um token desta API.                                                                                     | Descarte o token e peça outro em `POST /auth/token`.                                                            |
| 401    | `Credencial de API inválida`                                                                                    | Todas              | Em `POST /auth/token`, a chave tem formato errado, não existe ou foi copiada errado. Nas demais rotas, a credencial do token não corresponde mais à chave que o gerou. | Copie a chave de novo, sem espaços, e peça um token novo. Se perdeu a chave, revogue a credencial e crie outra. |
| 401    | `Credencial de API revogada ou inativa`                                                                         | Todas              | A credencial foi revogada, inclusive depois da emissão do token.                                                                                                       | Crie uma credencial nova e peça um token com a chave dela.                                                      |
| 401    | `Credencial de API expirada`                                                                                    | Todas              | A data de expiração da credencial passou, inclusive depois da emissão do token.                                                                                        | Crie uma credencial nova e peça um token com a chave dela.                                                      |
| 403    | `IP não autorizado para esta credencial`                                                                        | Todas              | O IP da requisição não está na lista da credencial.                                                                                                                    | Adicione o IP na credencial ou chame a partir de um IP autorizado.                                              |

## Guarde a chave com segurança

* A chave aparece **uma única vez**, na criação. Veja [O que aparece uma única vez](/docs/guias/fundamentos/credenciais#uma-unica-vez).
* Guarde a chave em uma variável de ambiente ou em um cofre de segredos do seu servidor.
* Nunca coloque a chave nem o token no código do navegador, em aplicativo de celular ou no repositório.
* O token também é um segredo: quem tem o token chama a API no seu lugar até ele expirar.
* Se a chave vazar, [revogue a credencial](/docs/guias/fundamentos/credenciais#revogar) na hora e crie outra.

## Próximos passos

- [Erros](/docs/guias/fundamentos/erros) — Leia o formato de erro e decida o que repetir.
- [Limites de requisição](/docs/guias/fundamentos/limites-de-requisicao) — Saiba quantas chamadas por minuto você pode fazer.
