Skip to main content

Rate Limits

ARQERA enforces two layers of rate limiting: request-level (per-endpoint throttling) and usage-level (monthly allowances tied to your subscription tier).


Request Rate Limits

Request rate limits protect API stability. They apply to all tiers equally.

CategoryLimitWindowEndpoints
Global1,000 requests1 hourAll endpoints
Auth10 requests1 minute/auth/login, /auth/register, /auth/password, /auth/oauth, /auth/sso
AI / Ara100 requests1 minute/ai/*, /ara/*, /composer/*
Search60 requests1 minuteAny endpoint containing /search
Export30 requests1 minuteAny endpoint containing /export
Billing30 requests1 minute/billing/*

Exempt Endpoints

These endpoints are excluded from category-specific limits (global limit still applies):

  • /auth/me — called on every page load
  • /auth/csrf — CSRF token retrieval

Rate Limit Response Headers

Every API response includes rate limit headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997
X-RateLimit-Reset: 1708531200
X-RateLimit-Category: global
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining before the limit is reached
X-RateLimit-ResetUnix timestamp when the rate limit window resets
X-RateLimit-CategoryWhich rate limit category was applied (e.g., global, auth, ai)

Usage Limit Headers (on 429 responses)

When a usage limit is exceeded, the 429 response includes additional headers:

X-Usage-Limit: 1000
X-Usage-Current: 1001
X-Usage-Type: api_calls
Retry-After: 3600
HeaderDescription
X-Usage-LimitYour monthly allowance for this resource (or unlimited)
X-Usage-CurrentYour current usage count
X-Usage-TypeResource type: tokens, api_calls, storage, users
Retry-AfterSeconds until the rate limit window resets

Handling Rate Limits (429 Responses)

When you exceed a rate limit, the API returns HTTP 429 with a JSON body:

{
"detail": "API call limit exceeded. Please upgrade your plan or wait until next billing period."
}
  1. Read the Retry-After header and wait that many seconds before retrying
  2. Implement exponential backoff for repeated 429s
  3. Monitor X-RateLimit-Remaining proactively to avoid hitting limits
  4. Cache responses where possible to reduce API calls
  5. Use webhooks instead of polling for real-time updates

Example: Retry with Backoff

Python

import time
import requests

def call_with_retry(url, headers, payload, max_retries=3):
for attempt in range(max_retries):
response = requests.post(url, headers=headers, json=payload)

if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
wait = min(retry_after, 2 ** attempt * 10)
print(f"Rate limited. Waiting {wait}s before retry...")
time.sleep(wait)
continue

return response

raise Exception("Max retries exceeded")

TypeScript

async function callWithRetry(url: string, options: RequestInit, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);

if (response.status === 429) {
const retryAfter = parseInt(response.headers.get("Retry-After") || "60");
const wait = Math.min(retryAfter, Math.pow(2, attempt) * 10) * 1000;
console.log(`Rate limited. Waiting ${wait}ms...`);
await new Promise(resolve => setTimeout(resolve, wait));
continue;
}

return response;
}

throw new Error("Max retries exceeded");
}

API Key Rotation

All API keys expire after 90 days by default (3-month rotation cycle). You receive a notification 24 hours before deactivation. Enterprise customers can request non-expiring keys.