Pagination
Roblox endpoints have multiple methods of pagination. This article will outline all of those methods and how to use them.
Cursor-based[edit | edit source]
Cursor-based pagination is where the endpoint takes in a cursor
and limit
parameter and returns data
, previousPageCursor
, and nextPageCursor
.
Here's an example of some response data from https://users.roblox.com/v1/users/search?keyword=Roblox&limit=10
:
{
"previousPageCursor": null,
"nextPageCursor": "3f71b6",
"data": [...]
}
To advance the page, we can take the cursor passed in the nextPageCursor
and pass it as a query parameter, then send the request again, like so:
https://users.roblox.com/v1/users/search?keyword=Roblox&limit=10&cursor=3f71b6
{
"previousPageCursor": "017bf6",
"nextPageCursor": "68df08",
"data": [...]
}
As you can see, we now have a previousPageCursor
, which we can use to move to the previous page:
https://users.roblox.com/v1/users/search?keyword=Roblox&limit=10&cursor=017bf6
{
"previousPageCursor": null,
"nextPageCursor": "92653a",
"data": [...]
}
Base64-encoded cursors[edit | edit source]
Some endpoints, like the one provided above, have Base64-encoded cursors. To test it out, go to https://users.roblox.com/v1/users/search?keyword=Roblox&limit=10
and copy the nextPageCursor
, then decode it as Base64. The resulting data will look like this:
{
"startIndex": 10,
"discriminator": "keyword:Roblox",
"count": 10
}
49bf38d601c7e6c89487af8bf51680663a4dfbeabb9324dbe335868881d3d671
As you can see, the cursor contains data about how data should be sent - including the original keyword discriminator passed to the endpoint, the start index, and the item count.
It also has this unique hash at the end - that's there to make this cursor unique.
Some endpoints, like https://badges.roblox.com/v1/users/2/badges?limit=10&sortOrder=Asc
, return cursors with even more data:
{
"key": {
"id": 94278219,
"awardDateTime": "2012-10-05T15:40:50.57Z"
},
"sortOrder": "Asc",
"pagingDirection": "Forward",
"pageNumber": 2,
"discriminator": "userId:2",
"count": 10
}
9c7bdcc882bb584620bf5ffd0df0eb12a298ca6e86574d53e4e6790e609fc45a
This cursor actually provides a sample of the data, the paging direction, the sort order, the page number, a unique discriminator containing the passed user ID, and the item count. Some of this data isn't something you can directly control via parameters, so this is a useful trick to learn more about your cursors and page data.
Here's an example of a cursor debugger that uses ro.py v1.x: https://gist.github.com/jmkd3v/cc53b48ccc2bf8a35a39cc4fdc9b28f3
Plain cursors[edit | edit source]
Some endpoints, like https://catalog.roblox.com/v1/users/1/bundles?sortOrder=Desc&limit=10
, return plain cursors. Here's some example data from that endpoint:
{
"previousPageCursor": null,
"nextPageCursor": "355290604_1_68f63a9c6a034d4d844b54bc7a694a14",
"data": [...]
}
This cursor has three components. The first one is some sort of unique identifier, the second one is the paging order (1 for Forward and 2 for Backwards), and the third one is a unique hash. You can see the page order component in action if you pass a cursor:
{
"previousPageCursor": "355290600_2_8d4328db75015faa465ab42ba6002cb6",
"nextPageCursor": "355290595_1_69e6032003ee1a67d54dc23252fe4605",
"data": [...]
}
As you can see, the previousPageCursor
has a value of 2, indicating a reverse order.
Static cursors[edit | edit source]
Another interesting thing is that plain cursor endpoints return static cursors. These static cursors never change unless the limit, order or cursor parameter is modified. To give you an example of what this means, a request to https://games.roblox.com/v1/games/606849621/servers/Public?sortOrder=Asc&limit=100
will always have a nextPageCursor
with a value of 100_1_6db4aa61b36f59d5977f0bd0cf5d9a9c.
This could be useful for finding a specific page of an endpoint without being rate limited, since you would be able to store these cursors anywhere for later usage. Another example is that the cursor of the 4th page of the endpoint above, will always be: 300_1_31128e077b81c0311d58678baaac292c. The previousPageCursor
and nextPageCursor
of https://games.roblox.com/v1/games/606849621/servers/Public?sortOrder=Asc&limit=100&cursor=300_1_31128e077b81c0311d58678baaac292c
will always be 200_2_77659228ff52c4abdb3e2a7dd3a16d4e and 400_1_c7c4637011cc3912611f2908771fb301 respectively.