- A rolling-hour rate limit — requests per hour, set by your tier.
- A monthly quota — requests per billing period, also set by your tier.
429 with a code that tells you which
limit was hit. Both limits are keyed on your organization, not your token —
rotating or adding tokens doesn’t reset or multiply them.
What counts
Quota is deducted only after a real data-layer lookup. A request rejected
before reaching the data layer (bad token, over quota, rate-limited) does not
consume monthly quota.
Response headers
Every billed response — success or429 — carries the current limit state, so
you can implement adaptive backoff without provoking a 429:
Hourly rate limit
The hourly limit is a token bucket: capacity equals your tier’s hourly cap, refilling smoothly. This tolerates bursts — a quiet client can briefly exceed the steady-state rate (useful for backfills and overnight batch pulls). When the bucket is empty:Retry-After is the whole number of seconds until the bucket has a token again.
Honor it before retrying.
Monthly quota
The monthly quota is a hard counter — there’s no overage. When it’s exhausted:Retry-After is not set on quota_exceeded — the wait is typically days.
Either upgrade your tier (effective immediately) or wait for resets_at.
Handling 429s
1
Distinguish the two codes
Branch on
error.code: rate_limited is short-lived; quota_exceeded
needs an upgrade or a wait until resets_at.2
Respect Retry-After
On
rate_limited, wait Retry-After seconds before retrying. Don’t retry
quota_exceeded in a tight loop.3
Back off proactively
Watch
X-RateLimit-Remaining and X-Requests-Remaining-Month on successful
responses and slow down before you hit zero.