Skip to main content

Rate limits

Rate limits are enforced per API key on a sliding 60-second window, bucketed by operation type: reads, writes, and outbound calls each have their own bucket.

The baseline is 60 reads, 20 writes, and 5 outbound calls per key per minute. Limits vary by plan; higher plans get more.

Discover your limits at runtime

Do not hardcode limits. Every authenticated response includes headers that tell you your current allowance:

HeaderMeaning
X-RateLimit-LimitRequests allowed in the current window.
X-RateLimit-RemainingRequests remaining before the limit is hit.
X-RateLimit-ResetUnix timestamp (seconds) when the window resets.
Retry-AfterSent on 429 only. Seconds to wait before retrying.

Read X-RateLimit-Limit and X-RateLimit-Remaining on each response to discover your allowance at runtime.

Handling 429 responses

When the limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header. Back off for the indicated number of seconds and retry. Use exponential backoff with jitter for retries beyond the first.

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1713590460
Retry-After: 12
{
"error": "Rate limit exceeded",
"limit": 60,
"window_seconds": 60,
"retry_after_seconds": 12
}

Example backoff loop:

async function requestWithBackoff(url, options, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const res = await fetch(url, options)
if (res.status !== 429) return res

const retryAfter = Number(res.headers.get('Retry-After')) || 1
// Retry-After first, then exponential backoff with jitter, capped at 30s
const waitSeconds = Math.min(
Math.max(retryAfter, 2 ** attempt + Math.random()),
30
)
await new Promise((r) => setTimeout(r, waitSeconds * 1000))
}
throw new Error('Rate limited after max retry attempts')
}

Need higher limits?

Contact support@autorev.ai with your use case. Enterprise customers can request custom limits or dedicated throughput.