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

# Authentication

> How API keys, scopes, and environments work.

The Kordless API uses bearer-token authentication. Your API key is the session — there is no OAuth flow, no token refresh, and no Clerk dependency on the API surface.

## Key format

Every API key is a secret string with an environment prefix:

| Prefix     | Environment | What it reaches                   |
| ---------- | ----------- | --------------------------------- |
| `sk_test_` | Test        | Test-mode data only. Never Live.  |
| `sk_live_` | Live        | Production data. Customer-facing. |

The prefix is not cosmetic — it is the first check the API performs. A Test key cannot address Live data because the environment is encoded in the key itself, before any database lookup.

<Warning>
  Never expose a Live key in client-side code, public repositories, or logs. Live keys can produce real quotes and create real commitments.
</Warning>

## Sending the key

Pass the key as a bearer token in the `Authorization` header:

```bash theme={null}
curl https://your-kordless-instance.com/v1/accounts/current \
  -H "Authorization: Bearer sk_test_..."
```

## Key storage

Only the SHA-256 hash of a key is stored. The plaintext secret is returned exactly once — at mint time or at rotation. A display prefix (for example, `sk_test_a1b2c3`) is stored so you can recognize the key in the Developers page without the secret.

## Scopes

Each key has a set of scopes that limit which operations it can perform. When you mint a key, choose the minimum set of scopes your integration needs.

| Scope               | What it allows                            |
| ------------------- | ----------------------------------------- |
| `accounts:read`     | List and retrieve account targets.        |
| `quote-spec:read`   | Read the published Book specification.    |
| `simulations:write` | Run non-persistent price simulations.     |
| `quotes:write`      | Produce formal, persisted quotes.         |
| `commitments:write` | Create and confirm commitments on quotes. |
| `logs:read`         | Read API request logs.                    |

If a key lacks the required scope for an operation, the API returns a `403` with `code: "insufficient_scope"`.

## Key lifecycle

### Minting

Only an organization admin can mint API keys. Minting requires the `api_access` feature on the account.

### Rotation

Rolling a key creates a new key with the same name, environment, and scopes, and schedules the old key for revocation after a grace period:

* **Default grace**: 24 hours.
* **Maximum grace**: 168 hours (7 days).
* **Immediate rotation**: Set grace to 0 hours.

During the grace period, both keys work. The old key's `revoked_at` is set to a future timestamp; the API accepts it until that instant passes. After expiry, the old key returns `401` with `code: "revoked_api_key"`.

### Revocation

Revoking a key kills it immediately. The revocation timestamp is preserved — if the key was already revoked, the original timestamp is kept.

### Status

| Status     | Meaning                                                                                |
| ---------- | -------------------------------------------------------------------------------------- |
| `active`   | The key is valid and accepted.                                                         |
| `rotating` | The key is in a grace period after rotation. Still accepted until `revoked_at` passes. |
| `revoked`  | The key is no longer accepted.                                                         |

## Checking key liveness

Use `GET /v1/accounts/current` to verify a key and inspect its environment and scopes:

```json theme={null}
{
  "object": "account",
  "id": "acct_abc123",
  "name": "Brandon's Auto Studio",
  "environment": "test",
  "scopes": ["accounts:read", "quote-spec:read", "simulations:write"],
  "entitlements": ["api_access", "price_book", "quote_engine", "quote_ui", "accounts"]
}
```

This endpoint requires no specific scope — any valid key can call it. Use it as a health check in your integration.

## Rate limiting

API requests are rate-limited per account and environment, not per key. Sibling keys on the same account and environment share one quota.

| Header                | Description                               |
| --------------------- | ----------------------------------------- |
| `ratelimit-limit`     | The maximum requests per minute.          |
| `ratelimit-remaining` | Requests remaining in the current window. |
| `ratelimit-reset`     | Seconds until the window resets.          |

The default limit is 600 requests per minute. When the limit is exceeded, the API returns `429` with a `retry-after` header.

## What authentication does not do

* Authentication does not authorize Book authoring or verification. Those are workspace operations.
* Authentication does not manage billing or plans. Those are admin operations.
* A key's scopes do not override the Book's autonomy mode. If the Book is in approval-first mode, every produced quote is held for owner review regardless of the API key's scopes.
