IBM Cloud Docs
Pagination

Pagination

Pagination MAY be implemented by any collection and is often desirable to provide faster responses and smaller payloads to clients. Although not all collections are required to provide pagination, it SHOULD be implemented for any collection where an unbounded number of resources may be present.

If a collection supports pagination, a request to that collection's URL without any query parameters MUST return the first page of resources.[1]

Pagination and stable order

In order to ensure paginated collections have a stable order, the server MUST sort collections on a unique value by default and, if necessary, supplement any requested sorting with a sort on a unique value (typically a primary key).[2]

For example, if the client wishes to sort on last_name, and the last name is not guaranteed to be unique, the system could implicitly sort on last_name and then id (where id is unique).

Token-based pagination

Collections SHOULD implement token-based pagination wherever practical, but MAY implement offset and limit pagination when deemed necessary for collection use-cases.

Token-based pagination MUST support a page token query parameter, which SHOULD be named start but MAY be named token, for accepting a page token that specifies the resource to start the page on or after. The collection MAY also support the limit query parameter.

Page tokens MUST be string values and SHOULD be presented as opaque values. If it is impractical for page tokens to be opaque, clients SHOULD still be discouraged from generating their own tokens. Page tokens MUST have an enforced maximum length and that length SHOULD be documented and SHOULD be no more than 512 characters.

A request made using a page token from next, previous, or last MUST NOT affect the response of a subsequent request using the same page token.

If a page token is passed in the page token query parameter of a request, the service MUST fail the request if any other parameters of the request are not consistent with the page token.

Token-based pagination can be implemented in a number of ways (including keyset pagination or cursor-based pagination). However, any implementation of token-based pagination SHOULD attempt to ensure that resources are not duplicated or omitted [3] if all pages in a collection are requested in sequence.

Page token query parameter

The page token query parameter, which SHOULD be named start but MAY be named token, MUST be used to determine what resource to start the page on or after. If the page token query parameter is unspecified, the logical first page of results MUST be returned.

Page tokens SHOULD be provided to the client in the page token field, having the same name as the page token query parameter, of the next, previous, or last object in a collection.

Limit

The collection MAY support the limit query parameter, which MUST be an integer. When supported, the limit parameter MUST be used to determine the maximum number of resources returned. Further, the number of resources returned SHOULD be the same as limit except for the last page of the collection.

If limit is unspecified or unsupported by the collection, a default limit MUST be used. The default limit MUST be consistent across all requests to the collection. It should be determined for each collection based on a reasonable default request time and payload size. The default limit should be highlighted in the collection's documentation.

If limit is supported, a collection MUST impose a maximum value for the limit. The maximum limit MUST be consistent across all requests to the collection. The maximum limit should be determined for each collection based on reasonable maximums for request time and payload size. The maximum limit should be highlighted in the collection's documentation.

If the value provided for limit is not a positive integer or is greater than the maximum limit, the server SHOULD return a 400 status code and appropriate error response model.

Additional response fields

Collections using token-based pagination MUST return a page token field, having the same name as the page token query parameter, in any next, previous, and last fields whenever these are present according the conditions defined for Link-based pagination. The value of the page token field can be passed in the page token query parameter on a subsequent request to retrieve the next, previous, or last page of results, respectively.

There is no need for a page token field in first since the first page of results can be obtained by simply omitting the page token query parameter from the request.

If the limit query parameter is supported, the limit MUST be included in the collection response. The value for this field MUST be an integer, and MUST be included whether it was explicitly provided by the user or provided by a default.

A total_count field MAY also be included in the collection response. If present, this field MUST contain an integer representing the total number of resources in the collection (accounting for filtering, but not for paging). If it is expensive or impractical to provide a total_count value, the total_count field SHOULD be omitted.

Accuracy and consistency

