403 Forbidden on /api/v2/routing/queues — OAuth scope mismatch

Problem

We’re pulling queue layout configurations for the dashboard team. Production throws a hard stop when hitting the routing queues path. The script runs fine in the dev sandbox.

Code

import requests
headers = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}
resp = requests.get('https://api.mypurecloud.com/api/v2/routing/queues', headers=headers)

Error

Returns 403 Forbidden. We’re running Python 3.11 with requests 2.31. The payload says {'code':'bad_request','message':'Access denied. Check your OAuth scopes.'}. We’ve verified the token is valid in us-east-1. The app registration has routing:read attached, but it still drops the call.

Question

Which exact scope handles this endpoint? The docs mention routing:write for mutations. We only need layout stats. Tried adding routing:queue:read and analytics:read without luck. Token refresh logic is working fine. It’s strictly a permission mismatch. Honestly, the UI shows the queues perfectly fine. The user role is correct. Just the API call is failing.

Check your OAuth scopes. The Python script is likely using oauth:standard:offline or a similar broad scope that doesn’t include queue read permissions. The docs explicitly state you need routing:queue for this endpoint. I hit this exact issue with our C# Azure Function last week. It worked in dev because the sandbox token had oauth:admin, but prod tokens are stricter. You’ll get a 403 if the scope isn’t precise.

Here is the minimal scope list you need to request during the client credentials flow. Make sure your integration setup in GC matches this exactly.

var scope = new List<string> { "openid", "routing:queue", "routing:queue:read" };
// Use this list when generating the token

If you’re using the SDK, it handles the scope aggregation, but raw requests need manual configuration. Don’t forget to rotate the token if you change scopes. The old token won’t pick up the new permissions.