Platform SDK JS: Pagination logic for getQueues across multiple divisions

Hey everyone. I’m hitting a wall with the getQueues method in the Genesys Cloud JavaScript SDK (@genesyscloud/genesyscloud-node-sdk).

We need to pull a complete list of queues across three different divisions for a reporting tool. The issue is that the division ID isn’t always known upfront, and the SDK’s pagination seems to reset or behave weirdly when switching contexts.

Here’s what I’ve got so far:

const { PlatformClient } = require('@genesyscloud/genesyscloud-node-sdk');
const client = PlatformClient.createClient({ client_id: '...', client_secret: '...' });

async function getAllQueues(divisions) {
 let allQueues = [];
 
 for (const divId of divisions) {
 let hasNext = true;
 let pageNum = 1;
 
 while (hasNext) {
 const response = await client.queues.getQueues({
 divisionId: divId,
 pageNum: pageNum,
 pageSize: 100,
 expand: 'members'
 });
 
 // Check for empty body to break loop
 if (!response.body || response.body.entities.length === 0) {
 hasNext = false;
 } else {
 allQueues = allQueues.concat(response.body.entities);
 if (response.body.nextPage != null) {
 pageNum++;
 } else {
 hasNext = false;
 }
 }
 }
 }
 return allQueues;
}

The problem is response.body.nextPage. Sometimes it returns a URL, sometimes it’s null even when there are more items. Also, if a division has no queues, the API returns a 200 with an empty entities array, but nextPage is undefined. My loop breaks correctly there, but I feel like I’m reinventing the wheel.

Is there a built-in utility in the JS SDK to handle cross-division pagination automatically? Or am I missing a flag in getQueues that handles division aggregation? I’ve checked the docs but they only show single-division examples. The searchQueues endpoint seems promising but the filter syntax is a pain to construct dynamically.

Any tips on stabilizing this?

Pagination resets because the SDK client holds state for the current request stream. Switching divisions mid-stream breaks that state. You shouldn’t try to paginate across divisions in one loop. It’s cleaner to fetch division IDs first, then iterate.

Here is a safer pattern. It pulls all divisions, then fetches queues for each one separately. This avoids the weird reset behavior you’re seeing.

const platformClient = require('@genesyscloud/genesyscloud-node-sdk').platformClient;
const oauthApi = new platformClient.AuthenticationApi();
const orgV2Api = new platformClient.OrgV2Api();
const routingApi = new platformClient.RoutingApi();

async function getAllQueues() {
 // 1. Get all divisions
 const divisions = await orgV2Api.orgDivisionsGet();
 const allQueues = [];

 for (const div of divisions.entities) {
 // 2. Paginate queues per division
 let page = 1;
 let hasNext = true;
 
 while (hasNext) {
 const queues = await routingApi.routingQueuesGet({
 divisionId: div.id,
 pageSize: 100,
 pageNumber: page
 });

 if (queues.entities && queues.entities.length > 0) {
 allQueues.push(...queues.entities);
 page++;
 } else {
 hasNext = false;
 }
 }
 }
 return allQueues;
}

The key is isolating the pagination loop inside the division loop. If you mix division IDs in a single routingQueuesGet call with a changing divisionId, the SDK’s internal cursor gets confused.

Also check your OAuth scopes. You need routing:queue:view at minimum. If your app runs as a user, make sure that user has access to all three divisions. If it’s a service account, check the division permissions on the application itself.

We use this pattern in our WFM adherence checker. It runs every 60 seconds and pulls agent states. It handles division changes without crashing. Just make sure you rate limit if you have dozens of divisions. The API might throttle you if you hit it too fast in a tight loop.

One thing to watch for is empty divisions. Some orgs have divisions with no queues. The loop handles that, but you might want to add a log statement if queues.entities is empty so you can debug later.