Error Handling

Understand API errors and how to handle them gracefully

Error Response Format

All API errors follow a consistent JSON structure:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {
      "field": "Additional context about the error"
    }
  }
}

HTTP Status Codes

400

Bad Request

The request was malformed or missing required parameters.

Example

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "title": ["The title field is required."],
      "payment_per_submission": ["Must be at least 0.01"]
    }
  }
}

How to Fix

Check all required parameters are included and properly formatted. Review the endpoint documentation for parameter requirements.

401

Unauthorized

Invalid or missing API credentials.

Example

{
  "success": false,
  "error": {
    "code": "INVALID_CREDENTIALS",
    "message": "Invalid API key or secret"
  }
}

How to Fix

Verify your X-API-Key and X-API-Secret headers are correct. Check for typos and ensure you're using active (not expired) credentials.

403

Forbidden

You don't have permission to access this resource or your quota is exceeded.

Example

{
  "success": false,
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Monthly budget limit exceeded",
    "details": {
      "limit": 5000.00,
      "used": 5150.00
    }
  }
}

How to Fix

Check your account limits and upgrade your tier if needed. For permission errors, ensure your account type allows this operation.

404

Not Found

The requested resource doesn't exist.

Example

{
  "success": false,
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "Content request with ID 999 not found"
  }
}

How to Fix

Verify the resource ID exists and belongs to your account. Check for typos in the endpoint URL.

429

Too Many Requests

You've exceeded your rate limit. Wait and retry after the specified time.

Example

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Retry after 45 seconds.",
    "retry_after": 45
  }
}

How to Fix

Wait for the retry_after seconds before making another request. Implement exponential backoff. Consider upgrading your tier.

500

Internal Server Error

An unexpected error occurred on our servers.

Example

{
  "success": false,
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "An unexpected error occurred. Please try again."
  }
}

How to Fix

Retry the request after a short delay. If the error persists, contact support@opttab.com with the request details.

Common Error Codes

Code Description HTTP Status
INVALID_CREDENTIALS Invalid API key or secret 401
VALIDATION_ERROR Request validation failed 400
RESOURCE_NOT_FOUND Requested resource doesn't exist 404
RATE_LIMIT_EXCEEDED Too many requests 429
INSUFFICIENT_BUDGET Not enough budget for operation 403
QUOTA_EXCEEDED Monthly quota limit exceeded 403
PERMISSION_DENIED Account type doesn't allow this action 403
INTERNAL_ERROR Unexpected server error 500

Handling Errors in Code

Python Example

import requests

def handle_opttab_request(url, headers, data=None):
    try:
        if data:
            response = requests.post(url, json=data, headers=headers)
        else:
            response = requests.get(url, headers=headers)
        
        # Check for errors
        if not response.ok:
            error_data = response.json()
            error_code = error_data.get('error', {}).get('code')
            error_message = error_data.get('error', {}).get('message')
            
            if response.status_code == 429:
                retry_after = error_data.get('error', {}).get('retry_after', 60)
                print(f"Rate limited. Retry after {retry_after}s")
                time.sleep(retry_after)
                return handle_opttab_request(url, headers, data)  # Retry
            
            elif response.status_code == 401:
                raise Exception(f"Authentication failed: {error_message}")
            
            elif response.status_code == 400:
                details = error_data.get('error', {}).get('details', {})
                raise Exception(f"Validation error: {details}")
            
            else:
                raise Exception(f"API error ({error_code}): {error_message}")
        
        return response.json()
    
    except requests.exceptions.RequestException as e:
        print(f"Network error: {e}")
        raise

# Usage
try:
    result = handle_opttab_request(
        "https://opttab.com/api/v1/ai/budget-status",
        {"X-API-Key": "...", "X-API-Secret": "..."}
    )
    print(result)
except Exception as e:
    print(f"Error: {e}")

JavaScript Example

async function makeOpttabRequest(url, options = {}) {
  try {
    const response = await fetch(url, {
      ...options,
      headers: {
        'X-API-Key': process.env.OPTTAB_API_KEY,
        'X-API-Secret': process.env.OPTTAB_API_SECRET,
        'Content-Type': 'application/json',
        ...options.headers
      }
    });

    const data = await response.json();

    if (!response.ok) {
      const error = data.error || {};
      
      switch (response.status) {
        case 429:
          const retryAfter = error.retry_after || 60;
          console.log(`Rate limited. Retry after ${retryAfter}s`);
          await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
          return makeOpttabRequest(url, options); // Retry
        
        case 401:
          throw new Error(`Authentication failed: ${error.message}`);
        
        case 400:
          throw new Error(`Validation error: ${JSON.stringify(error.details)}`);
        
        default:
          throw new Error(`API error (${error.code}): ${error.message}`);
      }
    }

    return data;
  } catch (error) {
    console.error('API request failed:', error);
    throw error;
  }
}

// Usage
try {
  const result = await makeOpttabRequest('https://opttab.com/api/v1/ai/budget-status');
  console.log(result);
} catch (error) {
  console.error(error.message);
}

Best Practices

Always Check Response Status

Don't assume requests succeed. Always check the success field and handle errors appropriately.

Log Error Details

Log error codes and details for debugging. Include request IDs if provided in error responses.

Implement Retry Logic

For 429 and 500 errors, implement exponential backoff retry logic with maximum retry limits.

Handle Network Errors

Catch network timeouts and connection errors separately from API errors.