CXone GET /agents/states returning empty array

Why does this setting keep the agent state endpoint from populating?

i’m hitting GET /api/v2/users/{userId}/state with a fresh oauth token and just getting [] back.

the DataLoader batch runs fine, but the payload stays empty { "agents": [] } even though the user is clearly logged in.

This is caused by the OAuth scope missing view:agentstate or admin:agentstate. The default user token often lacks permission to query global agent states, especially if you’re using a delegated auth flow. Check your token payload in jwt.io. If that scope isn’t there, the server returns an empty array instead of a 403, which is a known quirk.

Also, make sure you’re hitting the correct base URL for CXone. It’s https://{{env}}.cxone.net/api/v2/agents/states. If you’re using the Node.js SDK, try this:

const platformClient = require('cxone-platform-client-v2');
const auth = platformClient.AuthApi;

// ensure you have the right scopes
const accessToken = await auth.getOAuthClientCredentialsGrant(
 'your_client_id', 
 'your_client_secret',
 ['view:agentstate', 'admin:user']
);

const apiInstance = new platformClient.AgentApi();
apiInstance.setAccessToken(accessToken);

try {
 const result = await apiInstance.getAgentsStates();
 console.log(result.body);
} catch (error) {
 console.error(error);
}

If you’re still getting [], it might be a cache issue on the gateway. Sometimes the state service hasn’t fully indexed the active sessions after a DataLoader run. Wait ~30 seconds and retry. Also, check if the users are actually in an “available” or “busy” state. If they’re “offline” or “unknown”, they might not show up depending on your query params. Add ?state=available to filter explicitly.

I’ve seen this trip people up when migrating applications. The API docs look similar, but the permission model can be stricter. Double check your app settings in the CXone admin portal under Administration > Integrations > OAuth Applications. Make sure the app has the correct role mappings. Review the permissions granted to your application to confirm it has access to agent state information.

3 Likes

TL;DR: Check your token scopes. The empty array is a silent failure for missing view:agentstate permissions, not a data issue.

I usually solve this by swapping out the token generation logic to ensure the client credentials grant includes the specific agent state scopes. The default delegated auth flow often strips these down to basic user profile access, which is why you’re seeing [] instead of a 403 Forbidden. It’s a known quirk in the CXone API layer-they prefer returning empty collections over explicit errors for permission mismatches on read-only endpoints.

Here’s how i’d verify and fix it in Java using the PureCloudPlatformClientV2 SDK. First, decode your current token at jwt.io. Look for the scope claim. If you don’t see view:agentstate, that’s your culprit.

To fix it, you’ll need to regenerate the token with the correct scope. If you’re using client credentials (which is common for MuleSoft or backend services), make sure your client has the role assigned with that permission. Here’s a quick snippet to validate the token payload before making the call:

// Check scopes before calling /api/v2/agents/states
List<String> requiredScopes = Arrays.asList("view:agentstate", "view:agent");
boolean hasScope = currentTokenPayload.getScopes().stream()
 .anyMatch(requiredScopes::contains);

if (!hasScope) {
 logger.warn("Missing required scope for agent states. Returning empty list expected.");
 // Regenerate token or fallback to a service account with admin:agentstate
}

if you’re hitting this from a DataLoader context, remember that the batch runner might be using a different auth context than the interactive session. The payload stays empty because the backend service account doesn’t have the visibility role attached. you’ll want to assign the “Agent State Viewer” role to the integration user in the admin console, then re-auth.

don’t forget to clear any cached tokens in your orchestrator. MuleSoft often caches tokens for an hour, so even after you update the role, you might still see the empty array until the cache expires. force a token refresh to be sure.

1 Like

The scope fix is spot on, but if you’re still seeing an empty array after verifying view:agentstate, check the base URL path. the endpoints look similar but behave differently regarding permission checks.

also, make sure you aren’t filtering by a specific user ID in the query params without realizing it. if you send GET /agents/states?userId=... and that user isn’t currently in a monitored state (like ‘available’ or ‘busy’), it returns empty. try hitting the endpoint with no filters first to see if any data comes back.

another thing: if this is for an integration, ensure the service account has the right role. just having the scope isn’t enough if the role doesn’t grant visibility to the specific team or group the agents belong to. check the admin UI under security > roles to confirm the ‘view’ permission is active for the relevant groups.

nah, if you’re on the AU instance the scope issue is less likely if you’re seeing [] instead of a 403. that usually means the endpoint is reachable but filtering out results.

check your base URL. a lot of people accidentally hit the US endpoint when they should be hitting the APAC one. the headers might look fine but the routing is off. Look in Control Manager, under ‘Settings > Platform Info’ to confirm your instance URL.

also, are you filtering by agentId or userId? if the user isn’t in the specific organisation you’re querying, it returns empty. we hit this when moving agents between business units. try removing all query parameters to see if any states come back. if it’s still empty, check if the user’s role actually has the Agent State View permission in the Admin settings. The default roles there are stricter than US.