Skip to content

Error codes ​

Every JSON error response has the same shape:

json
{
  "error": "Job not found",
  "code": "NOT_FOUND",
  "requestId": "req-42"
}
FieldAlways presentMeaning
errorYesA human-readable message. Safe to show to users. Do not parse it.
codeYesA stable, machine-readable code. Branch on this.
requestIdYesThe server's ID for this request. Quote it when you report a problem; it matches the server log.
detailsSometimesMore context for some 4xx errors, such as the validation message.

Messages can change between releases. Codes do not, so write client logic against code.

Codes from the HTTP status ​

When a route does not set its own code, the server derives one from the status:

HTTP statuscode
400BAD_REQUEST
401AUTH_REQUIRED
403FORBIDDEN
404NOT_FOUND
409CONFLICT
413PAYLOAD_TOO_LARGE
415UNSUPPORTED_MEDIA_TYPE
422UNPROCESSABLE_ENTITY
429RATE_LIMITED
500INTERNAL_ERROR
501NOT_IMPLEMENTED
503SERVICE_UNAVAILABLE
507INSUFFICIENT_STORAGE

Any other 4xx falls back to BAD_REQUEST, and any other 5xx to INTERNAL_ERROR.

A route can set a more specific code, and then the response carries that code instead. For example, a tool that cannot run because its AI bundle is missing returns a feature-specific code. Those codes are described with the feature that raises them.

Authentication and access ​

codeStatusWhat to do
AUTH_REQUIRED401Send Authorization: Bearer <token> with a session token or an API key (si_...).
FORBIDDEN403The credential is valid but lacks the permission. Ask an admin for the permission.
MUST_CHANGE_PASSWORD403The account must change its password before it can call other endpoints. Call POST /api/auth/change-password with the session token, then retry.
USER_DISABLED403The account is disabled. An admin has to re-enable it.
LOGIN_THROTTLED429Too many failed sign-in attempts. Wait before trying again.
VALIDATION_ERROR400The request body or parameters failed validation. details names the problem.

The first-run admin account is admin with the password admin unless DEFAULT_USERNAME or DEFAULT_PASSWORD changed it. Unless SKIP_MUST_CHANGE_PASSWORD is set, that account gets MUST_CHANGE_PASSWORD on every call until the password changes.

Jobs ​

A job that fails reports its reason on the job itself, not in the HTTP error. Read error.code and error.message from GET /api/v1/jobs/{jobId}. See Progress Tracking.

Not yet cataloged ​

The codes raised by individual features (for example encryption, OIDC, SCIM, and teams) are not described on this page yet. Each one is a stable code; treat an unlisted code as opaque and handle it by its status.