API Rate Limits
Celavii API rate limits by tier — Starter 30 req/min, Pro 60 req/min, Enterprise 120 req/min. Daily operation caps, response headers, and retry logic.
Understand API rate limits and how to handle them in your integrations.
Limits by Plan
| Tier | Req/min | Req/hr | Req/day |
|---|---|---|---|
| Starter | 30 | 500 | 5,000 |
| Pro | 60 | 1,500 | 15,000 |
| Enterprise | 120 | 5,000 | 50,000 |
Pre-auth burst limit: 10 req/sec, 100 req/min per key (Redis-based, protects before the tier check).
Daily Operation Limits
| Tier | Scrape Profiles/Day | Enhance Profiles/Day |
|---|---|---|
| Starter | 50,000 | 5,000 |
| Pro | 200,000 | 20,000 |
| Enterprise | Unlimited | Unlimited |
Response Headers
Every API response includes headers with your current rate limit status:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1699459200
X-RateLimit-Daily-Limit: 15000
X-RateLimit-Daily-Remaining: 14150
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Max requests per minute |
X-RateLimit-Remaining | Requests remaining this minute |
X-RateLimit-Reset | Unix timestamp when limit resets |
X-RateLimit-Daily-Limit | Max requests per day |
X-RateLimit-Daily-Remaining | Requests remaining today |
Handling Rate Limits
When you exceed rate limits, the API returns a 429 status code:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"retry_after": 45
}
}
The Retry-After header tells you the seconds to wait.
Best Practices
- Implement exponential backoff — When rate limited, wait progressively longer between retries (1s, 2s, 4s, 8s...)
- Monitor rate limit headers — Check remaining requests before making calls to avoid hitting limits
- Batch requests when possible — Use bulk endpoints to fetch multiple items in a single request
- Cache responses — Store frequently accessed data locally to reduce API calls
Example: Retry Logic
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options)
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60
await sleep(retryAfter * 1000)
continue
}
return response
}
throw new Error('Max retries exceeded')
}