Rate Limits
Rate limits protect the API infrastructure and ensure fair usage across all clients. Limits vary by environment and subscription tier.
Limits by Environment
Sandbox
Production
Rate Limit Headers
Every API response includes rate limit headers so you can track your remaining quota in real time.
X-RateLimit-Limit60Maximum requests allowed in the current window
X-RateLimit-Remaining42Requests remaining in the current window
X-RateLimit-Reset1740268800UTC epoch seconds when the window resets
Retry-After12Seconds to wait before retrying (only on 429 responses)
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1740268800
{
"success": true,
"data": { ... }
}Handling 429 Too Many Requests
When you exceed the rate limit, the API returns a 429 status with a Retry-After header indicating how many seconds to wait.
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1740268812
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 12 seconds.",
"retryAfter": 12
}
}Retry Strategies
Implement exponential backoff with jitter for resilient integrations.
async function withRetry(fn, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (err.status !== 429 || attempt === maxRetries) throw err;
const retryAfter = err.headers?.["retry-after"] || 1;
const jitter = Math.random() * 1000;
const delay = retryAfter * 1000 + jitter;
console.log(`Rate limited. Retrying in ${delay}ms...`);
await new Promise(r => setTimeout(r, delay));
}
}
}import time, random
def with_retry(fn, max_retries=3):
for attempt in range(max_retries + 1):
try:
return fn()
except ApiError as e:
if e.status != 429 or attempt == max_retries:
raise
retry_after = int(e.headers.get("retry-after", 1))
jitter = random.uniform(0, 1)
delay = retry_after + jitter
print(f"Rate limited. Retrying in {delay:.1f}s...")
time.sleep(delay)Respect the Retry-After header
Always wait at least the number of seconds specified in the Retry-After header before retrying.
Add jitter to prevent thundering herd
Add a random delay (0–1s) to your retry timing to prevent multiple clients from retrying simultaneously.
Use exponential backoff for transient errors
For 500/503 errors, double the wait time on each retry: 1s → 2s → 4s → 8s (with jitter).
Set a maximum retry count
Cap retries at 3–5 attempts. If the request still fails, log the error and alert your team.
Need Higher Limits?
Enterprise customers can request custom rate limits. Contact support@compliancegrid.ai with your use case and expected request volume.
HTTP status codes and error format
API keys and OAuth 2.0