Skip to main content

Pagination

List queries (orders, repaymentRequests, paymentExternalTransactions, a brand's products, …) return connections: paginated lists that expose the items together with the metadata needed to walk the pages.

Two facts cover most needs:

  • Pages hold at most 20 items: 20 is both the default and the maximum page size, so requesting first: 50 still returns 20.
  • To fetch the next page, pass the previous response's pageInfo.endCursor as the after argument, until hasNextPage is false.

Connection fields

  • nodes: the items of the page. Use this unless you need per-item cursors.
  • edges: the items wrapped with their cursor, useful to resume from a specific item.
  • pageInfo: startCursor, endCursor, hasNextPage, hasPreviousPage.
  • totalCount: the number of items matching the query, capped at 1001 for performance reasons: a value of 1001 means "1001 or more". The cap applies to every connection, including nested ones (e.g. a brand's products.totalCount).
  • totalPageCount: the number of pages, computed from the (capped) totalCount and the page size.

Cursors are opaque: always use a cursor read from a previous response (their format may change over time), never build one yourself. Pages can also be walked backwards with last and before, using pageInfo.startCursor.

Example

The first page, with first: 3 to keep the response short (omit it to get the default 20 items). Note that hasPreviousPage is false, and that totalCount is capped at 1001 because no filter was set. The top-level extensions are the usual rate limiting metadata.

Request
query ordersFirstPage {
orders(first: 3) {
totalPageCount
totalCount
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
edges {
cursor
node {
id
}
}
}
}
Response
{
"data": {
"orders": {
"totalPageCount": 334,
"totalCount": 1001,
"pageInfo": {
"startCursor": "WzQ1OTZd",
"endCursor": "WzQ1OTld",
"hasNextPage": true,
"hasPreviousPage": false
},
"edges": [
{ "cursor": "WzQ1OTZd", "node": { "id": "4596" } },
{ "cursor": "WzQ1OTdd", "node": { "id": "4597" } },
{ "cursor": "WzQ1OTld", "node": { "id": "4599" } }
]
}
},
"extensions": {
"queryComplexity": 18,
"bucketBalance": 9982,
"bucketRestoreRate": 100
}
}

The second page: pass the previous endCursor as after. Now hasPreviousPage is true.

Request
query ordersSecondPage {
orders(first: 3, after: "WzQ1OTld") {
totalPageCount
totalCount
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
edges {
cursor
node {
id
}
}
}
}
Response
{
"data": {
"orders": {
"totalPageCount": 334,
"totalCount": 1001,
"pageInfo": {
"startCursor": "WzQ2MDFd",
"endCursor": "WzQ2MDNd",
"hasNextPage": true,
"hasPreviousPage": true
},
"edges": [
{ "cursor": "WzQ2MDFd", "node": { "id": "4601" } },
{ "cursor": "WzQ2MDJd", "node": { "id": "4602" } },
{ "cursor": "WzQ2MDNd", "node": { "id": "4603" } }
]
}
},
"extensions": {
"queryComplexity": 18,
"bucketBalance": 9964,
"bucketRestoreRate": 100
}
}