# Autenticação

A API do marketplace UniSupri usa autenticação **bearer token** em todos os endpoints de seller. O token é obtido a partir de uma credencial (username + senha) criada no Portal do Vendedor. Leia [Primeiros Passos](/guia/primeiros-passos) se ainda não criou a sua.

---

## Modelo

```mermaid
sequenceDiagram
    autonumber
    participant I as Integrador
    participant A as API

    I->>A: POST /integration/auth<br/>{ username, password }
    A-->>I: { token, expires_at }
    I->>A: GET /api/* + Bearer sk_live_*
    A-->>I: 200 OK
```

**Dois conceitos distintos:**

| Conceito | Onde mora | Quem usa | Quando renova |
|----------|-----------|----------|---------------|
| **Credencial** (`username` + `senha`) | Portal do Vendedor | Operador humano | Manualmente, quando suspeita de vazamento ou rotação programada |
| **Token de acesso** (`sk_live_*`) | Memória do ERP | Sistema externo | Automaticamente via `/api/integration/auth`, antes de expirar |

A credencial **fica parada** no seu cofre de senhas e não vai em chamadas de API. O token é o que circula em cada requisição.

---

## Obter um token

<a class="api-route" href="/reference/primeiros-passos#tag/autenticação/POST/api/integration/auth"><span class="api-method api-method-post">POST</span><span class="api-path">/api/integration/auth</span></a>

Endpoint **público**, não exige `Authorization`. A própria credencial (no body) é a forma de autenticação.

### Request

```json
{
  "username": "loja-xpto@12345678",
  "password": "Xk9p2Lm7nQ4rT8vW3yZ1"
}
```

### Response 200

```json
{
  "success": true,
  "data": {
    "token": "sk_live_a1b2c3d4e5f6...",
    "expires_at": "2026-06-19T12:34:56-03:00"
  }
}
```

### Rotação

Cada chamada bem-sucedida ao `/api/integration/auth`:

- Emite um **token novo**.
- Substitui o token anterior. O antigo deixa de funcionar imediatamente.
- Repopula `expires_at` para `agora + 30 dias`.

Implicação prática: **só existe 1 token ativo por credencial**. Se você roda dois sistemas que precisam de tokens independentes, crie **duas credenciais separadas** no portal.

### Quando renovar

Renove **antes** de expirar. Recomendamos disparar uma nova chamada quando faltarem 24-48h pra expiração. Você não vai encontrar um endpoint de refresh-token separado, e isso é proposital: pra manter o fluxo simples, a renovação é a própria chamada ao `/api/integration/auth` — a mesma que você já usa pra obter o token. Um endpoint só, que serve tanto pra primeira emissão quanto pra renovar. Se o token expirar e você fizer uma chamada com ele, a API responde **401** e o ERP deve renovar e tentar de novo.

---

## Usar o token

Em qualquer endpoint do seller, envie o token no cabeçalho `Authorization`:

```bash
curl https://api.sandbox.samdevel.com.br/api/products \
  -H "Authorization: Bearer sk_live_a1b2c3d4e5f6..."
```

A API valida:

1. **Formato:** o token começa com `sk_live_` e tem comprimento esperado.
2. **Existência:** existe uma credencial associada a este token.
3. **Ativação:** a credencial não foi revogada (`active = false`).
4. **Validade:** `expires_at` ainda não passou.

Falha em qualquer uma → resposta **401 Unauthorized**.

---

## Confirmar a autenticação

<a class="api-route" href="/reference/primeiros-passos#tag/sessão/GET/api/stores/auth/session"><span class="api-method api-method-get">GET</span><span class="api-path">/api/stores/auth/session</span></a>

Use para validar que o token está autenticando a loja correta. A resposta traz os dados da loja (id, nome, código, status, tipo, limites e features), a `company` associada (CNPJ, razão social, regime tributário) e `auth_type: "integration_token"`.

---

## Limites de taxa

O `/api/integration/auth` é protegido contra brute-force:

- **5 tentativas por minuto** por par `(IP, username)`.
- Estourou o limite: **429 Too Many Requests**, com `Retry-After` em segundos.

O contador é por par IP+username; tentativas legítimas de outras lojas/IPs não são afetadas.

> Este limite é só da emissão de token. O limite das **demais rotas de integração** está em [Limites de uso](/guia/limites).

---

## Erros possíveis

| Status | Quando acontece | O que fazer |
|--------|-----------------|-------------|
| **401** no `/integration/auth` | Username inexistente, senha errada **ou** credencial inativa | Verifique username/senha. A mensagem é genérica de propósito e não revela qual dos três casos é. Se persistir, confirme no portal que a credencial está ativa. |
| **401** em endpoints autenticados | Token ausente, malformado, revogado ou expirado | Renove o token via `/integration/auth`. Se o erro persistir após renovar, a credencial pode ter sido revogada; verifique no portal. |
| **422** no `/integration/auth` | `username` ou `password` ausente / vazio | Garanta que os dois campos vão no body como strings não-vazias. |
| **429** no `/integration/auth` | Mais de 5 tentativas/minuto pra mesma credencial+IP | Aguarde o `Retry-After` segundos antes de tentar novamente. Cache o token e não chame o auth em loop. |

---

## Trocar a senha

Quando trocar:

- Você suspeita que a senha vazou.
- Rotação preventiva periódica (recomendado a cada 90 dias).
- Trocou de mãos a operação do ERP.

Como trocar:

1. Portal do Vendedor → **Configurações → API & Integrações**.
2. Localize a credencial na lista.
3. Clique no ícone de **chave** (`🔑 Trocar senha`).
4. Escolha **Gerar aleatória** (recomendado) ou **Definir manualmente** (mínimo 12 caracteres).
5. Copie a nova senha. Ela aparece **uma única vez**.

**Importante:** trocar a senha **não invalida o token corrente**. O ERP que está usando o token atual continua funcionando até a próxima expiração ou até você revogar a credencial inteira. Se você precisa **invalidar imediatamente** (suspeita de comprometimento), revogue a credencial (lixeira) e crie uma nova.

---

## Revogar uma credencial

Portal do Vendedor → **Configurações → API & Integrações** → ícone de **lixeira** na linha da credencial.

Efeito imediato:

- Username e senha deixam de autenticar no `/integration/auth`.
- O token corrente (se ainda estiver dentro do prazo) **continua válido até a expiração**, porque a checagem do middleware é pelo `token`, e o registro inteiro foi removido.

Se precisa cortar acesso de imediato, faça nessa ordem:

1. Marque a credencial como inativa (botão futuro) **ou** delete.
2. Acompanhe `last_used_at` para confirmar que o ERP parou de chamar.

---

## Boas práticas

- **Cache o token.** Não chame `/integration/auth` antes de cada requisição; emita um token e use-o pelos 30 dias.
- **Renove proativamente.** Agende um job que renove o token quando faltarem ~24h.
- **Trate 401 como sinal de renovação.** Se uma chamada autenticada retornar 401, renove o token e tente uma vez. Se ainda falhar, alerte um humano.
- **Uma credencial por sistema.** Não compartilhe credenciais entre ERPs diferentes; a rotação substitui o token, e isso quebra o sistema que ficou pra trás.
- **Não logue a senha nem o token em arquivos de log persistentes.** Use mascaramento (`sk_live_...XXXX`).
- **Cofre de senhas.** Guarde `username` + `password` em um gerenciador de segredos (1Password, Vault, AWS Secrets Manager, etc.), nunca em código-fonte commitado.
