CXone API client_credentials grant returning 401 Invalid Client

Trying to get a bearer token for our backend service hitting the CXone REST API. I’m using the client_credentials grant type since this is a server-to-server call and there’s no user context involved.

Here’s the curl command I’m running from my local machine in Sydney:

curl -X POST "https://api.nice.com/v1/oauth2/token" \
 -H "Content-Type: application/x-www-form-urlencoded" \
 -d "grant_type=client_credentials&client_id=my_client_id&client_secret=my_client_secret&scope=api:read"

I keep getting back a 401 Unauthorized with this JSON:

{
 "error": "invalid_client",
 "error_description": "Client authentication failed"
}

I’ve double-checked the Client ID and Secret in the CXone Admin portal under Integrations > API Clients. The client is active. I’ve also tried URL-encoding the secret just in case it had special characters, but same result.

Is the endpoint correct? I saw some docs referencing platform.nice.com and others saying api.nice.com. Also, do I need to add a specific scope for the token to be valid for the /api/v2/ endpoints, or is api:read enough?

Stuck on this for an hour. Any ideas?