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
Every API-key response includes headers for the tightest window (the one with the least headroom):
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1732998000X-RateLimit-Reset is a unix timestamp in seconds. Rate-limited responses
also carry a Retry-After header (seconds).
When you hit the limit
The server returns:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{ "error": "rate_limited", "message": "hourly limit exceeded (1000 per hour)" }error is the stable machine-readable code; message names the exhausted
window. Back off and retry when X-RateLimit-Reset (or Retry-After)
elapses. The errors page has a minimal
backoff helper.
Usage tracking & billing
Every served API-key request (429s excluded) is recorded twice:
- a durable per-request ledger row (method, path, status, latency), rolled up monthly per team and per key. This is what usage billing reads, and
- a per-team, per-key monthly counter (Redis-backed) powering the live usage view in Team → Settings → API Keys → Usage in the web app.
API usage bills to the team that owns the key, on the team's plan the same billing customer as storage and other metered usage.
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.