Gallery Platform API

Rate limits

Every response advertises your remaining quota with IETF RateLimit headers. Read them and self-throttle.

The API is rate-limited per principal with a token-bucket limiter: a burst capacity plus a sustained refill rate. Every response carries the IETF RateLimit headers so your client can self-throttle before it's ever throttled.

Limits are keyed on the principal — the API key or the user — never on IP address. The limiter is DoS and cost protection; row-level security remains the real access boundary.

Response headers

Every response (including 429s) includes:

RateLimit: "default";r=27;t=2
RateLimit-Policy: "default";q=30;w=15
FieldMeaning
RateLimit rRequests (tokens) remaining right now.
RateLimit tSeconds until the bucket is full again.
RateLimit-Policy qThe quota — the bucket's burst capacity.
RateLimit-Policy wSeconds it takes an empty bucket to refill to q.

These follow the IETF RateLimit header fields draft. Read r and back off as it approaches 0. Note that w is not a fixed calendar window: tokens refill continuously, so q over w gives the sustained rate (e.g. q=30, w=15 refills two requests per second).

When you're limited

Over the limit, the API returns 429 rate_limited (an RFC 9457 error) with a Retry-After header giving whole seconds to wait, alongside RateLimit (r=0) and RateLimit-Policy:

HTTP/1.1 429 Too Many Requests
Retry-After: 1
RateLimit: "default";r=0;t=15
RateLimit-Policy: "default";q=30;w=15
Content-Type: application/problem+json

Retry-After is the wait (whole seconds, minimum 1) until the next request can be served — usually short, because tokens refill continuously. Honor it, then retry. Well-behaved clients watch the RateLimit header and slow down before hitting 429 at all.

Quotas

Quotas depend on the principal class. Current burst / sustained limits:

PrincipalBurst (q)Refill window (w)Sustained (per minute)
Gallery key (gpk_)3015s~120
Org key (opk_)6012s~300
First-party app user10010s~600
External user token4012s~200

Treat these as the current values, not a contract — the authoritative, per-response numbers are always the RateLimit / RateLimit-Policy headers.

Limiter unavailable

If the limiter must run but can't, the API fails closed with 503 service_unavailable and Retry-After: 5 rather than letting an unmetered request through. Retry after the indicated delay.

On this page