Skip to content
Download as .md

Rate Limiting

Written by Rohman Beny Riyanto

Every request is rate-limited per client IP, not per account or per token - a shared office network or a NAT'd mobile carrier can hit the limit collectively, not just one misbehaving client. Default limit: 100 requests per rolling 1-minute window. Both successful and failed requests count against it (neither is skipped/excluded).

Reading the headers

Every response - not just the one that finally trips the limit - carries three headers so a client can back off before hitting 429:

HeaderMeaning
X-RateLimit-LimitThe window's total allowance (100 by default).
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetWhen the current window resets.

A reasonable FE strategy: once X-RateLimit-Remaining drops into single digits, start throttling your own request rate (debounce search-as-you-type calls, batch polling, etc.) instead of waiting to get a 429 back.

When the limit is hit

json
{
  "response_code": "502",
  "response_text": "Rate limit exceeded",
  "error_details": {
    "error": "BUSINESS_ERROR",
    "detail": "...",
    "path": "/v2/..."
  }
}

HTTP status 429. There is currently no Retry-After header - use X-RateLimit-Reset from the previous response (the 429 response itself still carries the standard rate-limit headers) to know when the window rolls over, and don't retry before then. Retrying immediately in a tight loop just keeps consuming whatever's left of the next window the moment it opens.

This is a global default, not necessarily every environment's exact number

100 requests/minute is this project's own default - an individual deployment can configure a different value. Always read the live X-RateLimit-Limit header rather than hardcoding 100 in FE code.