Rate Limits
How Selyf's API throttles requests -- the global default, per-route limits, and AI token budgets.
Global default
100 requests / 60 seconds per client, configurableApplies to every route that has no more specific limit of its own. The numbers shown here are this codebase’s schema defaults (RATE_LIMIT_MAX / RATE_LIMIT_WINDOW_SECONDS) -- an operator can configure different values; this page does not claim to know this specific production deployment’s live configuration.
Authentication routes
20 requests / 60 seconds, fixedGET /auth/google, GET /auth/google/callback, POST /auth/google/disconnect, and DELETE /auth/account -- the highest-value target for brute-force or account-enumeration attempts, so this limit is a fixed code constant, not environment-configurable.
Mailbox sync
10 requests / 60 seconds, fixedPOST /api/mail/sync. A sync already in progress for the account also returns RATE_LIMITED immediately, independent of this window, so two overlapping syncs never run at once.
AI analysis & drafting
20 requests / 60 seconds, fixedPOST /api/mail/threads/:threadId/analyze and POST /api/mail/threads/:threadId/draft. This is defense in depth on top of the real cost control below (the per-account token budget) -- it bounds how fast either endpoint can be probed regardless of budget.
Analytics
60 requests / 60 seconds, fixedPOST /api/analytics/event. Generous relative to the limits above -- these are cheap UI-interaction pings, not Gmail or AI-provider calls, so the real cost control is the fixed event allowlist, not this number.
AI token budgets
Independent of the request-rate limits above, every AI call is checked against a per-account daily and monthly token budget (input plus output tokens) before it is made. This codebase’s schema defaults are 20,000 tokens/day and 200,000 tokens/month -- again, configurable defaults, not a claim about this deployment’s live values. Exceeding either returns AI_BUDGET_EXCEEDED; see Errors for what that means for a client.
Handling a 429 or 503
A rate-limited or temporarily-unavailable response includes a Retry-After header naming the number of seconds to wait. See API Reference for the exact limit and error codes each route can return.