Pagination & filtering
List endpoints return pages of results, not everything at once. The gateway passes paging and filter parameters straight through to the capability, so the exact names and limits are defined per endpoint — check the API Explorer for the one you're calling. Most follow the same conventions below; Storage and Search are the two exceptions.
Common conventions
| Parameter | Purpose | Example |
|---|---|---|
limit | How many items to return. | ?limit=50 |
offset | How many items to skip (offset paging). | ?offset=100 |
order | Sort field and direction, as field.direction. | ?order=created_at.desc |
curl "https://api.revenexx.com/v1/products?limit=50&order=created_at.desc" \
-H "X-Revenexx-Tenant: <TENANT_SLUG>" \
-H "X-Revenexx-Api-Key: rvxk_..."
A typical page response carries the items, the paging state and an echo of the filter that was applied:
{
"items": [ /* ... */ ],
"page": { "limit": 50, "offset": 0, "total": 248, "returned": 50, "hasMore": true },
"filter": {}
}
page.limit is the size actually used: a limit above an endpoint's maximum is clamped, not refused.
Filtering
Filters are query parameters named after a field, and they match exactly:
curl "https://api.revenexx.com/v1/orders?number=ORD-000123" \
-H "X-Revenexx-Tenant: <TENANT_SLUG>" \
-H "X-Revenexx-Api-Key: rvxk_..."
?field=valueis equality on that field. There is no substring search, noOR, no negation and no range.- Several filters are
ANDed. - A parameter the endpoint doesn't know is ignored, not rejected. A typo such as
?stauts=pendingreturns200and the unfiltered list. Where the response carries afilterecho, read it to see what was actually applied; not every list returns one.
Operator prefixes such as ?status=eq.pending are not part of the public filter syntax. Write ?status=pending. Pagination and filtering in App Studio has the full rules for the lists an App serves.
Storage and Search use their own conventions
Two services don't take the limit/offset/order and ?field=value conventions above. Using them there is silently ignored, so match the service:
| Service | Paging | Sorting | Filtering | Response |
|---|---|---|---|---|
| Most services (Products, Orders, Customers, Inventories, Payments, and so on) | limit, offset | order=field.direction | ?field=value | items and page |
Storage (GET /v1/storage/assets) | limit (default 50, max 200), page | sort=field, prefix - to reverse (created_at, size_bytes, original_name) | filter[folder_id], filter[kind], filter[status], filter[created_at][gte]/[lte], plus search | data, links and meta |
Search (/v1/search/collections/{collection}/documents/search) | page, per_page | sort_by | filter_by | see the API Explorer |
curl "https://api.revenexx.com/v1/storage/assets?filter[folder_id]=<FOLDER_ID>&sort=-created_at&limit=50&page=2" \
-H "X-Revenexx-Tenant: <TENANT_SLUG>" \
-H "X-Revenexx-Api-Key: rvxk_..."
On Storage, ?folder_id=... is an unknown parameter and is ignored, so it returns every asset. offset and order are ignored too. Storage's folder list isn't paged or filtered at all.
Paging through everything
For a service that uses limit and offset, increase offset by limit until page.hasMore is false — or, on an endpoint that doesn't return page, until a page holds fewer items than you asked for:
async function* pages(path, limit = 100) {
for (let offset = 0; ; offset += limit) {
const res = await fetch(`${path}?limit=${limit}&offset=${offset}`, { headers })
const { items, page } = await res.json()
yield* items
if (page ? !page.hasMore : items.length < limit) return
}
}
limit, the sortable fields, and the exact response shape are defined by each capability. The API Explorer shows the authoritative parameters and schema for every endpoint your tenant exposes.