Skip to content
thefaqappthefaqapp
Browse docs

Rate limits

Per-key rate limits by plan, response headers, and how to back off cleanly.

Updated 2026-06-14

Rate limits apply per API key and combine a per-minute burst limit with a per-month quota. Hitting the per-minute limit returns 429 rate_limit_exceeded; exhausting the monthly quota on a write or AI request returns 429 monthly_quota_exceeded. Both carry a Retry-After header.

Limits by plan

Plan Per minute Per month Notes
Free 60 1,000 Read API only
Starter 300 10,000 Read + write
Pro 1,500 read / 600 write 100,000 Full API
Enterprise Custom Custom Negotiated per contract

Per-minute caps are scoped by tier, read and write each get their own window. Free and Starter share a single per-minute figure across both tiers; Pro splits them (1,500 read, 600 write).

Per-minute uses a sliding window resetting every 60 seconds. Per-month resets on the 1st of each calendar month, UTC, not your billing renewal date.

Multiple keys on one org each get their own burst limit but share the monthly quota.

Response headers

Every response, success or failure, includes:

Header Meaning
X-RateLimit-Limit Total requests allowed in the current per-minute window
X-RateLimit-Remaining Requests left before the per-minute limit triggers
X-RateLimit-Reset Unix timestamp (seconds) when the per-minute window resets
X-Monthly-Quota-Limit Monthly request quota for the plan
X-Monthly-Quota-Used Requests counted against the monthly quota so far this period
X-Monthly-Quota-Reset Unix timestamp (seconds) when the monthly quota resets (1st of next month, UTC)
X-Monthly-Quota-Exceeded true on read responses served after the monthly quota is hit. You’re still served, but you’ve passed your quota, upgrade or wait for the reset.
Retry-After Seconds to wait before retrying. Present only on 429 responses.

429 response shape

A per-minute burst limit returns rate_limit_exceeded:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please try again later.",
    "retryAfter": 42
  }
}

A monthly quota limit (on write or AI tiers) returns monthly_quota_exceeded:

{
  "error": {
    "code": "monthly_quota_exceeded",
    "message": "Monthly API request quota exceeded. STARTER plan allows 10000 requests/month. Resets at 2026-07-01T00:00:00.000Z.",
    "limit": 10000,
    "used": 10000,
    "resetAt": "2026-07-01T00:00:00.000Z",
    "upgradeUrl": "https://thefaq.app/pricing"
  }
}

Branch your retry logic on the code. A rate_limit_exceeded means wait retryAfter seconds and try again. A monthly_quota_exceeded means upgrade or wait until resetAt, days, not seconds. Read requests are never blocked by the monthly quota; they keep serving with the X-Monthly-Quota-Exceeded: true header instead.

Staying within limits

Cache reads. Question lists and search results change far less than read traffic. The @faqapp/core SDK has built-in caching with configurable TTL. For your own stack, cache responses by the URL + auth-key pair.

Paginate with cursors, not by fetching everything. Use cursor from meta.pagination to walk through pages on demand. Don’t fan out parallel requests for every page; that hits the burst limit fast.

Batch writes when you can. If you have 50 questions to import, send them as a single create-many request rather than 50 sequential POSTs.

Watch x-ratelimit-remaining. When it drops below ~20% of x-ratelimit-limit, slow down. Most rate-limiting incidents are visible 10–30 seconds before they hit.

Back off exponentially on repeated 429s. Start with the Retry-After value; on the second 429 double it; cap at ~60s. The SDK does this automatically.

Separate read and write keys. Burst spikes on read traffic shouldn’t block your write workload. Two keys, two separate per-minute windows.