Skip to main content
The total result set for a query may exceed the maximum number of items allowed in a single response. This limit is typically 100 items by default but can be increased to up to 1000 items in most cases by providing a value for the limit query parameter. If the number of items matching the query (see filtering syntax) is greater than the limit, the response object’s has_more property will have the value true and the next property will be a string which is the API URI providing the next “page” of items for the same query. These properties can be used to easily and efficiently traverse the full result set one page at a time without missing items or traversing the same item twice as can happen when using offsets due to race conditions. The following pseudo-code example demonstrates how you can traverse a full result set one page at a time using has_more and next properties of the response:

Previous Page

Similarly to next, a previous property is included in the response when the result has a previous page. This can be used to traverse backwards in a result set. When traversing backwards (which uses cursor_end) the has_more property in the response will be false when there are no more pages in the “previous” direction.

Metadata

The query parameters cursor_start and cursor_end are used to implement the basic paging mechanism, but these parameters are specified automatically in the URI which is returned in the next and previous properties respectively and so do not need to be provided manually. However, the appropriate values of these fields for the next and previous pages of results are also returned in the response’s meta object with the properties cursor_start and cursor_end respectively. These can be used in case you prefer or need to construct the URIs for paging on your own.

Count

If the query includes count=1 then the meta object will also include a total count which can be useful for predicting the total number of pages in a query result. The count is not included by default since in some edge cases it can have an impact on performance and is many times not required by the implementation.

Paging Sorted Results

Paging works with any supported sort order (see sorting syntax), and the shape of the cursor depends on the sort:
  • For collections ordered by id (the default on most endpoints), cursors are plain record ids — integers, as shown in the examples below.
  • For any other sort order, cursors are opaque tokens which identify the boundary row’s position in the sorted result. Treat them as black boxes: follow the next/previous URIs or pass the meta values back verbatim.
Cursors are point-in-time: they identify a position in the sort order, not a snapshot of the result set — rows inserted, removed, or re-ordered after a page was fetched are reflected on subsequent pages. A cursor token is bound to the sort order it was created for. Reusing it with a different sort value returns a 400 error (Cursor does not match the requested sort.). A plain record id is also accepted as a cursor for a sorted collection and resumes from that record’s position in the sort order; if the record no longer exists, the response is a 400 error (The record referenced by the cursor no longer exists.).
For bulk exports and synchronization jobs, explicitly request sort=id: it is backed by the primary key index and provides the fastest, most stable walks. Some endpoints default to a different sort order, and sorting large collections by fields other than id can require the server to re-sort the collection for every page.

Example

First page:
Request
Response
Second page:
Request
Response

Sorting

See sorting syntax for more info on sorting the result set.