Note: Beginning August 15, 2023, offset-based pagination requests over the first 10,000 records (100 pages) will result in a “400 Bad Request” error message. For more information, see New limits for offset-based pagination.

The Support API has several endpoints that return lists of items, such as tickets and users. This article explains how to paginate through the lists.

For bandwidth reasons, the API doesn't return large record sets all at once. It breaks up the results into smaller subsets and returns them in pages. The number of items per page varies by endpoint. The tickets and users endpoints return 100 items per page while the articles endpoint returns 30 items per page.

You must paginate through the results to get all the data. This article explains how basic pagination works.

The pagination methods discussed in this article are supported by following Zendesk APIs:

  • Support API
  • Help Center API
  • Talk API

The pagination details of other APIs might be different but the logic is the same.

See also Pagination in the Introduction of the Zendesk REST API documentation.

Disclaimer: Zendesk provides this article for instructional purposes only. Zendesk does not support or guarantee the code. Zendesk also can't provide support for third-party technologies such as Python and Perl.

Choosing a pagination method

The Support API has two pagination methods: cursor-based and offset-based.

  • In cursor-based pagination, Zendesk uses a pointer in the recordset to keep track of the next record. The pointer moves in the recordset like the cursor in a text editor indicating where the next words you type will appear. Zendesk paginates based on the position of the pointer in the recordset.

  • In offset-based pagination, Zendesk keeps a record count and "turns the page" after reaching a specific number of records (the offset number).

Zendesk recommends using cursor-based pagination when it's available. It's currently available only for certain list endpoints in the Support API, including List Tickets and List Users. If the API documentation for a specific list endpoint doesn't specify that cursor-based pagination is available, then the resource only supports offset-based pagination.

See also Understanding the limitations of offset pagination.

Adding pagination with the cursor-based method

By default, the pagination method for all list endpoint is the offset method. The cursor-based pagination method is supported by certain list endpoints in the Support API. Examples include List Tickets and List Users. If the API documentation for a specific list endpoint doesn't specify that cursor-based pagination is available, then the resource only supports offset-based pagination.

When using this method, requests return a meta object and links object along with the list of requested records. The links object has a next property with the URL of the next page of results, if any. Example:

"users": [ ... ],"meta": {  "has_more": true,  "after_cursor": "eyJvIjoibmljZV9pZCIsInYiOiJhV2tCQUFBQUFBQUEifQ==",  "before_cursor": "eyJvIjoibmljZV9pZCIsInYiOiJhUzRCQUFBQUFBQUEifQ=="},"links": {  "next": "https://example.zendesk.com/api/v2/users.json?page[size]=100&page[after]=eyJvIjoibmljZV9pZCIsInYiOiJhV2tCQUFBQUFBQUEifQ==",  "prev": "https://example.zendesk.com/api/v2/users.json?page[size]=100&page[before]=eyJvIjoibmljZV9pZCIsInYiOiJhUzRCQUFBQUFBQUEifQ=="}...

Note: The url values in the example will be url-encoded in actual use.

To use cursor-based pagination, you must include a page[size] query parameter. Example:

https://example.zendesk.com/api/v2/users.json?page[size]=100

The following pseudo code is a common pattern for paginating through items with cursor-based pagination:

url = 'https://example.zendesk.com/api/v2/users.json?page[size]=100'while url is not nothing:    response = request(url)    // do something with the response    if response('meta.has_more') is true:        url = response('links.next')    else:        url = nothing

Keep paginating until the has_more property in the meta object is false then stop. Note that if you happen to specify a page[size] that is exactly the number of results, the has_more property in the meta object will be true.

Python example

Here's a Python example that uses the third-party requests library:

auth = f'{ZENDESK_USER_EMAIL}/token', ZENDESK_API_TOKENurl = 'https://example.zendesk.com/api/v2/tickets.json?page[size]=100'
while url:    response = requests.get(url, auth=auth)    data = response.json()    for ticket in data['tickets']:        print(ticket['id'])
    if data['meta']['has_more']:        url = data['links']['next']    else:        url = None

Adding pagination with the offset method

The offset-based pagination method is supported by all list endpoints in the Support, Help Center, and Talk APIs.

Note: Beginning August 15, 2023, offset-based pagination requests over the first 10,000 records (100 pages) will result in a “400 Bad Request” error message. In order to request data sets larger than 10,000 records, you must use cursor-based pagination. We strongly suggest you use cursor-based pagination regardless of the number of records.

By default, the JSON objects returned by list endpoints contain a next_page property with the URL of the next page of results, if any. Example:

"users": [ ... ],"next_page": "https://example.zendesk.com/api/v2/users.json?page=2",...

If there's no next page, the value is null.

"users": [ ... ],"next_page": null,...

Your code should check the next_page property when it calls any list endpoint. If null, it can move on. If not null, it should make another request using the specified URL.

The following pseudo code is a common pattern for paginating through items:

url = 'https://example.zendesk.com/api/v2/users.json'while url is not nothing:    response = request(url)    // do something with the response    url = response('next_page')

Don't wait too long between next page requests because the real-time nature of the data could introduce inaccuracies in the pagination results. See Understanding the limitations of offset pagination.

Python example

Here's a Python example that uses the third-party requests library:

url = 'https://example.zendesk.com/api/v2/help_center/sections/200646/articles.json'while url:    response = requests.get(url)    data = response.json()    for article in data['articles']:        print(article['title'])    url = data['next_page']

After getting and processing the first page of results, the script checks the value of the next_page property. If the value is null, which Python considers false, the loop stops.