Rate Limiting
Overview
The Celper AI API enforces per-company rate limits using a sliding window algorithm. Each window spans 60 seconds and is tracked independently per endpoint category. When a request arrives, the API counts how many requests your company has made in the current window and either allows or rejects the request accordingly.
Rate limits protect the platform from traffic spikes and ensure fair access for all API consumers.
Rate Limit Categories
Every endpoint belongs to one of the following categories. A single request may count toward both the Global limit and a category-specific limit.
| Category | Limit | Endpoints |
|---|---|---|
| Global | 60 req/60s | All endpoints |
| Reads | 40 req/60s | GET endpoints |
| Writes | 20 req/60s | POST/PATCH/DELETE candidates |
| Analysis | 15 req/60s | CV analysis, interview analysis |
| Storage | 10 req/60s | CV document download |
| Bulk Import | 3 req/60s | POST /v1/candidates/bulk |
| Actions | 30 req/60s | Invite, select, reject |
| Webhooks | 20 req/60s | Webhook management |
Response Headers
Every API response includes rate limit headers so you can track your usage proactively:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1705312800| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum number of requests allowed in the current window. |
X-RateLimit-Remaining | Number of requests remaining before the limit is reached. |
X-RateLimit-Reset | Unix timestamp (seconds) when the current window resets. |
Handling 429 Responses
When you exceed a rate limit, the API returns HTTP 429 Too Many Requests with a Retry-After header indicating how many seconds to wait before retrying.
The Retry-After response header contains the number of seconds until the window resets:
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705312845Retry Strategy
Use exponential backoff to avoid hammering the API after a 429. Start with the Retry-After value and increase the delay on each subsequent retry.
#!/bin/bash
MAX_RETRIES=5
RETRY=0
DELAY=1
while [ $RETRY -lt $MAX_RETRIES ]; do
RESPONSE=$(curl -s -w "
%{http_code}" https://api.celper.ai/v1/job-positions -H "X-API-Key: celp_your_api_key_here")
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" -ne 429 ]; then
echo "$BODY"
exit 0
fi
RETRY_AFTER=$(echo "$RESPONSE" | grep -i "Retry-After" | awk '{print $2}')
DELAY=${RETRY_AFTER:-$DELAY}
echo "Rate limited. Retrying in ${DELAY}s (attempt $((RETRY + 1))/$MAX_RETRIES)"
sleep "$DELAY"
RETRY=$((RETRY + 1))
DELAY=$((DELAY * 2))
done
echo "Max retries exceeded"
exit 1