Skip to content
FolioSign inStart your trial

Docs · Concepts

Rate limits

The three limits that apply to a request, the headers that report them, and how to back off.

Three buckets apply to a request made with a key, and the tightest one wins:

BucketDefaultNotes
Per key120 requests per 60 secondsA key can be given a lower limit with rate_limit_per_minute.
Per church, shared by every key of that church3000 per minuteCreating more keys does not raise it.
Per device (booth keys)600 per minute, and 3000 per minute per churchSee booth devices.

The defaults can differ per deployment; trust the headers, not these numbers. Partner keys also have a per-customer bucket so one customer church cannot use up the rest.

Headers#

Successful responses carry:

HeaderMeaning
RateLimit-LimitRequests allowed in the current window.
RateLimit-RemainingRequests left in the current window.

A limited response is 429 rate_limited and also carries Retry-After, in seconds.

Code
{
  "status": false,
  "message": "Too many requests. Wait before trying again.",
  "error": { "code": "rate_limited", "status": 429, "request_id": "req_b337770ecebe03b03a88a8998b59263d" }
}

Backing off#

Wait at least Retry-After seconds. Without the header, double the wait each time (1, 2, 4, 8 seconds) up to a ceiling, and add a little random jitter so many clients do not retry together. Send an Idempotency-Key on writes so a retry is safe.

async function call(url, init, attempts = 5) {
  for (let attempt = 0; attempt < attempts; attempt += 1) {
    const response = await fetch(url, init);
    if (response.status !== 429 && response.status < 500) return response;
    const wait = Number(response.headers.get("retry-after")) || 2 ** attempt;
    await new Promise((done) => setTimeout(done, (wait + Math.random()) * 1000));
  }
  throw new Error("Folio is still limiting this key");
}

Spend is metered separately#

Transcription hours, notes and Ask are limited by the plan, not by request rate. Running out answers 402 quota_exceeded, and the monthly AI budget answers 402 ai_budget_exhausted. See errors.

Verified against API version 0.0.0-dev. Generated from the live OpenAPI document.