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

# Token de Serviço

> Obtenha um Bearer token OAuth2 para integrações máquina a máquina usando o fluxo Client Credentials.

# POST /oauth/token

Troque as suas credenciais de integração (`client_id` + `client_secret`) por um Bearer token de curta duração. Este é o método de autenticação recomendado para todas as integrações programáticas.

<Note>
  Este endpoint não requer autenticação prévia. As credenciais são provisionadas pelo seu gestor de conta DokStamp.
</Note>

***

## Pedido

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

| Parâmetro       | Tipo   | Obrigatório | Descrição                            |
| --------------- | ------ | ----------- | ------------------------------------ |
| `grant_type`    | string | Sim         | Deve ser `client_credentials`        |
| `client_id`     | string | Sim         | ID de cliente da sua integração      |
| `client_secret` | string | Sim         | Segredo de cliente da sua integração |

<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 `200`

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

| Campo          | Tipo    | Descrição                                                                 |
| -------------- | ------- | ------------------------------------------------------------------------- |
| `access_token` | string  | Bearer token — inclua no header `Authorization` de todos os pedidos à API |
| `expires_in`   | integer | Validade em segundos (`43200` = 12 horas)                                 |
| `token_type`   | string  | Sempre `"Bearer"`                                                         |

## Erro `401`

```json theme={null}
{
  "error": "invalid_client",
  "error_description": "Client authentication failed",
  "message": "Client authentication failed"
}
```

***

## Utilizar o token

Adicione o token a cada pedido subsequente:

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

***

## Expiração e renovação do token

Os tokens de serviço expiram após **12 horas**. Não existe refresh token — solicite um novo token quando o atual expirar. Padrão recomendado: guarde o token em cache e renove-o 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;
}
```

***

## Rotação de credenciais

Se um `client_secret` for comprometido, contacte o seu gestor de conta DokStamp para proceder à rotação das credenciais. Será emitido um novo par `client_id` / `client_secret` e todos os tokens existentes para as credenciais antigas serão imediatamente revogados.
