Every /api/v1/* response tells you exactly where you stand in your window, so
you never have to guess your quota. Read the headers on the response you already
have — do not hard-code a number.
Runnable. Every header and status on this page was captured live from the
partner sandbox at https://phosra-api-sandbox-production.up.railway.app on
2026-07-06. The /api/v1/platforms read used below needs no API key, so you
can reproduce the exact bytes.
The limit
Tier
Default limit
Window
Keyed by
Sandbox / free
100 requests
per 60 s (rolling)
your developer org (authenticated) or source IP (unauthenticated)
Paid
Raised per plan
per 60 s
your developer org
The default of 100 requests/minute is the free-tier org limit
(DefaultFreeRateLimitRPM). Authenticated calls are counted per developer org
— every key in the org shares one bucket — so adding keys does not add quota.
Unauthenticated calls (the sandbox read routes) are counted per source IP.
Discovery reads are unmetered. The unauthenticated OCSS discovery surface —
/.well-known/ocss/trust-list, profiles, and Annex B editions — carries no
rate-limit headers and is not counted against your window. Only the /api/v1/*
surface is metered. Poll discovery cheaply with ETags.
Read your window off every response
Every metered response carries three headers. Read them and you always know your
exact standing — no fixed quota to hard-code.
X-RateLimit-Reset is Unix epoch seconds, not a duration and not
milliseconds. To sleep until reset: wait = max(0, reset - now_seconds).
What a 429 looks like
When you exhaust the window you get 429 Too Many Requests with Retry-After
(seconds) and the same three counters, so a single response tells you both how
long to wait and that you are fully drained (remaining: 0). Captured live after
exhausting the 100-request window:
text
HTTP/2 429content-type: text/plain; charset=utf-8retry-after: 60x-ratelimit-limit: 100x-ratelimit-remaining: 0x-ratelimit-reset: 1783321440Too Many Requests
Two 429 bodies, one contract. The per-IP throttle on unauthenticated routes
returns the plaintext body above. The per-org limiter on authenticated routes
returns the machine-readable house envelope instead — same status, same intent:
Branch on the status code (429) and honour Retry-After — never on the
body shape. See the errors reference.
Handle it: wait for the reset, then retry
Do not retry a 429 immediately — sleep until the window resets, then send the
request exactly once. Retry-After (seconds) is the simplest signal;
X-RateLimit-Reset (absolute) is equivalent.