I’m hitting a wall with the CXone API authentication. I need to spin up a background service that doesn’t rely on user sessions, so I’m trying to use the client_credentials grant type.
The docs say it’s supported, but every time I hit the token endpoint, I get a 401 Unauthorized.
Here’s the request I’m sending:
const axios = require('axios');
const getToken = async () => {
const formData = new URLSearchParams();
formData.append('grant_type', 'client_credentials');
// I've verified these in the CXone Admin UI under API Access
formData.append('client_id', 'my-app-client-id');
formData.append('client_secret', 'my-app-secret');
try {
const response = await axios.post(
'https://api.cxone.com/api/v2/oauth/token',
formData,
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'
}
}
);
console.log('Token:', response.data.access_token);
} catch (error) {
console.error('Auth failed:', error.response.status, error.response.data);
}
};
getToken();
The error response is just generic:
Auth failed: 401 { error: 'invalid_client', error_description: 'Bad client credentials' }
I’ve copied the ID and Secret directly from the UI. I even regenerated the secret to make sure it wasn’t a copy-paste whitespace issue. The app is enabled and active.
Is there a specific scope I need to attach to the request body? I tried adding scope=platform:conversation:view but it didn’t change anything. Also, the endpoint URL… is it definitely api.cxone.com or does it vary by region? I’m assuming the global endpoint since I can’t find a region-specific one in the JS SDK examples.
Feeling pretty dumb about this one since it’s supposed to be the simplest auth flow.