Platform / Platform
API and login rate limits
Machine API traffic uses node-local Hammer counters. Password login uses a separate PostgreSQL-backed throttle shared by every application node.
01 Default limits
details1000 requests per 60 seconds
API_RATE_LIMIT controls the default ceiling (1000). Authenticated machine requests are keyed by credential ID; unauthenticated bootstrap requests are keyed by client IP. The 60-second period is fixed in runtime configuration. ETS counters are local to each application node.
02 Password login protection
details10 failures per identity and IP
Ten failed passwords for the same normalized email and client IP within 15 minutes start a 30-minute cooldown. The tenth failure returns HTTP 429 with retry-after; a successful login clears this identity/IP bucket.
50 unreturned attempts per client IP
A broader 15-minute IP ceiling limits email rotation and Argon2 CPU abuse. Every submission reserves one slot and a verified login returns its own slot, so the budget is spent by failures and shared NAT egress traffic is not punished for succeeding. IPv6 clients are counted per /64 prefix. Login counters are durable in PostgreSQL and shared across application nodes.
03 Trusted client IPs
detailsForwarded headers are fail-closed
The app reads x-forwarded-for only when the direct peer is listed in TRUSTED_PROXY_IPS. Forwarded headers from every other peer are ignored; keep the application origin firewalled from direct traffic.
04 Response headers
detailsx-ratelimit-remaining
Requests remaining in the current window. Included in every successful response.
x-ratelimit-reset
ISO 8601 timestamp indicating when the current rate limit window resets.
05 When rate limited (HTTP 429)
exampleResponse format
API limits return retry-after plus the shared RFC 9457 problem body. Password-login limits return retry-after with a minimal plain-text 429 response so browsers and automated clients preserve the real status instead of following a redirect loop.
HTTP/1.1 429 Too Many Requests
retry-after: 42
content-type: application/json
{
"type": "https://robotscenter.net/problems/rate-limited",
"title": "Rate limited",
"status": 429,
"detail": "Rate limit exceeded. Please retry later.",
"request_id": "req-abc123",
"extra": { "retry_after_seconds": 42 }
}
06 Configuration
detailsEnvironment variables
Set API_RATE_LIMIT to change the per-node machine API ceiling. Set TRUSTED_PROXY_IPS to the comma-separated direct reverse-proxy addresses allowed to supply x-forwarded-for. Login thresholds are fixed production safety limits.
Related docs
see also