Pagination
LATEST
AI Tools
Open in ChatGPT
Open in ChatGPT to ask questions about this page
Open in Claude
Open in Claude to ask questions about this page
Copy as Markdown
Copy this page as markdown to use with AI assistants
View as Markdown
Open this page as markdown in a new tab
Open in ChatGPT
Open in ChatGPT to ask questions about this page
Open in Claude
Open in Claude to ask questions about this page
Copy as Markdown
Copy this page as markdown to use with AI assistants
View as Markdown
Open this page as markdown in a new tab
The Zoho Cliq REST API v3 uses cursor-based pagination on all list endpoints. Pagination is standardized across modules using a consistent two-token model:
next_token: Fetch the next page of results.sync_token: Fetch only records created or modified since your last request.
Both tokens are returned in the response body. Use them exactly as returned—do not construct or modify them.
next_token → pagination (fetch next page)sync_token → incremental sync (fetch changes only)
Pagination support by module
| Module | next_token | sync_token |
|---|---|---|
| Datastores | ✅ | ✅ |
| Chats | ✅ | N/A |
| Threads | ✅ | N/A |
| Pin Messages | ✅ | ✅ |
| Messages (search) | ✅ | N/A |
| Functions | ✅ | ✅ |
| Widgets | ✅ | ✅ |
| Slash Commands | ✅ | ✅ |
| Message Actions | ✅ | ✅ |
| Schedulers | ✅ | N/A |
| Extensions (execution records) | ✅ | N/A |
next_token: Page through results
Use next_token to iterate through large result sets. Pass the token from the previous response to fetch the next page. When next_token is absent from the response, you have reached the last page.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | Integer | Optional | Records per page. Defaults and maximums vary by endpoint. |
next_token | String | Optional | Cursor from the previous response. Omit on the first request. |
First request
Omit next_token to start from the beginning of the result set.
GET /api/v3/datastores?limit=20
Authorization: Zoho-oauthtoken {access_token}
{
"url": "/api/v3/datastores",
"type": "datastore",
"data": [ ... ],
"next_token": "MTB8MTc3NzM2MDM5OTc0OXw=",
"sync_token": "MTB8MTc3NzM2MDM5OTc0OXw="
}
Next page
Pass next_token from the previous response to fetch the next batch of records.
GET /api/v3/datastores?limit=20&next_token=MTB8MTc3NzM2MDM5OTc0OXw=
Authorization: Zoho-oauthtoken {access_token}
{
"url": "/api/v3/datastores",
"type": "datastore",
"data": [ ... ],
"sync_token": "MTB8MTc3NzM2MDQwMzQ1NXw="
}
Fetch all records
Loop until next_token is absent. This example collects all datastores into a single array.
async function fetchAllDatastores(accessToken) {
let nextToken = null;
let all = [];
do {
const url = new URL('https://cliq.zoho.com/api/v3/datastores');
url.searchParams.set('limit', '100');
if (nextToken) url.searchParams.set('next_token', nextToken);
const res = await fetch(url, {
headers: { 'Authorization': `Zoho-oauthtoken ${accessToken}` }
});
const json = await res.json();
all = all.concat(json.data);
nextToken = json.next_token || null;
} while (nextToken);
return all;
}
sync_token: Incremental sync
Use sync_token to fetch only records that were created or modified since your last request. This is ideal for polling integrations, as it avoids re-fetching the entire dataset each time.
On the first call, omit sync_token to receive the full list along with a token. On subsequent calls, pass that token to receive only changed records and a new token for the next sync.
| Parameter | Type | Required | Description |
|---|---|---|---|
sync_token | String | Optional | Token from the previous response. Omit on first full load. |
First request (full load)
Omit sync_token to retrieve the complete dataset and receive a token for future syncs.
GET /api/v3/datastores
Authorization: Zoho-oauthtoken {access_token}
{
"url": "/api/v3/datastores",
"type": "datastore",
"data": [ ... ],
"sync_token": "MTB8MTc3NzM2MDM5OTc0OXw="
}
Subsequent request (changes only)
Pass the saved sync_token to receive only records created or modified since your last sync.
GET /api/v3/datastores?sync_token=MTB8MTc3NzM2MDM5OTc0OXw=
Authorization: Zoho-oauthtoken {access_token}
{
"url": "/api/v3/datastores",
"type": "datastore",
"data": [ ... ],
"sync_token": "MTB8MTc3NzM2MDQwMzQ1NXw="
}
Incremental sync pattern
Store the sync_token after each request and use it on the next sync to receive only updates.
async function syncDatastores(accessToken) {
// Load previously saved token (null on first run)
let syncToken = await db.get('cliq_sync_token');
const url = new URL('https://cliq.zoho.com/api/v3/datastores');
if (syncToken) url.searchParams.set('sync_token', syncToken);
const res = await fetch(url, {
headers: { 'Authorization': `Zoho-oauthtoken ${accessToken}` }
});
const json = await res.json();
// Process only the changed records
for (const item of json.data) {
await processChange(item);
}
// Save new token for the next sync
if (json.sync_token) {
await db.set('cliq_sync_token', json.sync_token);
}
}
Combining next_token and sync_token
For modules that support both tokens, use next_token to page through the full initial load, then capture sync_token from the last page and use it for all future incremental syncs.
Full initial load + sync setup
Page through all records first, then save the sync_token from the final page for future incremental updates.
async function initialLoadWithSync(accessToken) {
let nextToken = null;
let syncToken = null;
let all = [];
do {
const url = new URL('https://cliq.zoho.com/api/v3/datastores');
url.searchParams.set('limit', '100');
if (nextToken) url.searchParams.set('next_token', nextToken);
const res = await fetch(url, {
headers: { 'Authorization': `Zoho-oauthtoken ${accessToken}` }
});
const json = await res.json();
all = all.concat(json.data);
nextToken = json.next_token || null;
// Capture sync_token from the last page
if (!nextToken && json.sync_token) {
syncToken = json.sync_token;
}
} while (nextToken);
// Save sync_token for future incremental syncs
await db.set('cliq_sync_token', syncToken);
return all;
}
Best practices
- Use appropriate page sizes: Request only as many records as you need. Smaller pages reduce response time and memory usage.
- Store tokens securely: Treat
sync_tokenas application state. Persist it in a database so you can resume syncing after restarts. - Handle token expiration: If a token becomes invalid, discard it and perform a full sync to get a fresh token.
- Avoid parallel pagination: Process pages sequentially. Starting multiple pagination flows with the same token may cause duplicate or missing records.
- Rate limits apply per request: Each paginated request counts against your rate limit. Plan accordingly for large datasets.