Switching over to CXone for a new integration project. Trying to get a basic service-to-service auth flow working using the client_credentials grant type. I’ve generated the API keys in the CXone portal and confirmed the scopes include all.
The Node.js code looks standard enough. Using axios to hit the token endpoint directly since the SDK abstraction was hiding the response details I needed for debugging.
const axios = require('axios');
async function getAccessToken() {
const credentials = {
client_id: process.env.CXONE_CLIENT_ID,
client_secret: process.env.CXONE_CLIENT_SECRET,
grant_type: 'client_credentials'
};
try {
const response = await axios.post(
'https://api.cxone.com/oauth/token',
new URLSearchParams(credentials).toString(),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);
return response.data;
} catch (error) {
console.error('Auth failed:', error.response?.status, error.response?.data);
throw error;
}
}
I’m getting a 401 Unauthorized response. The error payload is pretty generic:
{
"error": "invalid_client",
"error_description": "Client authentication failed"
}
I’ve double-checked the env vars. No trailing spaces. The client ID matches exactly what’s in the portal. I even tried regenerating the secret just in case. Same result.
In Genesys Cloud this flow usually just works out of the box. CXone docs say the endpoint is https://api.cxone.com/oauth/token. Is there a specific header requirement I’m missing? Or maybe the Content-Type needs to be different?
Also noticed the docs mention something about API key rotation policies. Could that be blocking a fresh key immediately? Seems unlikely but worth asking.
Any ideas what might be causing the client auth failure here?