Pagination
There are two pagination modes. Cursor is the default on most list endpoints (items, monsters, quests, …): it is efficient because it leverages database indexes, but it does not report a total count. Page is offset-based and used by a smaller set of endpoints (patches, changelog, leaderboards); it reports a total count, which is convenient on smaller resources. Both accept an additional &limit=# parameter; each endpoint documents its own default and ceiling (the market caps at 50, most catalog lists at 250). Every paginated response carries a pagination block in the envelope with the request meta and the next cursor.
Cursor
Cursor pagination resumes where the previous request left off. Each response's pagination.next is the cursor for the next page — pass it straight back as &cursor=<next>. When next is null you have reached the end. Cursors are opaque (for most endpoints, the last row's id) — read them from the response rather than constructing them by hand.
Paged
Page-based endpoints accept &page=# and add page, num_pages, and total to the pagination block. Endpoints that don't support paging (most of the high-volume catalogs, e.g. /v2/items) ignore the parameter and report these fields as null.
On very large collections (/v2/market), total and num_pages are estimates once a result set exceeds ~50,000 rows. Smaller (e.g. filtered) result sets report exact counts.
Sort
sort is a global parameter on every list endpoint. Two forms:
- ?sort=<field>:<order> — sort by a named field, where order is asc or desc (e.g. ?sort=gear_score:desc).
- ?sort=asc / ?sort=desc — order only; sorts by the endpoint's default sort field in that direction.
Omitting sort uses the endpoint's default field and order. The sortable fields are per-endpoint — most catalogs sort on id only, while richer lists add a sensible few (items: gear_score; monsters: max_health, adventure_points; market: price, price_per_unit, created_at). An unknown field returns 400. Cursor pages stay correct under any sort — the cursor encodes the (sort value, id) pair so there are no duplicates or gaps. Offset endpoints also take comma-separated multi-field sorts (price:asc,created_at:desc — later terms break ties); cursor endpoints take a single term, and every term must name a field — a bare asc/desc is a 400.