> This page is for Unified.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.merge.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.merge.dev/_mcp/server.

# Pagination

> Cursor-based pagination for list endpoints. Covers the next/previous cursor fields in responses and how to page through large result sets.

---

## Overview

Any data you interact with via the Merge API is able to be paginated. Pagination is specified via the `cursor` and `page_size` query parameters. Ensure that all query parameters, aside from `cursor` and `page_size`, remain consistent across pagination to maintain the integrity of your data retrieval. The `next` and `previous` cursors are attached to paginated API responses. Their values inform the `cursor` where to point to next.

---

## Query parameters

| Parameter   | Type    | Description                                                                                                                                                                                                                                                                          |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `cursor`    | String  | Denotes the starting position in the data list from where a paginated API endpoint should return bulk data. Get this value from the `next` or `previous` property of any previous paginated response. When `next` or `previous` is null there are no more pages to paginate through. |
| `page_size` | Integer | Limit on number of objects to return per request. Defaults to 30, maximum of 100.                                                                                                                                                                                                    |

## Sample HTTP request

Below is an sample request using pagination in `HTTP`. The `page_size` is set to 20, and the `cursor` is pointing to a value for the next page.

```

GET /api/ats/candidates?page_size=20&cursor=cD0yMDIxLTA3LTI4KzE5JTNBMzglM0EzNi42NzUxNTMlMkIwMCUzQTAw 
X-Account-Token: {Linked Account Token Here}
Authorization: Bearer {Production API Key Here}
```

---

## Getting the cursor

In the response payload of an API request to a paginated endpoint, you can find `next` and `previous` cursors.

**`Paginated API Response Payload`**

```json Paginated API Response Payload
{
  "next": "cD0yMDIxLTAxLTA2KzAzJTNBMjQlM0E1My40MzQzMjYlMkIwMCUzQTAw",
  "previous": null,
  "results": [
      {...},
      {...},
      {...}
  ]
}
```

---

## Using the cursor

These cursors can be attached to future requests to paginated API endpoints to query the next (or previous) page of results, as demonstrated in the following code sample using the Merge SDK:

```python
# See SDK docs for configuration information
import merge
from merge.client import Merge

merge_client = Merge(api_key="<YOUR_API_KEY>", account_token="<YOUR_ACCOUNT_TOKEN>")

cursor = ""

while cursor != None:
    try:
        next_employees_page = merge_client.hris.employees.list(next=cursor)
        pprint(next_employees_page)
        cursor = next_employees_page.next
    except Exception as e:
        print("Exception when calling EmployeesApi->employees_list: %s" % e)
```

```ruby
MergeATSClient.configure do |config|
  # See SDK docs for configuration information
end
x_account_token = 'END_USER_ACCOUNT_TOKEN'
api_instance = MergeATSClient::CandidatesApi.new
begin
  cursor = ''
  while cursor
    result = api_instance.candidates_list(x_account_token, { cursor: cursor })
    cursor = result._next
    puts result
  end
rescue MergeATSClient::ApiError => e
  puts "Exception when calling CandidatesApi->candidates_list: #{e}"
end
```

**`Node`**

```javascript Node
const getEmployees = (cursor) => {
  apiInstance.employeesList(xAccountToken, { cursor: cursor }, (error, data) => {
    if (error) {
      console.error(error);
    } else {
      console.log(data);
      if (data.next) {
        getEmployees(data.next);
      }
    }
  });
};

getEmployees(null);
```

```java
import merge_ats_client.ApiClient;
import merge_ats_client.ApiException;
import merge_ats_client.Configuration;
import merge_ats_client.api.CandidatesApi;
import merge_ats_client.auth.ApiKeyAuth;
import merge_ats_client.model.PaginatedCandidateList;

public class MergePagination {
    public void paginateViaSDK() {
        MergeApiClient mergeClient = MergeApiClient.builder()
            .accountToken("ACCOUNT_TOKEN")
            .apiKey("API_KEY")
            .build();

        String cursor = "";
        while(cursor != null) {
            try {
                Candidate candidate = mergeClient.ats().candidates().list( 
                    RequestOptions.builder()
                        .accountToken("OVERRIDE_ACCOUNT_TOKEN")
                        .cursor(cursor)
                        .build());
                cursor = candidate.getNext();
            } catch (ApiException e) {
                System.out.println("Exception when calling CandidatesApi->candidate_list:" + e);
                break;
            }
        }
    }
}
```

If you don't want to use the Merge SDK and want to form your own API requests instead, you can do so as illustrated below:

```python
import requests

endpoint_url = "https://api.merge.dev/api/hris/companies"

headers = {"Accept": "application/json", "Authorization": "Bearer YOUR_API_KEY", "X-Account-Token": "END_USER_ACCOUNT_TOKEN"}
response = requests.request("GET", endpoint_url, headers=headers)
print(response.json()["results"])
cursor = response.json()["next"]

while cursor:
    page_url = f"{endpoint_url}?cursor={cursor}"
    response = requests.request("GET", page_url, headers=headers)
    print(response.json()["results"])
    cursor = response.json()["next"]
```

```ruby
require 'httparty'
require 'json'

cursor = ''
url = 'https://api.merge.dev/api/hris/companies'
headers = {
  'Authorization' => "Bearer YOUR_API_KEY",
  'X-Account-Token' => 'END_USER_ACCOUNT_TOKEN'
  'Accept' => 'application/json',
}

while cursor:
  query = {
    'cursor' => cursor,
  }
  response = HTTParty.get(url, query: query, headers: headers)
  cursor = JSON.parse(request.body)["next"]
end
```

**`Node`**

```javascript Node
const axios = require("axios");

async function getEmployees(cursor) {
  const response = await axios.get("https://api.merge.dev/api/hris/employees" + (cursor ? "?cursor=" + cursor : ""), {
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "X-Account-Token": "END_USER_ACCESS_TOKEN",
    },
  });

  console.log(response.data);

  if (response.data.next) {
    getEmployees(response.data.next);
  }
}
```

```java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ManualPagination {

    public void printAllCandidates() {
        try {
            HttpClient client = HttpClient.newHttpClient();
            String cursor = fetchCandidate(client, null);

            while (cursor != null) {
                cursor = fetchCandidate(client, cursor);
            }

        } catch (IOException ioException) {
            System.out.println("IO Exception occurred during manual pagination fetch: " + ioException);
        } catch (InterruptedException interruptedException) {
            System.out.println("Interruption Exception occurred during manual pagination fetch: " + interruptedException);
        }
    }

    private String fetchCandidate(HttpClient client, String cursor) throws IOException, InterruptedException {

        String endpointUrl = "https://api.merge.dev/api/ats/candidates";
        endpointUrl = cursor != null ? String.format("%s?cursor=%s", endpointUrl, cursor) : endpointUrl;
        URI uri = URI.create(endpointUrl);

        HttpRequest request = HttpRequest.newBuilder(uri)
                .header("Accept", "application/json")
                .header("Authorization", String.format("Bearer %s", "YOUR_API_KEY"))
                .header("X-Account-Token", "END_USER_ACCOUNT_TOKEN")
                .build();
        HttpResponse<String> candidateResult = client.send(request, HttpResponse.BodyHandlers.ofString());

        ObjectNode parsableData = new ObjectMapper().readValue(candidateResult.body(), ObjectNode.class);
        System.out.println(parsableData.get("results").textValue());
        return parsableData.get("next").textValue();
    }
}
```