How I usually solve this is by verifying the grant type and scope syntax first because CXone is strict about these fields. The client_credentials flow requires grant_type: client_credentials in the body, not just implied by the endpoint. Also, cxone:api is often too broad or incorrect for specific resource access; check your integration settings for the exact scopes granted to that client ID. If the scope is wrong, the token endpoint will return 401. Here is the minimal working payload structure for Python requests:
import requests
url = "https://api.nicecxone.com/oauth/token"
payload = {
"grant_type": "client_credentials",
"scope": "cxone:api" # Verify this matches your integration config exactly
}
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
# Use basic auth with client_id and client_secret
response = requests.post(url, data=payload, headers=headers, auth=("abc-123", "xyz-789"))
print(response.status_code)
print(response.json())
The second issue is usually authentication header formatting. CXone expects Basic Authentication with the client ID and secret encoded in Base64. If you pass these in the body or use Bearer tokens here, it fails. Ensure requests handles the auth tuple correctly as shown above. If you still get 401, check that the client credentials are active and not expired in the CXone admin console. Also, verify that the integration has the necessary permissions. A common gotcha is using the wrong environment endpoint; ensure you are hitting api.nicecxone.com for production or the correct staging URL if testing. Double-check your client secret for hidden characters.
Have you tried ensuring the payload is form-encoded rather than JSON? The NICE CXone OAuth endpoint strictly requires application/x-www-form-urlencoded, so sending a JSON body will result in a 401. Use the Python snippet from the previous post, but verify your client secret is correctly encoded in the auth tuple.
You might want to look at the form-encoded payload. Sending JSON to the token endpoint triggers a 401 immediately. Use data not json in the requests call.