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

# Autenticação

> Autentique requisições à API usando um token de serviço obtido via o fluxo OAuth2 Client Credentials.

# Autenticação

Todas as requisições à API são autenticadas usando um **Token de Serviço** — um Bearer token de curta duração obtido via o grant OAuth2 Client Credentials. Este é um fluxo máquina a máquina: não há login humano envolvido.

***

## Como funciona

Sua integração possui um `client_id` e um `client_secret` (fornecidos pelo seu gerente de conta DokStamp). Troque-os por um token de acesso e inclua esse token em cada requisição à API.

```
client_id + client_secret
        │
        ▼
POST /oauth/token
        │
        ▼
access_token (válido por 12h)
        │
        ▼
Authorization: Bearer {access_token}
```

***

## 1. Obtenha um token

```http theme={null}
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
```

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.dokstamp.com/oauth/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch('https://api.dokstamp.com/oauth/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: process.env.DOKSTAMP_CLIENT_ID,
      client_secret: process.env.DOKSTAMP_CLIENT_SECRET,
    }),
  });
  const { access_token, expires_in } = await res.json();
  ```

  ```php PHP theme={null}
  $response = Http::asForm()->post('https://api.dokstamp.com/oauth/token', [
      'grant_type'    => 'client_credentials',
      'client_id'     => env('DOKSTAMP_CLIENT_ID'),
      'client_secret' => env('DOKSTAMP_CLIENT_SECRET'),
  ]);
  $token = $response->json('access_token');
  ```
</CodeGroup>

**Resposta:**

```json theme={null}
{
  "token_type": "Bearer",
  "expires_in": 43200,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."
}
```

| Campo          | Descrição                                                    |
| -------------- | ------------------------------------------------------------ |
| `access_token` | Incluir em cada requisição à API via `Authorization: Bearer` |
| `expires_in`   | Validade em segundos — **43 200 = 12 horas**                 |

***

## 2. Use o token

Inclua o token em cada requisição subsequente:

```http theme={null}
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
Accept: application/json
X-Tenant: your-tenant-identifier
```

***

## 3. Renovação do token

Os tokens expiram após **12 horas**. Não há refresh token — solicite um novo usando suas credenciais quando necessário. Padrão recomendado: armazene o token em cache e renove proativamente \~60 segundos antes da expiração.

```javascript theme={null}
let token = null;
let expiresAt = null;

async function getToken() {
  if (token && Date.now() < expiresAt - 60_000) return token;

  const res = await fetch('https://api.dokstamp.com/oauth/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: process.env.DOKSTAMP_CLIENT_ID,
      client_secret: process.env.DOKSTAMP_CLIENT_SECRET,
    }),
  });

  const data = await res.json();
  token = data.access_token;
  expiresAt = Date.now() + data.expires_in * 1000;
  return token;
}
```

***

## Endpoints públicos

Estes endpoints **não** requerem autenticação:

| Endpoint                     | Finalidade                   |
| ---------------------------- | ---------------------------- |
| `POST /oauth/token`          | Obter um token de serviço    |
| `GET /files/{uuid}/download` | Baixar um documento assinado |

<Note>
  Armazene `client_id` e `client_secret` em variáveis de ambiente ou em um gerenciador de segredos. Nunca os inclua diretamente no código-fonte.
</Note>
