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

# Authentication

> Create, scope, and manage API keys for the DraftLift API.

# Authentication

The DraftLift API uses API keys for authentication. Keys carry **scopes** (what they can do) and an optional **workspace binding** (which workspace they operate against). Both are chosen at creation time and cannot be changed after issue — re-issue the key to change them.

## Creating an API key

1. Navigate to **Settings → API Keys** in your DraftLift dashboard.
2. Click **Create API Key** and give it a descriptive name.
3. Pick scopes (**Read** is always included; **Write** is on by default).
4. Pick a workspace binding (or leave it as **All workspaces**).
5. Pick an expiration: **30 days**, **90 days** (default), **365 days**, or **Never**.
6. Copy the key immediately — it is only shown once.

If your account has exactly one workspace, the workspace picker is hidden and the key binds to that workspace automatically.

## API key format

```
dl_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
```

Keys always start with `dl_live_` for easy identification.

## Using your key

Include the key in the `Authorization` header:

```bash theme={null}
Authorization: Bearer dl_live_your_key_here
```

You can also set `DRAFTLIFT_API_KEY` in your environment — the CLI prefers it over the saved credentials file:

```bash theme={null}
export DRAFTLIFT_API_KEY=dl_live_your_key_here
```

## Scopes

| Scope   | What it allows                                                       |
| ------- | -------------------------------------------------------------------- |
| `read`  | Every `GET` endpoint (list, get, search).                            |
| `write` | Everything `read` allows, plus create, update, delete, and generate. |

Scopes are additive. The default for newly issued keys is `["read", "write"]`. The `admin` scope is reserved in the schema but is not surfaced in v1; admin endpoints stay JWT-only.

A scope-gated mutation called with a `read`-only key returns:

```http theme={null}
HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": "FORBIDDEN",
  "message": "This endpoint requires the 'write' scope.",
  "details": {
    "error_code": "insufficient_scope",
    "required_scope": "write",
    "current_scopes": ["read"],
    "upgrade_action": "Re-issue your API key with the required scope at https://app.draftliftai.com/settings/api-keys"
  },
  "trace_id": "tr_..."
}
```

The CLI maps this to exit code 2 and prints the `upgrade_action` URL on its own line.

## Workspace binding

Workspaces partition references, memories, content calendars, and generated drafts. When you create a key, you choose one of two postures:

| Posture                  | When to use                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------------ |
| **All workspaces**       | Multi-workspace agents, CLI on a laptop, anything that operates across workspaces.               |
| **Bound to a workspace** | Per-client keys, scoped CI tokens, or any key you want to silently lock to one workspace's data. |

### Behavior at request time

| Request                                            | Outcome                                                                      |
| -------------------------------------------------- | ---------------------------------------------------------------------------- |
| Unbound key, no `workspace_id`                     | Endpoints that require a workspace return `400` (or operate on the default). |
| Unbound key, explicit `workspace_id`               | Operates on the requested workspace.                                         |
| Bound key, no `workspace_id`                       | Server injects the bound workspace automatically.                            |
| Bound key, `workspace_id` matches the binding      | 200 OK.                                                                      |
| Bound key, `workspace_id` differs from the binding | `403 workspace_mismatch` — the server never silently overrides.              |

### Mismatch errors

```http theme={null}
HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": "FORBIDDEN",
  "message": "This API key is bound to a specific workspace.",
  "details": {
    "error_code": "workspace_mismatch",
    "bound_workspace_id": "ws_aaa...",
    "requested_workspace_id": "ws_bbb..."
  },
  "trace_id": "tr_..."
}
```

For a deeper guide on choosing scopes and binding, see [API Key Scopes & Workspace Binding](/quickstart/api-key-scopes).

## Introspecting a key

```bash theme={null}
curl -H "Authorization: Bearer dl_live_..." \
  https://draftliftai.com/api/v1/api-keys/current
```

Returns the calling key's `name`, `scopes`, `workspace_id`, `expires_at`, and `last_used_at`. This is the only `/api-keys/*` endpoint that accepts API keys — every other key-management operation requires a web session.

## Endpoints not callable with API keys (denylist)

Some operations require an interactive web session and cannot be performed with a `dl_live_` key:

* `POST /api-keys`, `DELETE /api-keys/:id`, `PUT /api-keys/:id` — creating, revoking, or renaming keys.
* `/billing/*` mutations — checkout, portal sessions, refunds, cancel subscription.
* `/admin/*` — every admin endpoint.
* `PUT /me/settings`, `PUT /learning-preferences`, account/profile mutations.
* Auth flows: `/auth/login`, `/cli-auth/*`, OAuth callbacks.

Calling these with a Bearer key returns `401 Unauthorized`. Use the dashboard for these operations.

## Stability and versioning

Endpoints are tagged in the OpenAPI spec:

* **`stable`** — Stable. Breaking changes will require a `/api/v2/...` mount.
* **`beta`** — Functional but the response shape may evolve. New fields are additive; we will not remove or rename fields without a deprecation cycle.
* **`internal`** — Excluded from public docs. Do not depend on these.

Newly dual-auth routes (everything outside `/templates`, `/generate`, `/finalizeContent`, `/thesis`, `/mcp`) ship as `beta` until they have \~30 days of stable use without schema changes.

## Key management

* **Revoke** a key from **Settings → API Keys** — takes effect within seconds.
* **Rename** keys to keep them organized.
* **Monitor usage** per key from the Settings page.
* **Rotate** by creating a replacement, rolling it into your config, then revoking the old key.

## Requirements

API access requires a **Business** or **Agency** plan. Starter and Pro users see an upgrade prompt on the **API Keys** settings tab.
