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

# Authentication

> Create, use, and revoke API keys.

API requests are authenticated with a Bearer token:

```http theme={null}
Authorization: Bearer apf_live_<64 hex chars>
```

The `apf_live_` prefix identifies these as AutoPrintFarm production keys. It
also lets GitHub's secret scanning flag accidental commits.

## Creating a key

Only **owners** and **admins** can mint API keys.

1. Open **Settings → API Keys** in the dashboard.
2. Click **Create API Key**.
3. Enter a descriptive name (e.g. `warehouse-dashboard-prod`).
4. Choose the scopes you need:
   * `read` — list/fetch any resource
   * `write` — create, update, and delete data
   * `control` — physical printer actions (start, pause, stop, heaters, light, filament)
5. Click **Create key**.

<Warning>
  The full key is shown **exactly once** after creation. AutoPrintFarm only
  stores its SHA-256 hash, so we can't recover it for you. Copy it immediately
  into your secret manager.
</Warning>

## Using a key

Send the key in the `Authorization` header on every request:

```bash Terminal theme={null}
curl -H "Authorization: Bearer apf_live_xxx..." \
  https://api.autoprintfarm.com/public/v1/printers
```

```javascript JavaScript theme={null}
const res = await fetch("https://api.autoprintfarm.com/public/v1/printers", {
  headers: { Authorization: `Bearer ${process.env.APF_API_KEY}` },
});
const { data } = await res.json();
```

```python Python theme={null}
import os, requests
r = requests.get(
    "https://api.autoprintfarm.com/public/v1/printers",
    headers={"Authorization": f"Bearer {os.environ['APF_API_KEY']}"},
)
r.raise_for_status()
print(r.json()["data"])
```

## Scopes

Each request checks for the scope the endpoint requires. A key without the
right scope gets `403 INSUFFICIENT_SCOPE`.

| Scope     | Grants                                                                                                                               |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `read`    | Every `GET` endpoint (printers, jobs, inventory, orders, products, files, hubs, assembly, materials, wiki, worklist, analytics)      |
| `write`   | Data mutations: create/update/delete, uploads, inventory adjustments, BOM edits, order fulfillment, job enqueue/patch/retry/complete |
| `control` | Physical printer commands: start, pause, resume, stop, heaters, light, filament load/unload, cancel a running print                  |

Keys can hold any combination of scopes. Grant only what you need.

## Revoking a key

Open **Settings → API Keys** and click the trash icon on a row. Revocation is
immediate — the next request using that key returns `401 TOKEN_REVOKED`.

If you think a key may have leaked, revoke it and mint a new one. There is no
rotation flow — just create + revoke.

## Error codes

| HTTP | Code                 | Meaning                                       |
| ---- | -------------------- | --------------------------------------------- |
| 401  | `UNAUTHORIZED`       | Missing `Authorization` header                |
| 401  | `TOKEN_INVALID`      | Bad prefix or unknown hash                    |
| 401  | `TOKEN_REVOKED`      | Key was revoked                               |
| 401  | `TOKEN_EXPIRED`      | Key expired (if expiration was set)           |
| 403  | `INSUFFICIENT_SCOPE` | Key doesn't have the scope the endpoint needs |
| 429  | `RATE_LIMITED`       | You exceeded the per-key rate limit           |
