Docs Guides Rate Limiting

Rate Limiting

API requests are rate limited to protect the platform and ensure fair usage.

Default limits

CategoryEndpointsLimitWindow
Calculation/calculate-pay, /calculate-pay-audited, /compare-awards, /compare-scenario, /detect-risks, /detect-risks-from-calculation, /batches/upload60 req/min1 minute
GeneralAll other authenticated endpoints (/awards, /batches, etc.)120 req/min1 minute
Health/healthNo limit

Limits are applied per API key. Each key has its own independent counter.

Response headers

Every response includes rate limit headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the current window resets

429 Too Many Requests

When you exceed the limit, the API returns:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1710410460
Retry-After: 23
{
  "error": "rate_limit_exceeded",
  "detail": "Rate limit exceeded. Please retry later.",
  "status_code": 429
}

Retry strategy

Use the Retry-After header (seconds) or X-RateLimit-Reset (unix timestamp) to determine when to retry:

import time
import requests

response = requests.post(url, headers=headers, json=payload)

if response.status_code == 429:
    retry_after = int(response.headers.get("Retry-After", 5))
    time.sleep(retry_after)
    response = requests.post(url, headers=headers, json=payload)

Best practices

  • Spread requests evenly rather than sending bursts
  • Cache award data — award detail and classification lists change infrequently
  • Use batch upload for bulk compliance checking instead of individual calls
  • Monitor X-RateLimit-Remaining to proactively slow down before hitting limits
  • Implement exponential backoff for retries after 429 responses