CXone client_credentials token request returning 401 Bad Request

I need to set up a service account for our routing compliance checks in the US/Eastern org. We are using the CXone API and trying to get an access token via the client_credentials grant. The goal is to automate queue status pulls without user interaction. I followed the standard OAuth2 docs for CXone but keep hitting a wall with the initial token request.

Here is the curl command I am running against the https://api.cxone.com/oauth/token endpoint:

curl -X POST https://api.cxone.com/oauth/token \
 -H "Content-Type: application/x-www-form-urlencoded" \
 -d "grant_type=client_credentials&client_id=MY_CLIENT_ID&client_secret=MY_SECRET&scope=api:read"

The response is consistently a 401 Unauthorized. The body just says {"error":"invalid_client","error_description":"Client authentication failed"}. I have double-checked the client ID and secret in the CXone admin portal under Security > OAuth Clients. They look correct. I also tried adding the Content-Type as application/json and sending the payload as a JSON object instead of form-urlencoded, but that just gave a 415 Unsupported Media Type.

I am not sure if I need to encode the credentials in the Authorization header instead of the body. Some docs mention Basic Auth for the client credentials. Is there a specific way CXone expects the client_secret to be passed? I am using the public US/Eastern environment. Any working example of the exact curl command or Python requests snippet would be great. I just need to get past this auth step to start building the Terraform modules for our routing rules.