Tier matrix
All tiers include all 22 cohorts and full history.
Webhook event delivery is on the roadmap and not yet available.
Per-response rate-limit headers
Every 2xx response from/v1/permits (and other quota-gated endpoints)
carries the following headers so your client can self-throttle:
X-RateLimit-Reset semantics (kind-aware)
The reset surface is interpreted via the X-RateLimit-Quota-Kind header
(or the 429 body’s quota_kind field — they always agree):
Branch on
X-RateLimit-Quota-Kind (or quota_kind in the 429 body) if you
need to display the right narrative to a user. Otherwise the retry
guidance below works identically for both kinds.
429 response shape (RFC 9457 problem+json)
When a key exceeds its quota, the API returns429 Too Many Requests
with a Content-Type: application/problem+json body conforming to
RFC 9457:
Field map
Title and detail are illustrative — the example body shows representative
prose, but title/detail may change without notice. Always branch on
type;
never on the prose fields or the deprecated legacy_code.
Recommended retry behavior
Sleep onretry_after_seconds (or the Retry-After header, or
X-RateLimit-Reset) and retry — the timer is kind-aware on both
daily and monthly quotas. All three surfaces agree.
For monthly quotas the timer points at the next slot in the trailing
30-day window (not the full ceiling restoring at once), so a successful
retry consumes that newly-available slot — back-to-back retries against
a fully-exhausted monthly key will still 429.
Node.js
quota_kind for the
narrative. The retry mechanics are the same either way.
Other guidance
- Cache responses when you can — most endpoints declare
Cache-Controlheaders (e.g., cohort distribution caches 1 hour). - Bulk over loop. Where the API supports bulk parameters, prefer them.
- Watch
X-RateLimit-Remaining-Requestson 2xx responses — back off before the 429 fires.
Migration: away from legacy_code
The legacy_code field ("rate_limited") was added at launch for clients
written against a pre-RFC-9457 error envelope shape. It is deprecated and
being removed — do not depend on it. To migrate:
- Move any client logic branching on
error.code === "rate_limited"to branching ontype(URI) instead. - The
typeURI pattern is stable:…/errors/{daily|monthly}-{requests|exports}-quota-exceeded. - As a fallback, branch on HTTP status
429plus theX-RateLimit-*headers.