Errors
Errors
Corteksa uses standard HTTP status codes and one JSON error shape, so you can handle failures the same way across every endpoint.
Error shape
Every error response has this body:
| Key | Type | Always present | Meaning |
|---|---|---|---|
status | number | yes | The HTTP status code, repeated. |
message | string | yes | What went wrong, in plain words. Always one string, never an array. |
code | string | no | A stable reason you can branch on, such as INVALID_ASSIGNEE. Only some errors set it. |
data | object | no | Extra detail about the error. Only some errors set it. |
An error with a code and data:
Branch on status and, when it is present, code. Do not parse message: its
wording can change.
Validation errors
When a request body or query parameter fails validation, the answer is 422.
message describes only the first problem found; fix it and send the
request again to see the next one. For example, a webhook subscription whose
target_url is not an HTTPS URL returns:
A field the endpoint does not declare is rejected too:
When the problem is inside a nested object, message is Validation error.
Status codes
| Code | Meaning | Common cause | Fix |
|---|---|---|---|
| 400 | Bad Request | The body is well-formed, but a value is not accepted: a field value breaks the field's rules, a required field is missing, or a records endpoint gets an object or record slug that does not exist | Read message; key record bodies by field slug |
| 401 | Unauthorized | Missing, invalid, revoked or expired API key or token | Send X-Api-Key or Authorization: Bearer; reconnect if the credential was revoked |
| 403 | Forbidden | Authenticated, but the credential lacks the scope for the route, or the user it acts as may not do this | Grant the read.* / create.* scope or raise the access level |
| 404 | Not Found | The resource does not exist on this path, for example a webhook subscription slug your credential does not own | Check the slug and the credential |
| 409 | Conflict | Another record already has the same value in a unique field | Change the value or update the existing record |
| 422 | Unprocessable Entity | The body or query failed validation, or a rule reported with a code failed | Read message, and code when present |
| 429 | Too Many Requests | The API key went over its per-minute request limit, or too many requests came from one IP address | Wait for the next minute, then retry with backoff |
| 500 | Server Error | Unexpected fault. message is Internal server error | Retry with backoff; if it persists, contact support |
Auth: 401 vs 403
- 401 = "I don't know who you are" — the credential is missing or invalid.
- 403 = "I know who you are, but you can't do this" — the credential's
scopes or the access level (
A > G > M > D) of the user it acts as forbid it.
Not found can mean no access
A record outside the credential's access is treated as if it did not exist, so
you cannot probe for records you cannot see. GET /api/v1/object/data/:objectSlug/:dataSlug
answers 400 with Data with slug '…' not found, and lists and searches leave
the record out. If you are sure the record exists, the access level of the user
the credential acts as is too low for that object.
Handle errors well
- Show
messageto a person; branch your code onstatusandcode. - Retry
429and5xxwith exponential backoff; never retry4xxblindly. - Treat
401as "disconnected". For an OAuth token, refresh once; if that fails, or for an API key, ask the customer to reconnect.