Error codes
A failed call uses the same envelope as a successful one: read the HTTP status code, then read response for a message describing what went wrong. Messages are stable English strings, so you can match on them, but prefer the status code for branching.
{
"code": 403,
"title": "Forbidden",
"response": "The API key is missing the required scope: team:write"
} Status codes
| Code | Title | What it means |
|---|---|---|
| 200 | OK | The call succeeded. Reads, updates and deletes all use this. |
| 201 | Created | A record was created. Used by the key, team and feedback endpoints. |
| 301 | Moved Permanently | You called http://. Repeat the call on https://. |
| 400 | Bad Request | The body was not a JSON object, or a required field was absent. |
| 401 | Unauthorized | No usable key was presented, or the key has expired. |
| 402 | Payment Required | The plan does not cover the action, or its allowance is used up. |
| 403 | Forbidden | The key is unknown, disabled, or short of the required scope. |
| 404 | Not Found | No such path, or no such record in this project. |
| 405 | Method Not Allowed | The method is not accepted on that path. |
| 413 | Payload Too Large | The request body exceeded 200,000 bytes. |
| 422 | Unprocessable entity | The body parsed but a value was rejected, or the method and path do not combine. |
| 501 | Not Implemented | The endpoint is reserved and does not act yet. |
| 503 | Service Unavailable | A backing service was briefly unreachable. Retry. |
| 500 | Internal Server Error | An unexpected fault. Retry, then report it. |
Authentication failures
These are raised before any endpoint code runs, so they can answer any path.
| Code | Message | Cause |
|---|---|---|
| 401 | No valid API key provided. | The Authorization header is absent, or does not begin with Bearer . |
| 401 | The API key has expired. | The key had an expiry and it has passed. A key with no expiry never raises this. |
| 403 | The API key doesn't have permissions to perform the request. | The key is unknown, or it is disabled, or its consumer or project is no longer active. |
Note — An unknown key and a disabled key give the same
403with the same message, on purpose: the API never confirms whether a key exists.
Scope failures
An endpoint checks its scope before doing any work.
| Code | Message | Cause |
|---|---|---|
| 403 | The API key is missing the required scope: <scope> | The key holds neither *, nor <resource>:*, nor the exact scope named. |
| 403 | Cannot create a key with wider scope than the calling key. | You asked for * on a new key while your own key is narrower. |
The message names the scope that was wanted, so the fix is either to widen the key or to stop calling that endpoint. See API keys.
Request failures
| Code | Message | Cause |
|---|---|---|
| 400 | Invalid JSON. | The body is not parseable JSON, or it is a JSON value that is not an object. |
| 413 | Request body too large. | The body exceeded 200,000 bytes. |
| 422 | The parameters were valid but the request failed. | The method and path do not combine into a supported endpoint, or a value was rejected without a more specific message. |
Not found
Two different 404s exist, and they are easy to tell apart.
An unknown path is refused by the gateway, before any endpoint is reached. This one repeats code as a string rather than a number:
{
"code": "404",
"title": "Not Found",
"response": "The requested resource was not found."
} A path that exists but names a record your project cannot see is refused by the endpoint, with a message naming the record type — App not found., Event not found., File not found., API key not found., Team member not found., Feedback not found., Reasoning not found. or Public app not found.
Important — A record that belongs to another project returns the same
404as one that never existed. This is what makes a key safe to hand to a third party: it cannot be used to discover what other projects hold.
Plan and quota failures
The run and app endpoints check the project's plan before acting.
| Code | Title | Message |
|---|---|---|
| 402 | Quota exceeded | Your reasoning quota is exhausted. Please wait until it resets or upgrade your plan. |
| 402 | Payment Required | The current billing plan does not allow custom app creation for this project. |
| 402 | Payment Required | The current billing plan app limit has been reached for this project. |
Call GET /v1/run-usage/summary to read the remaining allowance before you launch a run, and to find when the cycle resets.