If it is deemed critical that a client be able to retrieve all pages without any duplicated or omitted resources, one of two approaches MAY be implemented:

  1. Pagination MAY be performed across an ephemeral snapshot of the collection made with the first request and referenced by the token.[4] This approach guarantees that all pages in a paginated set represent the resources in the collection at the time of the initial request.
  2. A paginated collection MAY require that sorting be performed only on immutable fields, while each request is still made against live data. This approach guarantees that all resources that existed for the entire duration of paginated requests are neither omitted nor duplicated if all pages in a collection are requested in sequence.

Example token-based pagination response

{
  "limit": 50,
  "total_count": 232,
  "first": {
    "href": "https://api.example.com/v2/accounts?limit=50"
  },
  "next": {
    "href": "https://api.example.com/v2/accounts?start=3fe78a36b9aa7f26&limit=50",
    "start": "3fe78a36b9aa7f26"
  },
  "accounts": [
    ...
  ]
}

Offset and limit pagination

Offset and limit pagination MUST support two query parameters: offset and limit.

Offset

The offset parameter MUST be used to determine how many resources to skip over, given the order of the collection. If offset is unspecified, the response MUST be identical to the response where offset is explicitly provided as 0.

Any non-negative integer MUST be a valid value for the offset parameter. If the supplied offset is greater than or equal to the total number of resources present, the server MUST return an empty collection, and MUST NOT return an 400- or 500-series response code.

If the value provided for offset is not a non-negative integer, the server SHOULD return a 400 status code and appropriate error response model.

Limit

The limit parameter MUST determine how many resources are returned, unless the offset and limit are such that the response is the last page[5] of resources.

If limit is unspecified, a default limit MUST be used. The default limit MUST be consistent across all requests to the collection. It should be determined for each collection based on a reasonable default request time and payload size. The default limit should be highlighted in the collection's documentation.

A paginated collection MUST impose a maximum value for the limit. The maximum limit MUST be consistent across all requests to the collection.[6] The maximum limit should be determined for each collection based on reasonable maximums for request time and payload size. [7] The maximum limit should be highlighted in the collection's documentation.

If the value provided for limit is not a positive integer, or if the value provided is greater than the maximum value for the collection, the server SHOULD return a 400 status code and appropriate error response model.

Additional response fields

The fields offset and limit MUST be included in the collection response. The values for these fields MUST be integers, and MUST be included whether they were explicitly provided by the user or provided by defaults.

A total_count field SHOULD also be included in the collection response. If present, this field MUST contain an integer representing the total number of resources in the collection (accounting for filtering, but not for paging). If it is expensive or impractical to provide a total_count value, the total_count field MAY be omitted.

Example offset and limit pagination response

{
  "offset": 100,
  "limit": 50,
  "total_count": 232,
  "first": {
    "href": "http://api.example.com/v2/accounts?limit=50"
  },
  "last": {
    "href": "http://api.example.com/v2/accounts?offset=200&limit=50"
  },
  "previous": {
    "href": "http://api.example.com/v2/accounts?offset=50&limit=50"
  },
  "next": {
    "href": "http://api.example.com/v2/accounts?offset=150&limit=50"
  },
  "accounts": [
    ...
  ]
}

  1. That is, a paged collection should never return all resources if paging parameters are unspecified. ↩︎

  2. If the records returned in a paginated request have arbitrary ordering, the client has no assurance that a particular page corresponds to specific records. ↩︎

  3. There are two possible exceptions to this rule. First, if the resources are being ordered based on mutable fields, and the value of one or more of those fields changes for a particular resource in between page requests, it is acceptable for that resource to be duplicated or omitted as an artifact of that change. Second, if a resource is added to the collection after the initial request or removed prior to the final request, it is acceptable for it to be omitted from the complete set of pages. ↩︎

  4. Note that the token must still refer to a particular page of the snapshot such that multiple requests made with the same token yield the same results. ↩︎

  5. The "last page" is defined as the scenario where the sum of the supplied offset and limit is greater than the total number of resources in the collection. ↩︎

  6. That is, the maximum limit must not change based on any other request parameters; it may vary for different collections, but not for different request parameters on one collection. ↩︎

  7. Without a maximum limit, it may be possible for clients to (intentionally or not) inundate a system with prohibitively expensive requests. ↩︎