Skip to content

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:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix 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

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/populate endpoint 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:

EndpointNote
POST /api/v2/ingestUses HMAC auth; same global limit applies
GET /api/v2/brainSupports ETag caching to avoid unnecessary requests
POST /api/v2/sessions/[id]/enrichTriggers 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