Skip to main content

Rate limiting

API requests are rate limited to protect the platform and prevent a single tenant from degrading service for others ("noisy neighbor").

Headers​

Throttled responses carry standard headers:

HeaderMeaning
X-RateLimit-LimitRequest quota for the current window
X-RateLimit-RemainingRequests left in the current window
Retry-AfterSeconds to wait before retrying (on 429)

Limits​

ScopeDefault (per minute)Keyed byEnv var
Global API120authenticated user id, else client IPRATE_LIMIT_API
Per-tenant300tenant id (fair sharing across tenants)RATE_LIMIT_TENANT
Auth (login, register, magic link, password reset)5 attemptsemail + IP(fixed)

The numeric limits are environment-configurable via the env vars above. Treat 429 responses as authoritative and honor Retry-After.

Ordering and the noisy-neighbor limiter​

The global limiter runs before authentication, so unauthenticated floods are throttled at the edge. The per-tenant limiter runs after the tenant context is resolved from the authenticated user, so its counter is keyed by the real tenant id — one tenant cannot exhaust another tenant's quota. Counters are backed by Redis in production.

Handling 429​

On 429, back off for Retry-After seconds (or use exponential backoff if the header is absent) before retrying. Never tight-loop on a throttled endpoint.