Guides
Get Started
Error Handling

Error Handling

All Orsa API errors follow a consistent format with machine-readable error codes and human-readable messages.

Error Response Format

{
  "success": false,
  "error": {
    "code": "INVALID_DOMAIN",
    "message": "The provided domain could not be resolved",
    "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Every error response includes:

FieldDescription
successAlways false for errors
error.codeMachine-readable error code (use this for programmatic handling)
error.messageHuman-readable description
error.request_idUnique ID for debugging — include this in support requests

Error Codes

Client Errors (4xx)

CodeHTTP StatusDescription
INPUT_VALIDATION_ERROR400Invalid request parameters or body
UNAUTHORIZED401Missing or invalid API key
FORBIDDEN403Insufficient permissions (e.g., free plan using paid features)
NOT_FOUND404Resource not found (brand, crawl job, etc.)
USAGE_EXCEEDED402Insufficient credits for the request
RATE_LIMITED429Rate limit exceeded

Server Errors (5xx)

CodeHTTP StatusDescription
INTERNAL_ERROR500Unexpected server error
WEBSITE_ACCESS_ERROR502Failed to access or extract data from the target website

Handling Errors

TypeScript

import { Orsa, OrsaError } from 'orsa';
 
const client = new Orsa({ apiKey: process.env.ORSA_API_KEY });
 
try {
  const brand = await client.brand.retrieve({ domain: 'invalid..domain' });
} catch (error) {
  if (error instanceof OrsaError) {
    switch (error.code) {
      case 'INPUT_VALIDATION_ERROR':
        console.error('Bad input:', error.message);
        break;
      case 'NOT_FOUND':
        console.error('Brand not found');
        break;
      case 'RATE_LIMITED':
        const retryAfter = error.headers?.['retry-after'];
        console.error(`Rate limited. Retry in ${retryAfter}s`);
        break;
      case 'USAGE_EXCEEDED':
        console.error('Out of credits — upgrade your plan');
        break;
      default:
        console.error(`API error [${error.code}]: ${error.message}`);
    }
 
    // Always available for debugging
    console.error('Request ID:', error.requestId);
  }
}

Python

from orsa import Orsa, OrsaError
 
client = Orsa(api_key=os.environ["ORSA_API_KEY"])
 
try:
    brand = client.brand.retrieve(domain="invalid..domain")
except OrsaError as e:
    if e.code == "INPUT_VALIDATION_ERROR":
        print(f"Bad input: {e.message}")
    elif e.code == "NOT_FOUND":
        print("Brand not found")
    elif e.code == "RATE_LIMITED":
        print(f"Rate limited. Retry in {e.retry_after}s")
    elif e.code == "USAGE_EXCEEDED":
        print("Out of credits")
    else:
        print(f"API error [{e.code}]: {e.message}")
 
    print(f"Request ID: {e.request_id}")

Retry Strategies

Which Errors to Retry

Error CodeRetry?Strategy
INPUT_VALIDATION_ERROR❌ NoFix the request parameters
UNAUTHORIZED❌ NoCheck your API key
FORBIDDEN❌ NoUpgrade your plan
NOT_FOUND❌ NoThe resource doesn't exist
USAGE_EXCEEDED❌ NoAdd credits or upgrade
RATE_LIMITED✅ YesWait for Retry-After, then retry
INTERNAL_ERROR✅ YesExponential backoff (max 3 retries)
WEBSITE_ACCESS_ERROR⚠️ MaybeSite may be down — retry once after 30s

Exponential Backoff

const delay = baseDelay * Math.pow(2, attempt) + Math.random() * 1000;

Add jitter (random component) to prevent thundering herd when multiple clients retry simultaneously.

Debugging

  1. Check the request_id — include it when contacting support.
  2. Check rate limit headers — you might be hitting limits without realizing it.
  3. Validate inputs client-side before making API calls to avoid unnecessary 400 errors.
  4. Log error codes, not just messages — codes are stable; messages may change.