Links
📍

Cursor Pagination

Learn how to use cursor pagination to get all the data from Airstack queries.
Airstack uses cursor-based paginations to retrieve huge amounts of on-chain and off-chain data that is broken down into pages with a maximum of 200 objects returned in a single response.
If you're look on how to implement pagination using the Airstack SDKs in your application, click here.

How Does It Work?

Each response result from an API call is a page and is indicated by a cursor value.
Thus, in order to go to the next (or previous) page, you will need to get the cursor value for the next (or previous) page, which is provided in every Airstack GraphQL schema as pageInfo.nextCursor (or pageInfo.prevCursor):

Try Demo

https://app.airstack.xyz/query/gyvtfKZmiI
Show me all holders of @BoredApeYachtClub (Demo)

Code

Query
Response
query MyQuery {
TokenBalances(
input: {filter: {tokenAddress: {_eq: "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D"}}, blockchain: ethereum, limit: 200}
) {
TokenBalance {
owner {
identity
}
}
pageInfo {
hasNextPage # Booelan indicating if the next page of data exist
hasPrevPage # Booelan indicating if the previous page of data exist
nextCursor # cursor to next page (2nd page)
prevCursor # cursor to prev page
}
}
}
{
"data": {
"TokenBalances": {
// Token holders from the 1st page result
"TokenBalance": [
{
"owner": {
"identity": "0xbc8dd02976bdfbda4f4146a89445ee66e28806da"
}
},
{
"owner": {
"identity": "0xcafba4ca4a4886ae0938cc8ef91b605db9e4bf08"
}
},
{
"owner": {
"identity": "0xdbfd76af2157dc15ee4e57f3f942bb45ba84af24"
}
}
],
"pageInfo": {
// `hasNextPage`: indicate there exist the next page (2nd page)
"hasNextPage": true,
// `hasPrevPage`: indicate there is no previous next page
"hasPrevPage": false,
// `nextCursor`: Cursor for the next page (2nd page)
"nextCursor": "eyJMYXN0VmFsdWVzTWFwIjp7Il9pZCI6eyJWYWx1ZSI6IjEweGJjNGNhMGVkYTc2NDdhOGFiN2MyMDYxYzJlMTE4YTE4YTkzNmYxM2QweDMzYzFmZWZmYmY3MjE3ZDdiMjI0NGRjOTA1MWYwNGM0OTdhMDRhMDI1Nzc4IiwiRGF0YVR5cGUiOiJzdHJpbmcifSwibGFzdFVwZGF0ZWRUaW1lc3RhbXAiOnsiVmFsdWUiOiIxNjkyOTE4MTc5IiwiRGF0YVR5cGUiOiJEYXRlVGltZSJ9fSwiUGFnaW5hdGlvbkRpcmVjdGlvbiI6Ik5FWFQifQ==",
// `prevCursor`: Cursor for the prev page (empty for 1st page)
"prevCursor": ""
}
}
}
}
If pageInfo.nextCursor or pageInfo.prevCursor is returned as an empty string, then it implies that there is no more next or previous page, respectively.
Once you have the cursor for the next page, you can use the cursor value to retrieve data from the 2nd page by making another API call with the pageInfo.nextCursor value provided in the cursor input filter:

Try Demo

https://app.airstack.xyz/query/ypsxxeH9TC
Show me all holders of @BoredApeYachtClub on the 2nd page (Demo)

Code

Query
Response
query MyQuery {
TokenBalances(
input: {
filter: {
tokenAddress: {
_eq: "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D"
}
},
blockchain: ethereum,
limit: 200,
# Cursor of the 2nd page
cursor: "eyJMYXN0VmFsdWVzTWFwIjp7Il9pZCI6eyJWYWx1ZSI6IjEweGJjNGNhMGVkYTc2NDdhOGFiN2MyMDYxYzJlMTE4YTE4YTkzNmYxM2QweDMzYzFmZWZmYmY3MjE3ZDdiMjI0NGRjOTA1MWYwNGM0OTdhMDRhMDI1Nzc4IiwiRGF0YVR5cGUiOiJzdHJpbmcifSwibGFzdFVwZGF0ZWRUaW1lc3RhbXAiOnsiVmFsdWUiOiIxNjkyOTE4MTc5IiwiRGF0YVR5cGUiOiJEYXRlVGltZSJ9fSwiUGFnaW5hdGlvbkRpcmVjdGlvbiI6Ik5FWFQifQ=="
}
) {
TokenBalance {
owner {
identity
}
}
pageInfo {
hasNextPage
hasPrevPage
nextCursor
prevCursor
}
}
}
{
"data": {
"TokenBalances": {
// The token holders from the 2nd page result
"TokenBalance": [
{
"owner": {
"identity": "0xf15c93562bc3944a68e938ef75d2a3360d98ca57"
}
},
{
"owner": {
"identity": "0xdbfd76af2157dc15ee4e57f3f942bb45ba84af24"
}
},
{
"owner": {
"identity": "0xdbfd76af2157dc15ee4e57f3f942bb45ba84af24"
}
}
],
"pageInfo": {
// `hasNextPage`: indicate there exist the next page (3rd page)
"hasNextPage": true,
// `hasPrevPage`: indicate there exist the previous page (1st page)
"hasPrevPage": true,
// `nextCursor`: cursor to the next page (3rd page)
"nextCursor": "eyJMYXN0VmFsdWVzTWFwIjp7Il9pZCI6eyJWYWx1ZSI6IjEweGJjNGNhMGVkYTc2NDdhOGFiN2MyMDYxYzJlMTE4YTE4YTkzNmYxM2QweGIwZmZjNzhjODMyZDJjZjdmY2M2M2Y3OTIzOGZkZDcyMGI1Y2VlMzUxMDY0IiwiRGF0YVR5cGUiOiJzdHJpbmcifSwibGFzdFVwZGF0ZWRUaW1lc3RhbXAiOnsiVmFsdWUiOiIxNjkyNjM2MDIzIiwiRGF0YVR5cGUiOiJEYXRlVGltZSJ9fSwiUGFnaW5hdGlvbkRpcmVjdGlvbiI6Ik5FWFQifQ==",
// `prevCursor`: cursor to the prev page (1st page)
"prevCursor": "eyJMYXN0VmFsdWVzTWFwIjp7Il9pZCI6eyJWYWx1ZSI6IjEweGJjNGNhMGVkYTc2NDdhOGFiN2MyMDYxYzJlMTE4YTE4YTkzNmYxM2QweGYxNWM5MzU2MmJjMzk0NGE2OGU5MzhlZjc1ZDJhMzM2MGQ5OGNhNTc4NzYwIiwiRGF0YVR5cGUiOiJzdHJpbmcifSwibGFzdFVwZGF0ZWRUaW1lc3RhbXAiOnsiVmFsdWUiOiIxNjkyOTE1NjExIiwiRGF0YVR5cGUiOiJEYXRlVGltZSJ9fSwiUGFnaW5hdGlvbkRpcmVjdGlvbiI6IlBSRVYifQ=="
}
}
}
}

Developer Support

If you have any questions or need help regarding how cursor pagination work, please join our Airstack's Telegram group.

More Resources