Keys and scopes
Every request carries your business's API key in the Authorization header:
Authorization: Bearer ocost_sk_<id>_<secret>curl -sS https://api.ocost.io/public/v1/files \
-H "Authorization: Bearer $OCOST_KEY"import requests
session = requests.Session()
session.headers["Authorization"] = f"Bearer {key}"
files = session.get("https://api.ocost.io/public/v1/files", timeout=15).json()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. 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
- Make a new key with the same scopes.
- Switch your software to it.
- 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 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. |