Pagination
Cursor pagination (lists)
List endpoints – keys, audit log, conversions, leads, sync runs, ad entities, events – return a page and an opaque cursor:
{ "data": [ … ], "nextCursor": "eyJhdCI6IjIwMjYtMTAtMTRUMTI6MDA6MDBaIiwiaWQiOiI…" }Pass it back unchanged to get the next page; nextCursor: null means there is nothing more.
curl -H "Authorization: Bearer $X3_SECRET_KEY" \
"https://api.3x.example/v1/projects/my-site/conversions?limit=100&cursor=eyJhdCI6…"limitdefaults per endpoint (usually 50) and is capped (usually 200); the reference lists both.- Cursors are stable under inserts: new rows never shift a page you are reading.
- Do not build cursors yourself – their format may change. An invalid cursor is a 400
bad_request. - Keep the other parameters identical between pages; a cursor is only meaningful for the filter that produced it.
Offset pagination (sessions explorer)
GET /v1/projects/{project}/sessions mirrors the dashboard's sessions explorer: it sorts by any
column (sort, dir), so it uses limit (≤ 200) and offset (≤ 100 000) and returns
nextOffset. For exports beyond 100 000 sessions narrow the date range and page through it day by
day, or use POST /v1/projects/{project}/sql for aggregates.
Aggregates
Analytics endpoints (…/analytics/*) return complete aggregates for the filter and are not paged.
Breakdowns take limit (≤ 200) and min_sessions; the rows beyond the limit are summed into an
other row where the endpoint says so, so totals always add up.