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

# Authentication

> Client credentials flow, JWT claims, and response headers.

The Simply Tokenized API uses a **client credentials** flow. Exchange your `client_id` and `client_secret` for a short-lived JWT bearer token.

## Flow

```mermaid theme={null}
sequenceDiagram
  participant Client
  participant API as Simply Tokenized API
  Client->>API: POST /_api/auth (client_id, client_secret, scopes)
  API-->>Client: access_token, expires_at
  Client->>API: GET /_api/offerings (Authorization: Bearer token)
  API-->>Client: 200 + ST-Api-Version header
```

## Request

`POST /_api/auth`

| Field           | Type      | Required | Description                                                                             |
| --------------- | --------- | -------- | --------------------------------------------------------------------------------------- |
| `client_id`     | string    | Yes      | API credential identifier                                                               |
| `client_secret` | string    | Yes      | API credential secret                                                                   |
| `scopes`        | string\[] | Yes      | Fine-grained permissions to request (see [Scopes](/guides/scopes-and-permissions))      |
| `api_version`   | string    | No       | API contract date (`YYYY-MM-DD`). Defaults to credential default or `2026-07-02` (beta) |

## Response

| Field          | Type   | Description               |
| -------------- | ------ | ------------------------- |
| `access_token` | string | JWT bearer token          |
| `token_type`   | string | Always `"Bearer"`         |
| `expires_at`   | string | ISO 8601 expiry timestamp |

## JWT claims

The access token is an HS256 JWT with these claims:

| Claim         | Description                                                     |
| ------------- | --------------------------------------------------------------- |
| `client_id`   | API credential ID                                               |
| `tenant_id`   | Tenant the credential belongs to                                |
| `scopes`      | Granted fine-grained permissions                                |
| `api_version` | Locked API contract version (e.g. `2026-07-02`, currently beta) |
| `iss`         | `st-external-api`                                               |
| `aud`         | `st-api`                                                        |
| `iat` / `exp` | Issued at / expiry (10-minute TTL)                              |

## Token validity

Access tokens are valid for **600 seconds (10 minutes)**. After expiry, call `POST /_api/auth` again.

## Response headers

| Header                | Description                                                    |
| --------------------- | -------------------------------------------------------------- |
| `ST-Api-Version`      | API contract version used for the response (e.g. `2026-07-02`) |
| `ST-Api-Version-Beta` | `true` for beta versions — sent on all `2026-07-02` responses  |

## Using the token

Include the token on all protected requests:

```
Authorization: Bearer {access_token}
```

## Using the API playground

The [API Reference](/api-reference) includes an interactive playground on each endpoint. You do not need to paste your bearer token on every request — set it once and reuse it across endpoints.

<Steps>
  <Step title="Get an access token">
    Open [Authenticate](/api-reference/endpoint/authenticate) (`POST /_api/auth`) in the API Reference. Run the request with your `client_id`, `client_secret`, and scopes. Copy the `access_token` from the response.
  </Step>

  <Step title="Authorize once">
    In the API Reference, open the **Auth** (or **Authorize**) section. Paste your `access_token` into the bearer token field. You do not need to include the `Bearer` prefix — the playground adds it automatically.
  </Step>

  <Step title="Try any endpoint">
    Navigate to any protected endpoint and use **Try it**. The playground sends your saved token on every request until you clear it or it expires.
  </Step>

  <Step title="Refresh when expired">
    Access tokens expire after **10 minutes**. When requests start returning `401`, call `POST /_api/auth` again and update the token in the **Auth** section.
  </Step>
</Steps>

<Note>
  The playground stores your token in your browser's local storage for this documentation site. It persists when you move between endpoints and refresh the page, but it is not shared across browsers or devices.
</Note>

<Tip>
  For longer testing sessions, use a REST client such as Postman or Insomnia with a saved environment variable for `access_token`.
</Tip>

## Failed authentication alerts

After **3 consecutive failed authentication attempts** for the same API credential, an email notification is sent to the **tenant administrators**. The API credential is **not** automatically disabled.

If you receive repeated failure alerts, verify your `client_id` and `client_secret`, confirm you are calling the correct environment base URL, and rotate the credential if the secret may have been compromised.

## Security notes

* Never expose `client_secret` in client-side code or public repositories
* Store credentials in environment variables or a secrets manager
* Request only the scopes your integration needs
