Skip to content

Errors & Rate Limits

Consistent error handling, rate limiting, and pagination across all API endpoints.


Error Response Format

All errors return a JSON envelope with success: false:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The prompt field is required",
    "details": {
      "prompt": ["The prompt field is required."]
    }
  }
}

Error Codes

Code HTTP Status Description Common Cause
UNAUTHORIZED 401 Invalid or missing credentials Bad API key, expired OAuth token
FORBIDDEN 403 Valid credentials, insufficient permissions Wrong scope, resource owned by another user
NOT_FOUND 404 Resource does not exist Wrong ID, deleted resource
VALIDATION_ERROR 422 Invalid request parameters Missing required field, wrong type
RATE_LIMITED 429 Too many requests Exceeded plan limits
PRECONDITION_FAILED 412 Missing required precondition Missing conver_id, empty prompt
NO_CREDITS 419 Insufficient credit balance Credit quota exhausted
SERVER_ERROR 500 Internal server error Upstream AI provider failure

Rate Limiting

Limits by Plan

Plan Requests/Minute Requests/Day
Starter 60 1,000
Business 300 10,000
Enterprise 1,000 100,000

The Partner API has a dedicated throttle:partner rate limiter applied to all /api/v1/partners/* routes.

Rate Limit Headers

Every response includes rate limit headers:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 297
X-RateLimit-Reset: 1709000000
Header Description
X-RateLimit-Limit Maximum requests per window
X-RateLimit-Remaining Requests remaining in current window
X-RateLimit-Reset Unix timestamp when the window resets

When Rate Limited

You receive a 429 Too Many Requests response:

{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests. Retry after 45 seconds.",
    "retry_after": 45
  }
}

Retry Strategy

Use exponential backoff with jitter:

import time
import random
import requests

def api_call_with_retry(url, headers, max_retries=4):
    for attempt in range(max_retries):
        resp = requests.get(url, headers=headers)
        if resp.status_code != 429:
            return resp

        wait = (2 ** attempt) + random.uniform(0, 1)
        time.sleep(wait)

    return resp  # Return last response after all retries
async function apiCallWithRetry(url, headers, maxRetries = 4) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const resp = await fetch(url, { headers });
    if (resp.status !== 429) return resp;

    const wait = 2 ** attempt + Math.random();
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
}

Pagination

List endpoints return paginated results using cursor-based or offset pagination:

Request Parameters

Parameter Type Default Description
page integer 1 Page number
per_page integer 20 Items per page (max: 100)

Response Metadata

{
  "success": true,
  "data": [ ... ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 85,
    "current_page": 1,
    "last_page": 5,
    "from": 1,
    "to": 20
  }
}

Iterating Through Pages

import requests

def get_all_items(base_url, headers):
    items = []
    page = 1
    while True:
        resp = requests.get(
            base_url, headers=headers, params={"page": page, "per_page": 100}
        )
        data = resp.json()
        items.extend(data["data"])

        if page >= data["meta"]["last_page"]:
            break
        page += 1

    return items

Filtering and Sorting

List endpoints support query-parameter-based filtering. Common patterns:

Pattern Example Description
Exact match ?status=active Filter by exact value
Date range ?created_after=2026-01-01 Filter by date
Sort ?sort=created_at&direction=desc Sort results
Search ?search=cloud+security Full-text search

Specific filter options are documented on each endpoint page.


Credit Costs

AI-powered endpoints consume credits from your account balance:

Operation Credits
AI Chat message Varies by model and response length
AI Writer generation Varies by model and response length
AI Image generation Varies by model and resolution
Knowledge Base query 2
Platform Knowledge query 2
Search question discovery 3
Dry-run session message Varies by model

When credits are exhausted, AI endpoints return 419:

{
  "success": false,
  "error": {
    "code": "NO_CREDITS",
    "message": "Insufficient credit balance. Please upgrade your plan."
  }
}

Check your current balance at GET /api/v1/app/usage-data.