Error Handling

All Thallus API errors return a consistent JSON structure with an error type, human-readable message, and optional details. This page covers the error format, status codes, and when to retry.


Error response format

Every error response follows this structure:

ERROR RESPONSE
{ "error": "NotFoundError", "message": "Document not found", "details": null }
Field Type Description
error string Error type name (e.g., NotFoundError, ValidationError)
message string Human-readable explanation of what went wrong
details object or null Additional context when available

HTTP status codes

2xx Success 4xx Client Error 5xx Server Error
Code Meaning When returned
200 OK Successful request
201 Created Resource successfully created (registration, new workflow, new document)
400 Bad Request Invalid request body, malformed input, business logic violation
401 Unauthorized Missing or invalid authentication credentials
403 Forbidden Valid credentials but insufficient permissions
404 Not Found Requested resource does not exist
409 Conflict Resource already exists (duplicate email, active task already running)
422 Unprocessable Entity Request body fails schema validation
429 Too Many Requests Rate limit exceeded — check Retry-After header
500 Internal Server Error Unexpected server error

Validation errors (422)

When the request body fails schema validation, the response includes a details array describing each field error:

422 VALIDATION ERROR
{ "error": "validation_error", "message": "Invalid request data", "details": [ { "type": "value_error", "loc": ["body", "email"], "msg": "Invalid email address", "input": "not-an-email" } ] }

Each entry in the details array contains:

Field Description
type Error category (value_error, type_error, missing)
loc Path to the invalid field (e.g., ["body", "email"])
msg Human-readable error message for this field
input The value that was provided

Multiple fields can fail validation simultaneously — always iterate the full details array.


Authentication errors (401)

A 401 response means your credentials are missing, expired, or invalid.

Scenario Error type Message
No credentials provided AuthenticationError Not authenticated
Expired JWT AuthenticationError Token has expired
Invalid JWT signature AuthenticationError Invalid token
Invalid API key AuthenticationError Invalid API key
Revoked API key AuthenticationError API key has been revoked
Expired API key AuthenticationError API key has expired

Handling 401 errors: If using JWT authentication, attempt a token refresh before retrying. If the refresh also fails, redirect to login. If using an API key, verify the key is active in your dashboard.


Permission errors (403)

A 403 response means your identity is recognized but you lack permission for the requested action.

Scenario Error type Message Details
Insufficient role PermissionError Admin access required
Wrong organization PermissionError Not authorized for this organization
BYOK not configured byok_config_required Model configuration required {"redirect": "/settings?tab=models"}
Feature not available PermissionError Feature requires Pro plan

When you receive a BYOK configuration error, the details.redirect field indicates where the user should configure their model provider. See Model Configuration for setup details.


Rate limit errors (429)

Rate limit responses always include a Retry-After header with the number of seconds to wait:

429 RATE LIMITED
Retry-After: 60
{ "detail": "Too many requests. Please try again later." }

Always respect the Retry-After value. See Rate Limiting for the specific limits and lockout rules.


Retry guidance

Not all errors should be retried. Use the status code to determine the correct strategy.

Transient (retryable)
429, 500, 502, 503
Permanent (do not retry)
400, 401, 403, 404, 409, 422

Transient errors — retry with backoff

Code Strategy
429 Wait for Retry-After seconds, then retry once
500 Exponential backoff: 1s, 2s, 4s, up to 30s max. Stop after 3 attempts
502/503 Same as 500 — the server is temporarily unavailable

Permanent errors — do not retry

Code What to do
400 Fix the request body and resubmit
401 Refresh your token or check your API key
403 Check your user role or plan tier
404 Verify the resource ID exists
409 The resource already exists — fetch it instead of creating
422 Fix the validation errors listed in details

Common error scenarios

Scenario Code Error Resolution
Send chat without auth header 401 AuthenticationError Add Authorization or X-API-Key header
JWT expired mid-session 401 AuthenticationError Refresh token and retry the request
Upload to nonexistent collection 404 NotFoundError Verify collection ID before uploading
Create workflow exceeding plan limit 403 PermissionError Upgrade plan or delete unused workflows
Start a second concurrent task 409 Conflict Wait for the active task to complete
Submit invalid connection credentials 400 ValidationError Check hostname, port, and credentials
Register with existing email 409 Conflict Use login instead, or reset password
Query data connection while rate limited 429 RateLimitError Wait for Retry-After and reduce query frequency