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.