Global rate limit
The Contox API enforces a global rate limit of 200 requests per minute per IP address. This limit applies across all endpoints and authentication methods.
Rate limit headers
Every API response includes headers to help you track your usage:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Example response headers:
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 187
X-RateLimit-Reset: 1705312260
Handling 429 responses
When you exceed the rate limit, the API returns a 429 Too Many Requests response:
json
{
"error": "Rate limit exceeded. Please retry after 42 seconds."
}
The response includes a Retry-After header indicating how many seconds to wait:
Retry-After: 42
Recommended strategies
Exponential backoff
Implement exponential backoff with jitter for reliable retry behavior:
javascript
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
const retryAfter = parseInt(response.headers.get('Retry-After') || '60', 10);
const jitter = Math.random() * 1000;
const delay = retryAfter * 1000 + jitter;
await new Promise(resolve => setTimeout(resolve, delay));
}
throw new Error('Max retries exceeded');
}
Request batching
Where possible, batch operations to reduce the total number of requests:
- Use the
POST /api/contexts/populateendpoint to create multiple contexts in a single request - Use the V2 ingest endpoint to send multiple events in fewer calls
Monitor your usage
Check the X-RateLimit-Remaining header proactively to throttle requests before hitting the limit:
javascript
function shouldThrottle(response) {
const remaining = parseInt(
response.headers.get('X-RateLimit-Remaining') || '200',
10
);
return remaining < 10;
}
Per-endpoint notes
Most endpoints share the global 200 req/min limit. The following endpoints have additional considerations:
| Endpoint | Note |
|---|---|
POST /api/v2/ingest | Uses HMAC auth; same global limit applies |
GET /api/v2/brain | Supports ETag caching to avoid unnecessary requests |
POST /api/v2/sessions/[id]/enrich | Triggers async processing; avoid rapid repeated calls |
Best practices
- Cache responses when possible, especially for the brain endpoint which supports ETag
- Batch writes using populate and ingest endpoints
- Implement backoff in all automated clients
- Use webhooks instead of polling for event-driven workflows
- Monitor headers to stay within limits proactively
Next steps
- API Overview -- General API information
- Webhooks -- Event-driven alternative to polling