Errors
Every error code the API returns, what causes it and what to do about it.
Every failed call returns an HTTP status and a JSON body with a stable code. Branch on the code, show the message to people, and keep the request_id for support.
{
"error": {
"code": "FORBIDDEN",
"message": "permission denied: records:create",
"request_id": "9f2c41a0b7d3e655"
}
}
Codes
| Status | Code | When it happens | What to do |
|---|---|---|---|
| 400 | VALIDATION_ERROR |
The request is malformed or a value breaks a rule: wrong type, missing required field, limit out of range, bad cursor | Read message. For record values it names the field, such as amount: expected a number |
| 401 | UNAUTHORIZED |
The key is missing, invalid or revoked, or the route does not accept keys | Check the Authorization: Bearer axk_… header. See Authentication |
| 402 | LIMIT_EXCEEDED |
A free-plan cap was reached (for example record count, file storage, Ask Axis usage or team size) | Upgrade the plan in Settings › Billing & usage, or remove data. Paid plans are never blocked |
| 403 | FORBIDDEN |
The key's roles do not allow this action | Add the permission to the role. message names it, such as records:create |
| 403 | ORG_SUSPENDED |
The workspace is suspended | Contact support |
| 404 | NOT_FOUND |
The item does not exist, you may not know it exists, the key belongs to another workspace, or the app is switched off | Check the id and the Settings › Apps switches |
| 409 | KEY_TAKEN |
A key, slug, path or name you chose is already used | Choose another |
| 409 | DUPLICATE_VALUE |
A field marked unique already holds this value | Use another value or update the existing record |
| 409 | SLOT_TAKEN |
A calendar slot was just booked by someone else, or the calendar does not allow overlaps | Pick another time |
| 409 | SHEET_LOCKED |
Another editor holds the workbook | Retry shortly |
| 409 | AGENT_BUSY |
Ask Axis is already working on a request in that conversation | Wait for it to finish |
| 429 | RATE_LIMITED |
Too many requests. See Conventions | Wait a minute and retry |
| 500 | INTERNAL |
Something went wrong on our side | Retry once. If it persists, send the request_id to support |
| 502 | AGENT_ERROR |
An AI-assisted call (generate, natural-language query) could not be completed | Retry later |
| 502 | MARKETPLACE_ERROR |
A connected store answered with an error | Check the store connection |
| 502 | DATASOURCE_ERROR |
A connected external data source failed or refused the query | Check the data source in Analytics |
| 503 | ORG_NOT_READY |
The workspace is being set up or upgraded. A Retry-After header gives seconds |
Wait and retry |
| 503 | AGENT_DISABLED |
AI assistance is not available for this call | Use a manual alternative |
| 503 | KNOWLEDGE_DISABLED |
Knowledge search is not available | Try again later |
| 503 | SHEETS_MEMORY |
A spreadsheet could not be opened because the memory allowance was exceeded | Close or release other workbooks, or upgrade |
Behaviour to rely on
- Not found instead of forbidden. A record, workspace or form you cannot see answers
404, not403, so ids never leak. A route you may know exists but cannot use answers403. - Validation messages name the field for record writes (
status: must be one of the configured options). - Deletes and some updates return
204 No Contentwith an empty body on success. - Idempotency. Creating the same record twice creates two records unless a unique field stops it. Work queue items, however, are idempotent on their key, so a repeated enqueue or scan does not duplicate. See Work Queues.
- Retries. Retry
500,502,503and429with a short growing delay. Do not retry400,401,403,404or409without changing something.
Handling errors in code
status=$(curl -s -o body.json -w "%{http_code}" -X POST \
https://axisiq.co/api/v1/orgs/$ORG/records/invoices \
-H "Authorization: Bearer $AXIS_KEY" -H "Content-Type: application/json" \
-d '{"values": {"number": "INV-1001"}}')
if [ "$status" -ge 400 ]; then
jq -r '.error | "\(.code): \(.message) (ref \(.request_id))"' body.json
fi