Limits
Two limiters are in effect:| Limiter | Rate | Burst | Applies to |
|---|---|---|---|
| Global | 240 req/min (4/sec) | 60 tokens | All API endpoints |
| Auth | 10 req/min | 5 tokens | POST /api/auth/login, POST /api/auth/register, POST /api/auth/logout, GET /api/auth/callback/*, POST /api/auth/social, GET /api/bot-gateway |
Algorithm
Both limiters use a token bucket:- Each IP starts with a full bucket
- One token is consumed per request
- Tokens refill at the configured rate
- When the bucket is empty, the request is rejected
Rate limit response
When a limit is exceeded the server returns: Status:429 Too Many Requests
Header: Retry-After: 1
X-RateLimit-* headers. The Retry-After: 1 value is fixed at 1 second regardless of how depleted the bucket is.
IP detection
By default the limiter uses the TCPRemoteAddr. Forwarded headers (X-Forwarded-For, X-Real-IP) are only trusted when the request comes from a configured trusted proxy CIDR, preventing IP spoofing.
Configure trusted proxies via the TRUSTED_PROXIES environment variable (comma-separated CIDRs):
RemoteAddr is within a trusted CIDR, the leftmost IP in X-Forwarded-For (or X-Real-IP) is used as the client IP.
Exemptions
| Endpoint | Behaviour |
|---|---|
GET /api/ws (WebSocket) | Exempt from rate limiting once connected |
