Appearance
Rate limits and quota
Two separate counters guard the API.
- Rate limit: requests per minute, per key. Smooths bursts.
- Quota: requests per UTC day on paid plans, per calendar month on the trial, per account. Sets the plan.
Both are enforced at the edge, before a request reaches the index, so a rejected call is cheap for both of us.
Reading the headers
Every response carries the state of the minute window:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the window |
X-RateLimit-Remaining | Requests left in it |
X-RateLimit-Reset | Unix seconds when the window rolls over |
Retry-After | Seconds to wait. Present on 429 only |
Period quota is not in the headers, because it changes too slowly to be worth a byte on every response. Read it from GET /usage, which does not count against either counter.
When you cross a limit
Both cases answer 429. The code tells them apart:
json
{ "error": { "code": "rate_limited", "message": "120 requests per minute exceeded", "retryAfter": 27 } }rate_limited: the minute window. WaitretryAfterseconds and repeat the same request.quota_exceeded: the day or the month. Retrying will not help until the counter resets (00:00 UTC on paid plans,periodEndon the trial), or until the plan changes. Treat it as a state, not a transient error, and stop the loop.
Retry rate_limited with exponential backoff and jitter. A fleet that all retries at Retry-After exactly rebuilds the same spike it just caused.
Plans
| Plan | For | Requests | Per minute |
|---|---|---|---|
| Trial | Try every endpoint, decide if the corpus fits. | 500 / month | 30 |
| Starter | One app or site in production. | 2,000 / day | 60 |
| Growth | Higher volume, several products under one account. | 25,000 / day | 300 |
| Enterprise | Volume beyond the plans above, or terms of your own. | Talk to us | Talk to us |
Quota is counted per account, not per key. Creating a second key separates your environments; it does not double your allowance.
Paid plan numbers are quoted per integration for now, see Pricing.
Staying under them
The index changes once a day at most. Almost every integration that hits a limit is asking the same question repeatedly:
- Cache word lookups. A word's clip list is stable for hours, see Caching.
- Store
clipIdandvideoIdon your side after the first lookup. Clip metadata and transcripts are immutable for a given clip. - Fetch transcripts once per clip, not once per viewing.