Skip to content

Pagination

List endpoints return a consistent pagination envelope and support two modes of paging: shallow offset paging and deep cursor enumeration.

{
"list": [],
"totalSize": 0,
"offset": 0,
"pageSize": 25
}
FieldMeaning
listthe page of rows
totalSizeestimated total matching rows (see the cap below)
offsetthe offset this page started at
pageSizethe 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.

  • ?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= sets the starting offset. offset + limit must stay inside the OpenSearch result window of 10,000.

  • A deep offset whose page would cross the window is rejected with 400 and 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)."
    }

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, or null when enumeration is exhausted (a short page means the walk is done).
  • Pass it back as ?cursor=<token> to continue. Keep going until nextCursor is null, regardless of totalSize.
  • The cursor requires the stable itemId.keyword:asc sort (the default). An explicit non-stable ?sort is 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) returns 400.

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.