ReferenceRate limits

Rate limits and quotas

The platform applies rate limiting narrowly and deliberately. There is no blanket per-caller quota today; the limiter guards the surfaces where abuse is cheapest. This page is the authoritative account of the real limiter behavior — it deliberately does not publish specific numbers, because they are operational and subject to change.

⚠️

Handle 429 defensively on every route, not just the ones documented here. Never assume a route’s current throttling behavior is permanent, and never treat a 429 as a permanent failure.

What is rate-limited

Credential verification

The fdk_ verification path is rate-limited on the attempt, before the database lookup. An fdk_ key is otherwise online-guessable with no limiter, so the throttle sits in front of the key lookup rather than behind it. This covers /v1/my/* authentication and the initial-credential issuance / session-verification flow.

The limiter is keyed per caller (the verification bucket). When it is spent:

  • The response is 429.
  • A retry-after header (in seconds) is set to the limiter’s window.
  • The body’s code is rate_limited, with a message stating the per-minute limit.

Some management and operator routes

Selected management and operator routes carry their own limiters and return the same 429 + retry-after + rate_limited shape when spent. Treat any management route as potentially throttled.

Checkout velocity

Checkout has a velocity gate distinct from the credential limiter. When too many attempts occur for an order/scope, it returns 429 with code velocity_exceeded (a deliberately non-oracle-sensitive 429, so the storefront can back off and retry). See Error codes.

The 429 response

ElementValue
HTTP status429
retry-after headerSeconds to wait before retrying. Always honor it.
Body coderate_limited (verification/management) or velocity_exceeded (checkout).
HTTP/1.1 429 Too Many Requests
retry-after: 60
content-type: application/json
 
{ "error": { "code": "rate_limited", "message": "too many credential verification attempts; ..." } }

Fail-closed when the limiter store is down

The limiter is backed by a store. If that store is unavailable, the platform does not let an unmetered request through — it fails closed with a 503 rather than admitting the request:

SurfaceCodeStatus
Credential/session verification (limiter store down)db_error / select_failed (message: rate limiter unavailable)503
Credential/session check itself could not completeauth_unavailable503

The verification limiter does not emit rate_limiter_unavailable — that code belongs only to the provenance module. When its own backing store fails, it surfaces the underlying database error code (db_error or select_failed) with a 503 and the message rate limiter unavailable. Branch on the 503 status, not on the specific code.

A 503 from these surfaces means the request was refused, not admitted. Retry with backoff. This is the same fail-closed posture the rest of the platform takes on an unavailable dependency (see Error codes).

What is not rate-limited

  • The public catalog reads (GET /v1/tenants/{tenant}/catalog/* — products, product-by-slug, search, collections) are unthrottled today. There is no per-caller limit on them. This is the one deliberately public read surface, and it carries no verification hop to throttle in front of.

Because the public catalog is unthrottled today does not make that permanent. Build clients that back off on 429 everywhere, including on read paths, so a future limiter never breaks them.

Quotas

There are no published per-tenant request or resource quotas today. Pagination is offset-based (limit 1 to 100, offset 0 or greater); list endpoints do not impose a rate cost beyond the limiters described above. See Pagination and rate limits for the paging shape.

Client guidance

  • Read the retry-after header and wait at least that long before retrying.
  • Back off exponentially on repeated 429s.
  • Retry 503 (db_error / select_failed from a downed limiter store, auth_unavailable) with backoff — it is a transient fail-closed refusal, never a signal to proceed unmetered.
  • Do not hard-code any limit or window; they are operational and unpublished.