Authentication
Every call except GET /v1/health and POST /v1/validate/* carries an API key.
The header
Send Authorization: Bearer <key>. Keys are created on the dashboard. The full key is shown once: only its SHA-256 hash is stored, so a lost key cannot be recovered — create a new one and revoke the old.
Authorization: Bearer co_live_…Three kinds of key
- Live keys — for production. They come with an Engine API plan and draw on its monthly quota.
- Test keys — free for any signed-in account: 1,000 calls a month, never billed, counted separately from live keys. GET /v1/usage answers env: "test" for them.
- The public demo key — behind the "Run this example" buttons: no account, small synchronous 2D, 1D and wood jobs only, rate-limited. Every answer carries X-CutOptim-Demo: true.
One quota per account
An account holds up to 10 active live keys, and they all draw on the same monthly quota — more keys do not add allowance. Use them to separate environments and integrations. When the quota is used up, every key answers 402 until the month resets or a larger plan is chosen.
Rotating and revoking a key
Create the new key, switch your integration to it, then revoke the old one on the dashboard. A revoked key is refused at once with 403 key_revoked. Revoking is not a billing action and does not give back calls already spent.
GET /v1/usage
{
"plan": "studio",
"used": 137,
"limit": 10000,
"remaining": 9863,
"periodEnd": "2026-08-01",
"keyPrefix": "co_live_ab12",
"contractVersion": "1"
}Read-only: it does not consume a call and sends no rate-limit headers. ⚠️ used and limit describe the ACCOUNT, not the key you called with: every active key on the account draws on one shared allowance, so creating more keys does not create more quota. used counts the current UTC calendar month across all of them, remaining is limit minus used and never goes negative, periodEnd is the reset day as a plain YYYY-MM-DD date, and keyPrefix is the non-secret display prefix of the key you called with.
The key itself is never returned by any endpoint — only its hash is stored, so a lost key is replaced, not recovered.
| Field | Type | Description |
|---|---|---|
| plan | string | The tier slug frozen onto the key when it was minted. Re-pricing the product later does not rewrite a live key. |
| used | integer | Calls counted in the current UTC calendar month, across EVERY key on the account — revoked keys included, so revoking a key cannot un-spend what it spent (053) — not just the one you called with. The quota is account-wide. |
| limit | integer | The monthly cap for the ACCOUNT: the largest monthly quota frozen onto any of its ACTIVE keys (049). All active keys draw on this one allowance; creating more keys does not create more quota. Keys are for separating environments and integrations (and for revoking one without disturbing the rest). |
| remaining | integer | limit − used, never negative. |
| periodEnd | string (date) | First day of next month as YYYY-MM-DD — a DATE, not a timestamp. The counter resets at 00:00 UTC on that day. |
| keyPrefix | string | Non-secret display prefix of the calling key, so you can tell which key you queried. The key itself is never returned by any endpoint. |
| contractVersion | string | Shape version. Currently "1". |
| env | "test" | Present ("test") only for a TEST key: created in the dashboard, never billed, with its own monthly allowance separate from the live keys. Absent for a live key — a live key gets exactly the body it always got. |
| keyClass | "tenant" | Present ("tenant") only for a key CutOptim issues to its own first-party service. Absent for every key you create in the dashboard. |