API Pagination Guidelines¶
Introduction¶
Without pagination, a simple search could return millions or even billions of records. Most endpoints that return a list of entities need to support some form of pagination. A server MAY choose to limit the number of resources returned in a response to a subset ("page") of the whole set available.
Pagination links [600]¶
A server MAY provide links to traverse a paginated data set ("pagination links").
Pagination links SHOULD appear in the top-level links
object.
Pagination links MUST preserve sorting and filtering.
If pagination links are used, then the naming conventions for the link names (keys) MUST be followed:
first
: the first page of datalast
: the last page of dataprev
: the previous page of datanext
: the next page of data
Here is an example with a pagination key.
{
"links": {
"next": "https://api.bx.com/buildings?cursor=cXdlcnR5"
},
"data": [
{
"id": "12345",
"type": "Building",
...
}
...
]
}
Pagination strategies [601]¶
Pagination SHOULD be implemented using query parameters. The following topics describe different pagination strategies.
Cursor based strategy [601.1]¶
Cursor-based pagination is useful for server implementations based on NoSQL databases or when backends join data from multiple data sources.
When using cursor-based pagination, the following two parameter names SHOULD be used:
cursor
is an opaque identifier that only the server understands.limit
is used for the requested maximum page size.
The server MAY return an empty page containing a next
-link if that is necessary for scalability and performance reasons.
GET /buildings HTTP/1.1
{
"links": {
"self": "https://api.bx.com/buildings",
"next": "https://api.bx.com/buildings?cursor=cXdlcnR5"
},
"data": [
{
"id": "12345",
"type": "Building",
...
}
...
]
}
GET /buildings?cursor=cXdlcnR5&limit=50 HTTP/1.1
{
"links": {
"self": "https://api.bx.com/buildings?cursor=cXdlcnR5&limit=50"
},
"data": [
{
"id": "45678",
"type": "Building",
...
}
...
]
}
Server MAY provide pagination meta information to the API client [601.1.1]¶
The server MAY provide information about the nextCursor
that is required to fetch the next page in the meta.page.nextCursor
property. It should be a string.
{
"meta": {
"page": {
"nextCursor": "cXdlcnR5"
}
}
}
Offset based strategy [601.2]¶
Offset-based pagination MAY be used for servers that can skip records efficiently while also calculating the total number of records, such as SQL-based services.
When using offset-based pagination, the following two parameter names SHOULD be used:
offset
is an integer representing the elements of records to skip when responding.limit
is used for the requested maximum page size.
GET /buildings?limit=100 HTTP/1.1
{
"links": {
"self": "https://api.bx.com/buildings?limit=100",
"next": "https://api.bx.com/buildings?limit=100&offset=100"
},
"meta": {
"page": {
"totalElements": 101,
"offset": 0,
"elements": 100
}
},
"data": [
{
"id": "12345",
"type": "Building",
...
}
...
]
}
GET /buildings?limit=100&offset=100 HTTP/1.1
{
"links": {
"self": "https://api.bx.com/buildings?limit=100&offset=100"
},
"meta": {
"page": {
"totalElements": 101,
"offset": 100,
"elements": 1
}
}
"data": [
{
"id": "45678",
"type": "Building",
...
}
]
}
Server MAY provide pagination meta information to the API client [601.2.1]¶
The following meta information SHOULD be used:
meta.page.totalElements
total number of elements.meta.page.offset
current offset.meta.page.elements
number of records in the current page.
The meta information can be useful for rendering custom paging controls in the API client, for example, in a "data grid" or table where the user wants to skip to an arbitrary page.
{
"meta": {
"page": {
"totalElements": 101,
"offset": 100,
"elements": 1
}
}
}
Index based strategy [601.3]¶
Index-based pagination MAY be used for servers that can skip records efficiently while also calculating the total number of records, such as SQL based services. It is similar to offset-based pagination but is commonly used when page sizes are not flexible.
When using index-based pagination, the following two parameter names SHOULD be used:
number
is an integer representing the page-number to fetch.size
is used for the requested maximum page size.
GET /buildings?size=100 HTTP/1.1
{
"links": {
"self": "https://api.bx.com/buildings?size=100",
"next": "https://api.bx.com/buildings?size=100&number=2",
"last": "https://api.bx.com/buildings?size=100&number=3",
"first": "https://api.bx.com/buildings?size=100"
},
"meta": {
"page": {
"totalPages": 3,
"number": 1,
"elements": 100
}
}
"data": [
{
"id": "12345",
"type": "Building",
...
}
...
]
}
GET /buildings?size=100&number=3 HTTP/1.1
{
"links": {
"self": "https://api.bx.com/buildings?size=100&number=3",
"last": "https://api.bx.com/buildings?size=100&number=3",
"first": "https://api.bx.com/buildings?size=100",
"prev": "https://api.bx.com/buildings?size=100&number=2"
},
"meta": {
"page": {
"totalPages": 2,
"number": 3,
"size": 100,
"elements": 1
}
},
"data": [
{
"id": "45678",
"type": "Building",
...
}
]
}
Server MAY provide pagination meta information to the API client [601.3.1]¶
The following meta information SHOULD be used:
meta.page.totalPages
is an integer representing the total number of pages.meta.page.number
is an integer representing the current page number.meta.page.size
is an integer representing the page size.
The following meta information MAY be used:
meta.page.elements
is an integer representing the number of records returned in the current page.meta.page.totalElements
is an integer representing the total number of elements.
The meta information can be useful for rendering custom paging controls in the API client, such as in a "data grid" or table where the user wants to skip to an arbitrary page.
{
"meta": {
"page": {
"totalPages": 2,
"number": 2,
"size": 100,
"elements": 1,
"totalElements": 101
}
}
}
Note
JSON:API introduces query parameter families. When using JSON:API, query parameters like page[number]
and page[size]
should be used instead of just number
and size
. Then the parameters are compliant with the JSON:API pagination specification. But the names within the square brackets like number
and size
must comply with this guideline.