Pagination
List endpoints return a consistent pagination envelope and support two modes of paging: shallow offset paging and deep cursor enumeration.
The envelope
Section titled “The envelope”{ "list": [], "totalSize": 0, "offset": 0, "pageSize": 25}| Field | Meaning |
|---|---|
list | the page of rows |
totalSize | estimated total matching rows (see the cap below) |
offset | the offset this page started at |
pageSize | the effective page size for this page |
Profile list responses additionally carry bucket, identities, scope, and
nextCursor; events responses carry nextCursor. See each endpoint page for the exact
shape.
Page size
Section titled “Page size”?limit=controls page size. Default 25, hard maximum 100. A request above 100 is clamped down to 100 (not rejected).- Non-numeric or negative values floor to the default.
Offset paging (shallow)
Section titled “Offset paging (shallow)”-
?offset=sets the starting offset.offset + limitmust stay inside the OpenSearch result window of 10,000. -
A deep offset whose page would cross the window is rejected with
400and a pointer to the cursor — it is not silently clamped (clamping would return the wrong rows):{"error": "bad_request","error_description": "offset too deep: offset + limit must not exceed 10000 (the OpenSearch result window). To enumerate beyond the window, omit ?offset and paginate with the ?cursor token returned as nextCursor in each response (deep-pagination cursor)."}
Cursor enumeration (deep)
Section titled “Cursor enumeration (deep)”To enumerate an entire result set past the 10k window (billing-grade enumeration), switch
from ?offset= to the opaque ?cursor= token.
- Each response returns
nextCursor— an opaque, scope-bound token for the next page, ornullwhen enumeration is exhausted (a short page means the walk is done). - Pass it back as
?cursor=<token>to continue. Keep going untilnextCursorisnull, regardless oftotalSize. - The cursor requires the stable
itemId.keyword:ascsort (the default). An explicit non-stable?sortis honoured for ordering but makes the page offset-only — no cursor is minted, and you stay inside the 10k window. To enumerate the full set, use the default sort. - A cursor is bound to the brand scope it was minted under (and, for events, to the
profile). Presenting another brand’s cursor returns
403; presenting a profiles cursor to an events endpoint (or a different profile) returns400.
The totalSize cap
Section titled “The totalSize cap”totalSize is the OpenSearch result-window estimate, capped at 10,000 — it is not
the true total of a larger set. When paginating with the cursor, do not rely on
totalSize: enumerate until nextCursor is null.