The chat responses are generated using Generative AI technology for intuitive search and may not be entirely accurate. They are not intended as professional advice. For full details, including our use rights, privacy practices and potential export control restrictions, please refer to our Generative AI Service Terms of Use and Generative AI Service Privacy Information. As this is a test version, please let us know if something irritating comes up. Like you get recommended a chocolate fudge ice cream instead of an energy managing application. If that occurs, please use the feedback button in our contact form!
Skip to content

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 data
  • last : the last page of data
  • prev : the previous page of data
  • next : the next page of data

Here is an example with a pagination key.

Example: A list of buildings with a "next" link
{
  "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.

Example: Initial request to fetch buildings, where the server implement the cursor based strategy
GET /buildings HTTP/1.1
Example: Response of first request, including next-link
{
  "links": {
    "self": "https://api.bx.com/buildings",
    "next": "https://api.bx.com/buildings?cursor=cXdlcnR5"
  },
  "data": [
    {
      "id": "12345",
      "type": "Building",
      ...
    }
    ...
  ]
}
Example: Following next-link to fetch second page of buildings
GET /buildings?cursor=cXdlcnR5&limit=50 HTTP/1.1
Example: Response of second request limited to 50 resources, this is the last set of resources as there is no next-link anymore
{
  "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.

Example: Pagination meta-information
{
  "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.
Example: Initial request to fetch buildings, where the server implement the offset based strategy
GET /buildings?limit=100 HTTP/1.1
Example: Response of first request, including next-link
{
  "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",
      ...
    }
    ...
  ]
}
Example: Following next-link to fetch second page of buildings
GET /buildings?limit=100&offset=100 HTTP/1.1
Example: Response of second request, this is the last set of resources as there is no next-link anymore
{
  "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.

Example: Pagination meta-information
{
  "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.
Example: Initial request to fetch buildings, where the server implement the Index based strategy
GET /buildings?size=100 HTTP/1.1
Example: Response of first request, including next-link, first-link as well as last-link
{
  "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",
      ...
    }
    ...
  ]
}
Example: Following next-link as second, subsequent request to fetch third page of buildings
GET /buildings?size=100&number=3 HTTP/1.1
Example: Response of second request, this is the last page as there is no next-link
{
  "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.

Example: Pagination meta-information
{
  "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.