# Rate limits
Source: https://docs.aden.space/docs/developers/api/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 [#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 |

<Callout>
  `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.
</Callout>

## Response headers [#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: 1732998000
```

`X-RateLimit-Reset` is a unix timestamp in seconds. Rate-limited responses
also carry a `Retry-After` header (seconds).

## When you hit the limit [#when-you-hit-the-limit]

The server returns:

```http
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](/docs/developers/sdk/errors#rate-limits) has a minimal
backoff helper.

## Usage tracking & billing [#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 [#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.