Defaults
Out of the box, every (clientId, install) pair gets:
- Window: 60 seconds (configurable via
PUBLIC_API_RATE_WINDOW_MSon the server) - Max requests: 120 per window (configurable via
PUBLIC_API_RATE_MAX)
Per-app overrides are taken from AppApiKey.RateLimit.MaxRequests — if your account has a custom limit negotiated, it is applied automatically; you don't need to change anything in your code.
Headers
The limiter uses the IETF draft-8 RateLimit headers (NOT the legacy X-RateLimit-* form). Every /public/v1/* response includes:
RateLimit-Limit: 120
RateLimit-Remaining: 117
RateLimit-Reset: 53Reset is seconds until the current window rolls over.
Handling 429
When you exceed the limit:
HTTP/1.1 429 Too Many Requests{ "error": "rate_limited", "message": "Public API rate limit exceeded." }Recommended client behavior:
- Read
RateLimit-Resetfrom the 429 response (or the last 200 response, which also carries it). - Back off for that many seconds plus jitter (e.g.
reset + random(0, 5)). - Retry the same request — idempotent reads are always safe to retry; for writes, ensure your client uses an idempotency key (planned for the curated subset).
Do not implement aggressive retry without backoff — repeated 429s are tracked and may trigger temporary key suspension.