Pages
Lists takepage (1-100,000, default 1) and perPage (1-100, default 25) and answer with the page envelope:
totalis exact;totalPagesisceil(total / perPage)and0when nothing matches.- A page beyond
totalPagesreturns200with an emptydatalist. - There are no cursors or
nextlinks; compute neighbours frompageandtotalPages. - A
pageorperPageoutside its range → 400data-failed-validation, constraintinvalid-pagewithparams.min/params.max.
Sorting
sort is one field; prefix it with - for descending (sort=field or sort=-field):
id in the direction of the sort field, so the order is total and stable. Any other value, a comma-separated list included → 400 data-failed-validation, constraint invalid-sort with params.allowed (the sortable fields).
Searching
Lists that support it takesearch (1-255 characters): a case-insensitive substring match over the fields the reference page names, combined with filters by AND. A number also matches the id.
Voucher values are never searched as text: on the vouchers list, search is an exact match on the full value, and only for principals with reveal-provider-vouchers; others get an empty page.
Filtering
Filters use bracket notation:
Operators:
eq, ne, in, gt, gte, lt, lte, contains, startsWith, isNull. Each list allows specific fields and operators (see its reference page). Rules:
- at most 20 filter parameters per request and 100 values per
inlist (more → constraintinvalid-filter); - a literal comma inside a value is written
\,, a backslash\\; nullis not a value; useisNull;- an unknown field or operator, or a value of the wrong type → 400
data-failed-validation, constraintinvalid-filter,propertythe parameter (filter[redeemedAt][gte]); any other undeclared parameter → the same 400 with the constraintunknown-parameter; - URL-encode the brackets if your HTTP client does not (
filter%5Bstatus%5D=active).
status filters use the effective status: a scheduled set whose activeFrom has passed counts as active even before the schedule has run.
Invalid list parameters
Every problem with the list parameters of one request comes back in one 400data-failed-validation, one more.validationErrors item per problem:
page × perPage, but deep pages are slow and shift while rows are added: narrow the query with filters, or walk time windows as in Downloading large lists.
Syncing large collections
Offset pages can skip or repeat rows when data changes between requests. To keep a local copy in sync, filter by a time field and sort by it, then deduplicate byid:
redeemedAt you saw minus 60 seconds: a redemption can become visible shortly after its timestamp. For a full copy see Downloading large lists; for near-real-time updates use webhooks.
Downloading large lists
There are no export endpoints: to get a whole list (for a CSV or spreadsheet), page through the list operation itself.- Use
perPage=100(the maximum on every list) and send the same filters,searchandsorton every request. - For a small list, request pages 1 to
totalPages. - For a large list (we recommend it above about 100 pages), walk time windows on the list’s download key instead, so rows added meanwhile do not shift the pages:
createdAt, orredeemedAtfor redemptions. Fix a cut-off at the start time, sort newest first, and after page 100 restart at page 1 with the last row’s value as the new upper bound, dropping ids you already have:
- Rows created after the cut-off are not included; run again later for newer rows.
- Send one request at a time. On 429, wait
Retry-Afterand repeat the same request. Requests are limited at the network edge per source IP address (see Limits → Edge limits), and a 50,000-row download (500 requests) stays far below that limit.