Trying to set up a custom integration in CXone Studio to fetch user profiles via the API. I’m using GetRESTProxy with the client_credentials grant, but keep hitting a 401 Unauthorized error on the subsequent GET request. The token endpoint /api/v2/oauth/token returns a valid access token, but it seems to expire or be rejected immediately.
ASSIGN token_resp = GetRESTProxy("POST", "/api/v2/oauth/token", {"grant_type":"client_credentials"})
ASSIGN token = token_resp.access_token
Is there a specific header I’m missing when passing this token to the next call?
The issue is almost certainly the scope. client_credentials gives you an app-to-app token, but it doesn’t inherit user permissions by default. If your NICE CXone app doesn’t have the admin:api or specific user:read scopes assigned in the developer portal, that token is useless for fetching user profiles.
Check your app configuration first. Then, look at the GetRESTProxy call. You’re likely passing the token in the wrong header or missing the Authorization: Bearer prefix. Also, ensure you’re using the correct base URL for your region.
Here’s how to structure it in Studio to avoid the 401:
// Step 1: Get the token
ASSIGN token_resp = GetRESTProxy("POST", "/api/v2/oauth/token", {
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}, {
"Content-Type": "application/x-www-form-urlencoded"
});
// Step 2: Extract token
ASSIGN access_token = token_resp.access_token;
// Step 3: Fetch user with correct header
ASSIGN user_resp = GetRESTProxy("GET", "/api/v2/users/me", {}, {
"Authorization": "Bearer " + access_token,
"Accept": "application/json"
});
If you’re still getting 401, print token_resp to see if the token actually came back. Sometimes the token endpoint fails silently in Studio logs if you don’t check the status code. Also, verify that the app has the user:read scope enabled. Without it, the API rejects the request immediately.
One more thing: client credentials tokens expire in 24 hours by default, but they can be revoked if the app config changes. If this is running frequently, consider caching the token or refreshing it before expiry.
Check the app scopes in the developer portal. That’s usually the culprit.