Getting a 401 Unauthorized when calling POST /api/v2/oauth/token with the client_credentials grant type. The client_id and client_secret are verified correct and copied directly from the integration settings. Here is the request body:
grant_type=client_credentials&client_id=abc123&client_secret=xyz789
The response is just {"error":"invalid_client"}. Is there a specific scope required for this grant type that I’m missing?
Are you hitting the specific environment subdomain like api.us.genesys.cloud? You’ll need Content-Type: application/x-www-form-urlencoded in the headers, otherwise that 401 is just the server rejecting the payload format.
The invalid_client error usually means the platform can’t find the integration in the specific org you’re hitting, not that your credentials are wrong. You’re likely pointing at the wrong subdomain. Genesys Cloud environments are isolated, so api.us.genesys.cloud is different from api.eu.genesys.cloud or any custom instance. If you’re using the US East region, you must use api.us.genesys.cloud. If you’re on a custom instance like myorg.mypurecloud.com, you use api.myorg.mypurecloud.com. Mixing these up is the most common cause for this specific 401.
Here’s what to check:
- Verify the Base URL: Ensure your request hits
https://api.us.genesys.cloud/oauth/token (or your specific region). Don’t guess the region. Check your browser URL when logged into the admin UI.
- Content-Type Header: As mentioned,
application/x-www-form-urlencoded is mandatory. If you send JSON, it fails silently or with 401.
- Client Secret Encoding: Special characters in the secret (like
+ or /) must be URL-encoded. If your secret has a +, it might get interpreted as a space. Use encodeURIComponent in JS or urllib.parse.quote_plus in Python.
- Integration Status: Log into Admin > Integrations > OAuth. Make sure the integration is Active. Disabled integrations return 401.
curl -X POST "https://api.us.genesys.cloud/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
If the secret has special chars, encode it. For example, if the secret is abc+def, send abc%2Bdef. This is a frequent gotcha when copying secrets from the UI. Also, client credentials tokens don’t have user context. You can’t use them to access user-specific data like conversations or user profiles. They only work for org-level APIs. If you need user data, you’ll need a different grant type. Check the integration scopes too. They must be set correctly in the Admin UI, not just in the request.