Rate limits
Plan-based sliding windows, per team, per key.
API key traffic is rate-limited per team on four sliding windows simultaneously — hourly, daily, weekly, and monthly. Session-token traffic uses the per-user action limits documented in the web app.
The hit-closest-first window wins: if you're under the hourly limit but over the monthly limit, you're monthly-limited.
Limits per plan
These are the current SDK request budgets. See
packages/shared/src/plans/rate-limits.ts in the monorepo for the source
of truth (also covers per-action limits like album:create,
track:create, etc.).
| Plan | Hourly | Daily | Weekly | Monthly |
|---|---|---|---|---|
air | 1 000 | 5 000 | 20 000 | 50 000 |
pro | higher | higher | higher | higher |
ultra | higher | higher | higher | higher |
max | highest | highest | highest | highest |
air numbers shown above are exact; pro / ultra / max values
scale up. Check PLAN_RATE_LIMITS in the monorepo for the exact
current values — they're intentionally overridable per deploy.
Response headers
When you're close to a limit, every response includes:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1732998000X-RateLimit-Reset is a unix timestamp in seconds.
When you hit the limit
The server returns:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{ "error": "rate_limited" }Back off and retry when X-RateLimit-Reset elapses. The
errors page has a minimal backoff helper.
Usage tracking
Every API-key request is counted in a per-team, per-key monthly counter (Redis-backed, fire-and-forget). You can see usage in Team → Settings → API Keys → Usage in the web app.
Session tokens
User sessions don't share the SDK bucket — they're subject to the same per-action limits that the web app uses. These are generous and mostly protect against runaway client bugs.