Skip to main content
Every list operation (for example GET /consumer/v1/redemptions) takes the same query parameters. Each reference page lists exactly which sort fields, search fields and filters that operation supports.

Pages

The response is a page envelope:
  • page and perPage echo the values that were applied.
  • total is the exact number of matching items; totalPages is ceil(total / perPage) and 0 when nothing matches.
  • A page beyond totalPages is not an error: you get 200 with an empty data array and the real totals.
  • There are no next or prev links. Compute the next page from page and totalPages.
  • A page or perPage outside the allowed range is answered with 400 data-failed-validation: the more.validationErrors item has property page or perPage, the constraint invalid-page and params.min / params.max.

Sorting

sort is one field, optionally prefixed with - for descending order (sort=field or sort=-field):
  • Use one of the fields the operation allows. Any other value, a comma-separated list included, is answered with 400 data-failed-validation: the item has property sort, the constraint invalid-sort and params.allowed, the sortable fields.
  • The default is the resource’s natural time field, descending (for example -createdAt or -redeemedAt).
  • The server always appends id in the direction of your sort field, so the order is total and stable even when several items share a timestamp.
  • Sorting by a localised text field uses the language of your request.

Searching

search is a free-text term of 1 to 255 characters (an empty value is ignored).
  • It matches case-insensitively as a substring over the operation’s search fields, for example a redemption entity’s refId, displayName and email.
  • A term that is a numeric id, or an exact refId or externalRef, also matches by equality.
  • search and filters are combined with AND.

Filtering

Filters use bracket notation: filter[<field>][<operator>]=<value>, or filter[<field>]=<value> for the default operator. Rules:
  • Field names are the JSON property names; nested properties use dots (filter[redemptionEntity.refId]=customer:48213).
  • A value with an unescaped comma means in: filter[status]=completed,voided. Write a literal comma inside a value as \, and a backslash as \\.
  • null is not a value: use filter[redemptionLinkId][isNull]=true.
  • Several filters are combined with AND; the same field may appear with several operators to form a range.
  • At most 20 filter[…] parameters per request and 100 values per in list; more is answered like an invalid filter (below).
  • Timestamps need an offset (2026-10-01T00:00:00Z); ranges are half-open, so combine gte and lt.
  • An unknown field, an operator the field does not support or a value of the wrong type is answered with 400 data-failed-validation: the item’s property is the parameter (filter[redeemedAt][gte]) and its constraint is invalid-filter. A query parameter the operation does not declare at all gets the constraint unknown-parameter in the same response.
Brackets must be URL-encoded. With curl, let --data-urlencode do it:

Invalid list parameters

Every problem with the list parameters of one request is reported in one 400 data-failed-validation response, with one more.validationErrors item per problem:
There is no limit on page × perPage, but deep pages are slow and shift while rows are added. For large result sets, narrow the list with filters, sync incrementally (below) or walk time windows as described in Downloading large lists.

Syncing large collections

Page numbers shift when items are added while you page, so an offset walk can skip or repeat items. To keep a local copy in sync:
1

Filter by a time field and sort by it

Request filter[redeemedAt][gte]=<last timestamp you stored>&sort=redeemedAt&perPage=100 (use the time field the operation offers, for example redeemedAt or createdAt).
2

Walk the pages

Read pages until page equals totalPages. For a long backlog, restart every 100 pages with a new gte value: the largest timestamp you have seen.
3

Deduplicate by id

gte returns the boundary item again; upsert by id so repeats do not matter.
To react to changes as they happen, subscribe to webhooks.

Downloading large lists

There are no export endpoints: to get a whole list (for a CSV or spreadsheet file, or a one-off extract), page through the list operation itself. The dashboards’ “Download CSV / Excel” action works the same way.
  • Send perPage=100 (the maximum on every list) and the same filters, search and sort on every request. For a small list, plain paging from page=1 to totalPages is enough.
  • For a large list (we recommend it above about 100 pages), walk time windows on the list’s download key instead, so rows added while you download do not shift the pages: createdAt, or redeemedAt for redemptions (each reference page lists the operators; the key supports gt, gte, lt, lte).
    1. Fix a cut-off when you start: filter[redeemedAt][lte]=<start time> and sort by -redeemedAt.
    2. Read pages 1 to 100.
    3. Start again at page=1 with filter[redeemedAt][lte]=<redeemedAt of the last row you received>, and drop rows whose id you already have. Stop when a page has fewer than 100 rows.
  • Rows created after the cut-off are not included; take them in your next run.
  • Send one request at a time. On 429 wait for Retry-After, then 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.