Limits
The limit is applied per IP address (or the first value of
X-Forwarded-For when the request passes through a proxy). Requests from different IPs are counted independently.REDIS_URL), the limit is enforced across all API replicas using a shared fixed-window counter. Without Redis, the counter is per-process — a single IP hitting multiple replicas gets a higher effective limit. In production, configure Redis for consistent enforcement.
Rate limit response headers
Every response — including successful ones — carries two rate limit headers:
When the limit is exceeded, the
429 response also includes:
429 response body
The
429 error body does not include a trace_id. Use the Retry-After header value, not a fixed delay, to determine how long to wait.Handling rate limits
Read theX-RateLimit-Remaining header on every response. When it reaches zero or you receive a 429, back off and retry:
Best practices
ReadX-RateLimit-Remaining proactively. If it’s low, slow down your request rate before hitting the limit.
Implement exponential backoff with jitter. Start at the Retry-After value, then double the delay on each subsequent 429. Add random jitter (±500 ms) to avoid thundering-herd when multiple clients retry in sync.
Avoid polling for status. Use the WebSocket stream for real-time updates — WebSocket messages do not count against REST rate limits. For endpoints that do require polling:
Batch requests where possible. Filter lists server-side (
?status=open) rather than fetching all records and filtering client-side.