403 Forbidden on GET /api/v2/routing/queues despite having routing:queue:read scope

Noticed something weird in our Node.js worker tonight. The script pulls queue metrics every fifteen minutes, but suddenly it started dropping 403s on the exact same endpoint that’s been running clean for six months. Checked the token generation routine and the expiry logic looks fine. The access token is definitely valid since other calls to /api/v2/users/me go through without a hitch.

Here’s the fetch wrapper we’re using:
const response = await fetch(‘https://api.mypurecloud.com/api/v2/routing/queues’, {
headers: {
‘Authorization’: Bearer ${accessToken},
‘Content-Type’: ‘application/json’
}
});

The response body just gives back a generic JSON error: {“code”:“forbidden”,“message”:“User does not have permission to access the requested resource.”} We’ve got routing:queue:read attached to the service account, plus routing:queue:write just to be safe. Tried swapping to a fresh token generated with the client credentials flow, same result. Checked the scope list in the developer portal and it looks locked. The service account is tied to a supervisor role with full routing permissions. Still getting blocked.

Also tried bypassing fetch and calling platformClientV2.RoutingApi.getRoutingQueues() directly. Same 403. The SDK definitely doesn’t strip headers since other routing endpoints work fine. Is there a hidden scope requirement for bulk queue retrieval or something weird with the token caching layer? The docs just mention the standard read scope. Running this on Node 20 in a Tokyo ECS container. Logs show the request hits the gateway instantly. Token payload decodes fine too. Scope config looks fine. Just guessing at this point.

You got the scope right, but you’re probably hitting a data privacy wall. Just having routing:queue:read doesn’t mean you can see all queues. If your integration user isn’t assigned to the specific queue, or if the queue’s visibility is set to “Members only,” you’ll get a 403 even with a valid token.

Check the queue object directly. If you can’t GET the queue by ID, the user likely lacks permission to view it. Try switching the user to an admin role or explicitly adding them to the queue as a member.

Here’s how to verify the user’s queue access via the API:

const userSettings = await platformClient.UsersApi.getUserSettings(userId);
console.log(userSettings.queueAccess); // Check if the queue ID is in the accessible list

If that returns empty or missing the queue, that’s your blocker. Fix the membership, not the code.