Pagination and rate limits
List responses
List endpoints return a JSON object with a single named array — never a bare array at the top level, so the envelope has room to grow. The key names the resource:
{ "products": [ /* ... */ ] }{ "orders": [ /* ... */ ] }Read the array off its named key (products, orders, collections,
credentials, deliveries, and so on). An empty array means a verified empty
result; a failed read is a non-2xx error, never an empty array (see
Errors).
Pagination — limit and offset
Paging is offset-based, opt-in per route. Endpoints that page accept two query parameters:
| Parameter | Type | Range | Default |
|---|---|---|---|
limit | integer | 1 to 100 | route-defined (commonly 20) |
offset | integer | 0 or greater | 0 |
curl "https://api.ruo.pro/v1/merchant/subscriptions?limit=20&offset=40" \
-H "Authorization: Bearer fdk_your_key_here"Advance a page by adding limit to offset. There is no cursor scheme today.
Not every list endpoint pages. The public catalog list routes
(/v1/tenants/{tenant}/catalog/products, /catalog/collections) and the
merchant order and catalog lists (/v1/merchant/orders, /v1/merchant/catalog)
return the full set for the tenant. Routes that do accept limit/offset
include catalog search, merchant subscriptions, gift cards, returns, and
several operator/reporting lists.
Search — paging plus counts
Catalog search echoes the applied paging alongside the results, so you can page through matches:
curl "https://api.ruo.pro/v1/tenants/nova-peptide/catalog/search?q=bpc&limit=10&offset=0"The response includes result_count, the applied limit and offset, the
resolved filters, the facets, and the products page. A blank or empty q
returns an empty, unfiltered result set — not an error.
With the SDK, pass the same fields to the typed methods:
const results = await store.search({ q: "peptide", limit: 10 });Rate limits
Flightdeck applies rate limiting narrowly and deliberately today. Rather than a blanket per-caller quota, the limiter guards the surfaces where abuse is cheapest.
What is rate-limited
- Credential verification. The
fdk_verification path is rate-limited on the attempt, before the database lookup — anfdk_key is otherwise online-guessable with no limiter. This covers/v1/my/*authentication and the initial-credential issuance flow. - Some management and operator routes return
429when their limiter is spent.
When a limiter is spent, the response is 429 with a retry-after header (in
seconds) and an error body whose code is rate_limited. If the limiter’s own
backing store is unavailable, the route fails closed with a 503 rather than
letting an unmetered request through.
What is not rate-limited
- The public catalog reads (
/v1/tenants/{tenant}/catalog/*) are unthrottled today — there is no per-caller limit on them.
Client guidance
Do not hard-code any specific limit or window — the numbers are operational and
subject to change, and this page deliberately does not publish them. Instead,
handle 429 defensively everywhere:
- Read the
retry-afterheader and wait at least that long before retrying. - Back off exponentially on repeated
429s. - Never treat a
429as a permanent failure, and never assume a route’s current throttling behavior is permanent.
See Errors for the full status-code and error-code reference.