Aira

Error Handling

How to handle errors from the Aira API — error response format, common error codes, and SDK helpers.

Error Response Format

All Aira API errors follow a consistent JSON structure:

{
  "error": {
    "code": "AUTHENTICATION_FAILED",
    "message": "Invalid or expired API key.",
    "details": {}
  },
  "request_id": "req_abc123"
}
  • error.code — A machine-readable error code (see table below).
  • error.message — A human-readable description of what went wrong.
  • error.details — An optional object with additional context (e.g., which field failed validation).
  • request_id — A unique identifier for the request. Include this when contacting support.

Common Error Codes

CodeHTTP StatusDescription
AUTHENTICATION_FAILED401API key is missing, invalid, or expired.
FORBIDDEN403The authenticated key does not have permission for this action.
NOT_FOUND404The requested resource does not exist.
DUPLICATE_REQUEST409A request with the same idempotency key has already been processed.
RATE_LIMITED429You have exceeded the allowed request rate. See Rate Limits.
ENDPOINT_NOT_WHITELISTED403The target endpoint is not in your approved allowlist.
MODEL_UNAVAILABLE503The requested model is temporarily unavailable. Retry after a short delay.
VALIDATION_ERROR422The request body failed validation. Check error.details for field-level information.
INTERNAL_ERROR500An unexpected server error occurred. Retry with exponential backoff.

Example Error Response

A validation error with field-level details:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request body failed validation.",
    "details": {
      "fields": {
        "models": "must contain at least 2 model identifiers",
        "prompt": "must not be empty"
      }
    }
  },
  "request_id": "req_7xk29m"
}

Handling Errors in the Python SDK

The Python SDK raises typed exceptions that you can catch directly:

import aira

client = aira.Client(api_key="your-api-key")

try:
    result = client.actions.create(prompt="Evaluate this claim", models=["gpt-5.2", "claude-sonnet"])
except aira.AuthenticationError as e:
    # 401 — check your API key
    print(f"Auth failed: {e.message}")
except aira.RateLimitError as e:
    # 429 — back off and retry
    retry_after = e.retry_after  # seconds
    print(f"Rate limited. Retry after {retry_after}s")
except aira.ValidationError as e:
    # 422 — inspect field errors
    print(f"Validation: {e.message}", e.details)
except aira.APIError as e:
    # catch-all for any other API error
    print(f"[{e.code}] {e.message} (request_id={e.request_id})")

Handling Errors in the TypeScript SDK

The TypeScript SDK throws typed error classes:

import Aira, { AuthenticationError, RateLimitError, ValidationError, APIError } from "aira-sdk";

const client = new Aira({ apiKey: "your-api-key" });

try {
  const result = await client.actions.create({
    prompt: "Evaluate this claim",
    models: ["gpt-5.2", "claude-sonnet"],
  });
} catch (err) {
  if (err instanceof AuthenticationError) {
    // 401
    console.error("Auth failed:", err.message);
  } else if (err instanceof RateLimitError) {
    // 429
    console.error(`Rate limited. Retry after ${err.retryAfter}s`);
  } else if (err instanceof ValidationError) {
    // 422
    console.error("Validation:", err.message, err.details);
  } else if (err instanceof APIError) {
    // catch-all
    console.error(`[${err.code}] ${err.message} (request_id=${err.requestId})`);
  }
}

Best Practices

  • Always include the request_id in bug reports or support tickets.
  • Retry on 429 and 503 with exponential backoff. The Retry-After header (or SDK helper) tells you how long to wait.
  • Do not retry on 401 or 403 — these indicate a configuration problem, not a transient failure.
  • Validate inputs client-side before sending requests to avoid unnecessary 422 errors.

On this page