ScalixScalix Docs

Errors

Error codes, formats, and handling guidance

Error Response Format

All errors follow a consistent format:

json
{
  "error": "Invalid API key",
  "code": "AUTH_FAILED",
  "request_id": "req_abc123",
  "docs_url": "https://docs.scalix.world/api-reference/errors#AUTH_FAILED"
}

Error Codes

Authentication & Authorization

CodeHTTPDescription
AUTH_FAILED401Missing, expired, or malformed token
FORBIDDEN403Insufficient scope or wrong tenant

Request Errors

CodeHTTPDescription
BAD_REQUEST400Invalid request structure
VALIDATION_ERROR422JSON parsing or type mismatch
NOT_FOUND404Resource doesn't exist
ALREADY_EXISTS409Duplicate constraint violation
PAYLOAD_TOO_LARGE413Request body exceeds limit

Rate Limiting

CodeHTTPDescription
RATE_LIMITED429Too many requests

Check X-RateLimit-Reset header for when to retry.

Server Errors

CodeHTTPDescription
NOT_CONFIGURED501Feature not enabled for this project
INTERNAL_ERROR500Unexpected server error
BAD_GATEWAY502Backend service unavailable
GATEWAY_TIMEOUT504Backend service didn't respond

Auth-Specific Errors

CodeHTTPDescription
AUTH_FAILED401Sign-in failed. Returned identically for a wrong password, a non-existent account, and a locked account — the reason is deliberately not disclosed to prevent account enumeration and lockout probing.
FORBIDDEN403Action not permitted for this account or token — includes an unverified email attempting a gated action.
BAD_REQUEST400Malformed request, including a failed bot-prevention (captcha) check.

Database-Specific Errors

CodeHTTPDescription
QUERY_BLOCKED403Query rejected by policy — a write with a read-only key, a forbidden DDL/schema change, or a firewall rule.
QUERY_ERROR400Query failed to execute (syntax error, constraint violation, timeout, or other database error).

Handling Errors

The TypeScript SDK returns a { data, error, response } envelope instead of throwing:

typescript
import { executeSql } from "@scalix-world/sdk";
 
const { data, error, response } = await executeSql({
  body: { query: "SELECT * FROM users" },
});
 
if (error) {
  if (error.code === "AUTH_FAILED") {
    // Refresh token or re-authenticate
  } else if (error.code === "RATE_LIMITED") {
    const resetAt = Number(response.headers.get("x-ratelimit-reset"));
    await sleep(resetAt * 1000 - Date.now());
  } else {
    console.error(`Error ${error.code}: ${error.error}`);
  }
}