# Rate limits and quotas

> Buckets, weights, headers and the 429 response.

Source: https://docs.tune.toys/developers/rate-limits/ (updated 2026-11-01)

Limits use shared token buckets, so they hold across API instances. The numbers below are **proposed defaults** until an owner decision publishes advertised limits.

| Bucket (per minute, burst) | Anonymous (per address) | Free key | Pro key   |
| -------------------------- | ----------------------- | -------- | --------- |
| read                       | 120, 60                 | 300, 100 | 3000, 600 |
| write                      | not limited here        | 30, 10   | 300, 60   |
| expensive                  | 10, 5                   | 20, 10   | 240, 60   |
| Rolling 24 hour requests   | none                    | 10 000   | 500 000   |

Each route has a `cost`: list and sync pages weigh 2, release package, engine and asset bytes 5, webhook test sends 25 in `expensive`, and `0` for `/v1/developer/key`, `/v1/developer/limits`, `/v1/developer/scopes` and `/v1/openapi.json`.

## Headers

Every limited response carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds) for the most constrained bucket.

## When you are limited

A rejection is `429 RATE_LIMIT` with `Retry-After` and `details: { bucket, limit, remaining, resetSeconds, retryAfterSeconds, quota }`. `bucket` is `daily` for the quota. Back off for `Retry-After` seconds, then retry. The first quota rejection per key per day notifies the app owner.

## Tiers and usage

An app is **pro** while its owner holds an active Developer API grant, and **free** otherwise. Usage is recorded per key and hour and readable at `GET /v1/developer/apps/{appId}/usage` (also as CSV). Usage is informational and kept 90 days.
