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:

PlanSecret-key limit
Trial300 / min
Dev300 / min
Studio600 / min
Scale1,200 / min
Business1,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/posts returns 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.