CXone client_credentials grant failing with 401

Hey all,

Trying to set up a service account to hit the CXone API directly without user interaction. I’m using the client_credentials grant type but keep getting a 401 Unauthorized response.

Here’s the payload I’m sending to https://platform.devtest.nicecxone.com/oauth/token:

{
 "grant_type": "client_credentials",
 "client_id": "my-client-id",
 "client_secret": "my-secret"
}

Is there something missing here? The docs are a bit vague on the exact header requirements for this flow.

1 Like

The documentation is quite specific about the content type for OAuth client credentials. You need application/x-www-form-urlencoded, not JSON.

Here’s how you’d do it in Node with node-fetch or axios:

const axios = require('axios');

async function getToken() {
 const url = 'https://platform.devtest.nicecxone.com/oauth/token';
 
 // Must be form-encoded, not JSON
 const params = new URLSearchParams();
 params.append('grant_type', 'client_credentials');
 params.append('client_id', process.env.CXONE_CLIENT_ID);
 params.append('client_secret', process.env.CXONE_CLIENT_SECRET);

 try {
 const response = await axios.post(url, params, {
 headers: {
 'Content-Type': 'application/x-www-form-urlencoded'
 }
 });
 
 console.log('Token:', response.data.access_token);
 return response.data;
 } catch (error) {
 console.error('Auth failed:', error.response?.data || error.message);
 }
}

getToken();

Sending JSON to that endpoint usually results in a 401 because the server doesn’t parse the body correctly for that grant type. Also ensure your client ID and secret correspond to an application configured within the CXone Admin portal with the necessary API permissions for the endpoints you intend to access. Double-check the scopes assigned to the application.

If you’re using the CXone JavaScript SDK, you don’t need to handle this manually. Investigate the Client class and its authentication methods, which may provide a simplified approach to obtaining and managing OAuth tokens using the client credentials flow. Refer to the SDK documentation for examples.

// Example using a hypothetical SDK method (check the official docs)
async function initClient() {
 const client = new CxoneClient();

 try {
 await client.auth.login({
 clientId: process.env.CXONE_CLIENT_ID,
 clientSecret: process.env.CXONE_CLIENT_SECRET,
 grantType: 'client_credentials'
 });

 // Now you can use client.api.Users, client.api.Conversations, etc.
 return client;
 } catch (error) {
 console.error("Authentication failed:", error);
 }
}

Using the SDK will simplify token expiration handling and retry logic.