Client_credentials token returns 401 invalid_token on analytics POST queries

Service keeps throwing 401 Unauthorized with {"error":"invalid_token"} when calling POST /api/v2/analytics/conversations/queries. Background job aggregates queue stats without user context. client_credentials grant handles the auth.

POST /oauth/token returns 200. Payload looks standard:

{
 "grant_type": "client_credentials",
 "client_id": "${CLIENT_ID}",
 "client_secret": "${CLIENT_SECRET}",
 "scope": "analytics:read"
}

Response includes access_token and expires_in. Dashboard hits the analytics endpoint roughly 5 minutes after token issuance. Authorization: Bearer <token> header gets set.

JWT payload checks out. exp claim sits in the future. iss matches https://login.mypurecloud.com. aud points to https://api.mypurecloud.com. Token scopes list analytics:read.

GET /api/v2/users/me passes with the same token. App user data returns successfully. Token validity seems fine for basic scopes.

Analytics query body uses interval: "PT1H" and groupBy: ["routing.queue.id"]. Simple aggregate structure. Nothing triggering special validation.

Error headers contain x-correlation-id. Local debugging stops there.

403 errors appear for missing scopes usually. 401 suggests the token gets rejected outright. Node.js axios handles the requests. Raw HTTP preferred over SDK for retry control.

const response = await axios.post(
 'https://api.mypurecloud.com/api/v2/analytics/conversations/queries',
 {
 dateFrom: '2023-10-01T00:00:00.000Z',
 dateTo: '2023-10-02T00:00:00.000Z',
 interval: 'PT1H',
 groupBy: ['routing.queue.id']
 },
 {
 headers: {
 'Authorization': `Bearer ${token}`,
 'Content-Type': 'application/json'
 }
 }
);

client_credentials tokens failing on analytics endpoints specifically feels odd. Audience claim might need adjustment? Domain setup uses login.mypurecloud.com.

Token decodes correctly. invalid_token error persists. Don’t see what’s breaking here.