# Keys and scopes

Every request carries your business's API key in the `Authorization` header:

```text
Authorization: Bearer ocost_sk_<id>_<secret>
```

```bash
curl -sS https://api.ocost.io/public/v1/files \
  -H "Authorization: Bearer $OCOST_KEY"
```

```python
import requests

session = requests.Session()
session.headers["Authorization"] = f"Bearer {key}"
files = session.get("https://api.ocost.io/public/v1/files", timeout=15).json()
```

```javascript
const files = await fetch('https://api.ocost.io/public/v1/files', {
  headers: { Authorization: `Bearer ${key}` },
}).then((r) => r.json());
```

## Keys

The owner or the accountant makes keys under [Settings › API](https://app.ocost.io/settings/api). Ocost shows a key once and keeps only a fingerprint. If you lose a key, revoke it and make a new one.

The start of a key, `ocost_sk_<id>_`, isn't secret. Settings lists keys by it, with their scopes and last use. Secret scanners spot the `ocost_sk_` prefix in a leak.

A key belongs to one business. One Odoo company is one business with its own key. A business has at most 10 live keys. A key can also expire on a date.

Keep keys on your server. Never put one in a browser, a mobile app or a log.

## Rotate a key

1. Make a new key with the same scopes.
2. Switch your software to it.
3. Revoke the old key. Ocost refuses it from the very next request.

## Scopes

A key may do only what its scopes allow. Settings › API ticks the first three for a new key.

| Scope | Allows |
| --- | --- |
| `documents:write` | `POST /public/v1/files`, `DELETE /public/v1/files/{file_id}`, the MCP tool `send_file` |
| `documents:read` | `GET /public/v1/files`, `GET /public/v1/files/{file_id}`, `GET /public/v1/files/{file_id}/content`, `GET /public/v1/files/{file_id}/document`, `GET /public/v1/documents/{document_id}`, and the MCP tools that read records |
| `search:read` | `GET /public/v1/search`, and the MCP's search tools |
| `figures:read` | The MCP's figures tools. Only the owner makes a key with it. |
| `exports:write` | The MCP's export tools |

[MCP tools](https://docs.ocost.io/en/tools.md) lists each tool under its scope.

No key ever reads people's papers, such as pay slips, payroll or health papers.

## Refusals

| Answer | When |
| --- | --- |
| `401 urn:ocost:key:invalid` | No key, or a malformed, wrong, revoked or expired one, or a deleted business's. The answer is always the same. |
| `403 urn:ocost:key:scope` | The key lacks the route's scope. |
| `429 urn:ocost:key:rate` | Too many requests, or too many wrong keys from one address. Wait `Retry-After` seconds. |
| `400` | The request has an `Ocost-View…` header, which only Ocost's web app sends. |
