Skip to content

Error Handling

Understanding error responses helps you debug issues and build robust integrations.

HTTP Status Codes

Success Codes (2xx)

CodeMeaningWhen You Get It
200OKRequest succeeded
201CreatedResource was created
202AcceptedRequest accepted for processing

Client Errors (4xx)

CodeMeaningCommon CauseAction
400Bad RequestInvalid parametersFix request body/params
401UnauthorizedMissing/invalid authCheck API key
403ForbiddenInsufficient permissionsUse correct API key scope
404Not FoundResource doesn't existVerify resource ID
429Rate LimitedToo many requestsWait and retry

Server Errors (5xx)

CodeMeaningAction
500Internal Server ErrorRetry with backoff
503Service UnavailableCheck status page, wait

Error Response Format

All errors follow a consistent format:

json
{
  "error": {
    "code": "invalid_request",
    "message": "Missing required field: document_url",
    "details": {
      "field": "document_url",
      "type": "required"
    },
    "request_id": "req_abc123xyz"
  }
}
FieldDescription
codeMachine-readable error code
messageHuman-readable error message
detailsAdditional error context
request_idUnique ID for support

Common Error Codes

Authentication Errors

invalid_api_key

json
{
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid or expired API key"
  }
}

Solution: Generate a new API key in Settings

missing_authorization

json
{
  "error": {
    "code": "missing_authorization",
    "message": "Authorization header required"
  }
}

Solution: Add Authorization: Bearer YOUR_API_KEY header

Permission Errors

insufficient_permissions

json
{
  "error": {
    "code": "insufficient_permissions",
    "message": "API key doesn't have permission: write:documents"
  }
}

Solution: Use a key with the required scope or upgrade key permissions

Request Errors

invalid_request

json
{
  "error": {
    "code": "invalid_request",
    "message": "Missing required field: document_url",
    "details": {
      "field": "document_url",
      "type": "required"
    }
  }
}

Solution: Add the missing required field

invalid_parameter

json
{
  "error": {
    "code": "invalid_parameter",
    "message": "Invalid value for parameter 'language': 'spanish' (expected 'en', 'es', 'fr')",
    "details": {
      "parameter": "language",
      "value": "spanish",
      "valid_values": ["en", "es", "fr"]
    }
  }
}

Solution: Use a valid value from the list

invalid_json

json
{
  "error": {
    "code": "invalid_json",
    "message": "Request body is not valid JSON"
  }
}

Solution: Ensure request body is valid JSON

Resource Errors

resource_not_found

json
{
  "error": {
    "code": "resource_not_found",
    "message": "Document 'doc_xyz789' not found"
  }
}

Solution: Verify the resource ID is correct

resource_already_exists

json
{
  "error": {
    "code": "resource_already_exists",
    "message": "A document with this ID already exists"
  }
}

Solution: Use a different ID or update existing resource

Rate Limiting

rate_limit_exceeded

json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded: 60 requests per minute"
  }
}

Solution: Wait before retrying (check X-RateLimit-Reset header)

Server Errors

internal_server_error

json
{
  "error": {
    "code": "internal_server_error",
    "message": "An internal server error occurred",
    "request_id": "req_abc123xyz"
  }
}

Solution: Retry with backoff, include request_id in support ticket

Error Handling Patterns

Basic Error Handling (JavaScript)

javascript
const analyzeDocument = async (documentUrl) => {
  try {
    const response = await fetch(
      'https://api.solatis.team/v2/documents/analyze',
      {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ document_url: documentUrl })
      }
    );

    // Handle HTTP errors
    if (!response.ok) {
      const error = await response.json();

      if (response.status === 401) {
        console.error('Authentication failed:', error.error.message);
        // Handle auth error
      } else if (response.status === 429) {
        console.error('Rate limited:', error.error.message);
        // Implement retry
      } else if (response.status >= 500) {
        console.error('Server error:', error.error.message);
        // Retry with backoff
      } else {
        console.error('Request error:', error.error.message);
      }

      throw new Error(error.error.message);
    }

    return await response.json();

  } catch (error) {
    console.error('Request failed:', error.message);
    throw error;
  }
};

Error Handling with Retry (Python)

python
import requests
import time

def make_api_request(url, **kwargs):
    max_retries = 3
    base_delay = 1

    for attempt in range(max_retries):
        try:
            response = requests.post(url, **kwargs)
            response.raise_for_status()
            return response.json()

        except requests.exceptions.HTTPError as e:
            if e.response.status_code == 401:
                print('Authentication failed:', e.response.json())
                raise  # Don't retry auth errors

            elif e.response.status_code == 429:
                # Rate limited - wait and retry
                retry_after = int(e.response.headers.get('X-RateLimit-Reset', 60))
                wait_time = (retry_after * 1000) - (time.time() * 1000)
                print(f'Rate limited. Waiting {wait_time}ms...')
                time.sleep(wait_time / 1000)
                continue

            elif e.response.status_code >= 500:
                # Server error - retry with backoff
                if attempt < max_retries - 1:
                    delay = base_delay * (2 ** attempt)
                    print(f'Server error. Retrying in {delay}s...')
                    time.sleep(delay)
                    continue

            raise

        except requests.exceptions.RequestException as e:
            print('Request failed:', str(e))
            raise

Custom Error Class (JavaScript)

