Rate limits
Limits by key type
Publishable keys are fixed at 120 requests/minute, regardless of plan. They're meant for public, browser-side reads.
Secret keys scale with your workspace's plan:
| Plan | Secret-key limit |
|---|---|
| Trial | 300 / min |
| Dev | 300 / min |
| Studio | 600 / min |
| Scale | 1,200 / min |
| Business | 1,200 / min (raised on request) |
Limits are counted per project per key type, in a fixed window.
Unauthenticated reads
Public read requests — no key at all — are not rate limited by this system today. Don't build on that: it's a property of the current implementation, not a guarantee. If you're making volume requests, send a key so your traffic is attributable and predictable.
Hitting the limit
You get 429 with a message naming the limit:
{ "error": "Rate limit exceeded. This secret key allows 300 requests per 60s window." }The counter increments even on rejected requests, so hammering a limited key keeps it limited — back off rather than retrying tightly.
Backing off properly
async function fetchWithRetry(url: string, init: RequestInit, attempts = 4) {
for (let i = 0; i < attempts; i++) {
const res = await fetch(url, init);
if (res.status !== 429) return res;
// Exponential backoff with jitter, so parallel workers don't retry in lockstep.
const wait = Math.min(2 ** i * 500, 8000) * (0.5 + Math.random());
await new Promise((r) => setTimeout(r, wait));
}
throw new Error('Rate limited after ' + attempts + ' attempts');
}Staying under it
- Cache reads. Published content changes when you publish, not per visitor. Fetch at build time or cache with a TTL rather than per request.
- Fetch lists, not N+1.
GET /blog/postsreturns full metadata for every post — enough to render an index without a request per post. - Split keys by workload. A separate key per site or job keeps a runaway batch job from throttling your production site, and makes it obvious which one to revoke.
Newsletter endpoints are separate
The public subscribe endpoint has its own limits — per IP, per address, and per project — plus a confirmation-email cooldown. See Newsletter limits.
Usage metering
API requests are metered per workspace for billing. Metering never rejects a request —
it's an accounting path, and a failure there is swallowed rather than surfaced to you.
Rate limiting is the only thing that returns 429.