Is it possible to pull every queue across all our divisions without hitting the 250-item pagination wall on the first request?
Problem
i’m building a custom routing selector for a guest widget that needs to map queue IDs to display names dynamically. the standard queueApi.getQueues() call only returns a single page and the pageSize param seems capped at 250 in the SDK. when i try to loop through pages manually, the division filter behavior gets weird. it looks like the SDK doesn’t parse the divisionId array correctly, and if i leave it blank, it’s just dumping the default division queues.
Environment
genesys-cloud-platform-client v1.0.48
node 18 runtime for the proxy layer
us-east-1 org environment
custom oauth2 service account with org admin scope
Code
const client = require('@genesyscloud/purecloud-platform-client');
const queueApi = new client.QueueApi();
let allQueues = [];
let pageNumber = 1;
let hasMore = true;
while (hasMore) {
const res = await queueApi.getQueues({
pageSize: 250,
pageNumber: pageNumber,
divisionId: 'all' // trying to bypass division scoping
});
allQueues = [...allQueues, ...res.body.entities];
hasMore = pageNumber < res.body.pageCount;
pageNumber++;
}
Error / Behavior
the api throws a 400 bad request when divisionId is set to all. stripping that out just grabs queues from the root division. pagination works fine there, but i need the full list across every custom division we spun up last quarter. i tried swapping to a raw /api/v2/queues call with axios, but the SDK handles the bearer token refresh automatically and rewriting the credential rotation logic feels like a waste of time. the loop just hangs or returns duplicates depending on how i structure the fetch.
Have you tried looping through the nextPage link instead of fighting the 250 cap? the sdk doesn’t expose a “get all” method, so you’ll need to handle pagination manually.
watch out for division scopes here. if your token only has queue:read without specific division visibility, it’ll silently filter out queues in other divisions. verify your OAuth scopes include the necessary division access. also, caching this result is smart since queue configs don’t change often. just make sure your cache expiry aligns with how frequently you update routing logic. i’ve seen tokens expire mid-loop if the session is stale, so wrap it in a retry handler.
Make sure you check the response headers properly. The pagination logic in the previous post is a bit off. you need to pass the pageNumber parameter explicitly instead of relying on a nextPage function that might not exist in your SDK version.
const allQueues = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const res = await queueApi.getQueues({ pageSize: 250, pageNumber: page });
if (!res.entities || res.entities.length === 0) break;
allQueues.push(...res.entities);
page++;
hasMore = res.entities.length === 250;
}
This approach works because the API respects the pageNumber field. you’ll hit the endpoint directly and keep fetching until the returned array is smaller than your page size. it’s cleaner than trying to parse links manually. just remember to handle rate limits if you’re pulling a massive org. i usually add a small delay between requests to avoid getting throttled.
this looks like it will hang your process if you have more than a few hundred queues. the sdk doesn’t handle pagination state internally like that. you’re relying on a nextPage method that might not exist or behave consistently across versions. the documentation states, “pagination is handled via pageNumber and pageSize parameters, with a maximum of 250 entities per response.” you need to loop explicitly.
const allQueues = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const res = await queueApi.getQueues({ pageSize: 250, pageNumber: page });
if (!res.entities || res.entities.length === 0) break;
allQueues.push(...res.entities);
page++;
}
also watch out for rate limiting if you’re doing this on a hot path. 250 is the max, but hitting it repeatedly can trigger 429s. maybe cache the result for a few minutes. i’ve seen widgets timeout because they fetched queues on every render. don’t do that.
TL;DR: The JS SDK nextPage helper is flaky. Use explicit pageNumber loops. Also, check your OAuth scope.
the suggestion above regarding looping is correct, but the implementation is missing a critical check. if you just loop while hasMore without checking the entity count, you’ll spin forever on an empty page or hit rate limits. the docs say: “The API returns a maximum of 250 entities per page. Subsequent pages are retrieved by incrementing the pageNumber.”
here’s how i handle this in my python services, but the logic applies to JS too. you need to track the page index and break when the response is empty.
const allQueues = [];
let pageNumber = 1;
const pageSize = 250;
let hasMore = true;
while (hasMore) {
try {
const res = await queueApi.getQueues({ pageSize, pageNumber });
if (!res.entities || res.entities.length === 0) {
hasMore = false;
break;
}
allQueues.push(...res.entities);
// safety break if we get less than pageSize, we're done
if (res.entities.length < pageSize) {
hasMore = false;
} else {
pageNumber++;
}
} catch (err) {
console.error("Pagination failed:", err);
break;
}
}
also, make sure your OAuth token has the queue:view scope. if you’re using client credentials, double-check the app permissions in the developer portal. i’ve seen 403 Forbidden errors masquerade as empty arrays when the division filter isn’t set correctly.
if you’re fetching across multiple divisions, you might need to iterate over the divisions list first and append the division ID to the query. otherwise, you only get queues from the default division.
// fetch divisions first
const divisions = await organizationApi.getOrganizationDivisions();
// then loop divisions and queues
don’t forget to add a small delay between requests if you’re hitting this in a tight loop. the API isn’t infinite.