javascript
class SolatisError extends Error {
  constructor(code, message, details = null, requestId = null) {
    super(message);
    this.name = 'SolatisError';
    this.code = code;
    this.details = details;
    this.requestId = requestId;
  }

  isRetryable() {
    return ['rate_limit_exceeded', 'internal_server_error'].includes(this.code);
  }

  isAuthError() {
    return ['invalid_api_key', 'missing_authorization', 'insufficient_permissions']
      .includes(this.code);
  }
}

const handleApiError = (response, data) => {
  const { error } = data;
  throw new SolatisError(
    error.code,
    error.message,
    error.details,
    error.request_id
  );
};

// Usage
try {
  // Make request
} catch (error) {
  if (error instanceof SolatisError) {
    if (error.isRetryable()) {
      console.log('Will retry:', error.message);
    } else if (error.isAuthError()) {
      console.log('Auth error:', error.message);
      // Redirect to re-authenticate
    } else {
      console.log('Other error:', error.message);
    }

    // Log for support
    if (error.requestId) {
      console.log('Support reference:', error.requestId);
    }
  }
}

Debugging Tips

1. Use Request ID for Support

Every error includes a request_id. Include this when contacting support:

javascript
try {
  await makeApiRequest();
} catch (error) {
  const { request_id } = error;
  console.error(`Error (ref: ${request_id}): ${error.message}`);
  // Email support with request_id
}

2. Log Full Response

When debugging, log the complete error response:

javascript
const response = await fetch(url, options);

if (!response.ok) {
  const data = await response.json();
  console.error({
    status: response.status,
    headers: Object.fromEntries(response.headers.entries()),
    body: data
  });
}

3. Check Headers

Rate limiting and other info are in headers:

javascript
const response = await fetch(url, options);

console.log({
  rateLimit: response.headers.get('X-RateLimit-Limit'),
  remaining: response.headers.get('X-RateLimit-Remaining'),
  reset: response.headers.get('X-RateLimit-Reset'),
  retryAfter: response.headers.get('Retry-After')
});

4. Validate Before Sending

Catch errors early by validating requests:

javascript
const validateAnalyzeRequest = (params) => {
  if (!params.document_url) throw new Error('document_url required');
  if (!params.analysis_type) throw new Error('analysis_type required');

  const validTypes = ['contract_review', 'financial_analysis', 'legal_review'];
  if (!validTypes.includes(params.analysis_type)) {
    throw new Error(`analysis_type must be one of: ${validTypes.join(', ')}`);
  }

  return true;
};

// Validate before API call
validateAnalyzeRequest(params);
const result = await analyzeDocument(params);

Common Error Scenarios

Scenario 1: Invalid API Key

Error:

json
{
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid or expired API key"
  }
}

Solution:

  1. Go to Settings → Developer → API Keys
  2. Generate a new key
  3. Update your application with new key
  4. Delete the old key (if compromised)

Scenario 2: Rate Limited

Error:

json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded: 60 requests per minute"
  }
}

Solution:

  1. Check X-RateLimit-Reset header for when limit resets
  2. Wait before retrying
  3. Implement exponential backoff
  4. Consider upgrading plan for higher limits

Scenario 3: Server Temporarily Down

Error:

json
{
  "error": {
    "code": "internal_server_error",
    "message": "An internal server error occurred",
    "request_id": "req_abc123"
  }
}

Solution:

  1. Check status.solatis.team
  2. Retry with exponential backoff
  3. If persistent, email support with request_id

Scenario 4: Missing Required Field

Error:

json
{
  "error": {
    "code": "invalid_request",
    "message": "Missing required field: document_url",
    "details": {
      "field": "document_url",
      "type": "required"
    }
  }
}

Solution:

  1. Add the missing field to your request
  2. Check API documentation for required fields
  3. Validate locally before sending

Getting Support

When reporting issues to support:

  1. Include request ID from error response
  2. Provide exact error code (e.g., invalid_request)
  3. Show request and response (redact sensitive data)
  4. Describe steps to reproduce
  5. Mention your plan type (Individual, Team, Enterprise)

Email: developers@solatis.team

Monitoring Best Practices

Track Error Rates

javascript
const errorRates = new Map();

const trackError = (code) => {
  const count = (errorRates.get(code) || 0) + 1;
  errorRates.set(code, count);

  // Alert if error rate too high
  if (count > 100) {
    sendAlert(`High error rate: ${code} (${count} errors)`);
  }
};

Log Errors Consistently

javascript
const logError = (error, context) => {
  console.error({
    timestamp: new Date().toISOString(),
    code: error.code,
    message: error.message,
    requestId: error.requestId,
    context,
    environment: process.env.NODE_ENV
  });
};

Set Up Alerts

Monitor for specific errors:

javascript
const monitorErrors = async () => {
  const alertThresholds = {
    'rate_limit_exceeded': 10,    // Alert if > 10 rate limit errors
    'invalid_api_key': 1,         // Alert on any auth errors
    'internal_server_error': 5    // Alert if > 5 server errors
  };

  // Check error logs periodically
  const recentErrors = await getErrorsFromLastHour();

  for (const [code, threshold] of Object.entries(alertThresholds)) {
    const count = recentErrors.filter(e => e.code === code).length;
    if (count > threshold) {
      sendAlert(`High error count for ${code}: ${count}`);
    }
  }
};

Next Steps

Released under the MIT License.