Long-lived API token for CI/CD pipeline generation failing with 403

We are trying to set up a CI/CD pipeline to deploy our embeddable client apps to Genesys Cloud. The docs suggest using the client credentials grant flow to get an access token for the pipeline service account.

The flow works fine when I test it with Postman using the client ID and secret. But when we run the script in Azure DevOps, the request keeps returning a 403 Forbidden error.

Here is the C# code we are using to make the call:

var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));

var content = new FormUrlEncodedContent(new[]
{
 new KeyValuePair<string, string>("client_id", Environment.GetEnvironmentVariable("GENESYS_CLIENT_ID")),
 new KeyValuePair<string, string>("client_secret", Environment.GetEnvironmentVariable("GENESYS_CLIENT_SECRET")),
 new KeyValuePair<string, string>("grant_type", "client_credentials")
});

var response = await client.PostAsync($"{baseUrl}/oauth/token", content);

The error response body is just {"errors":["Unauthorized"],"message":"Unauthorized"}.

I’ve checked the API user permissions. The user has the apiadmin role. The client credentials were generated from the API user page. I’m wondering if there is a specific scope we are missing in the request payload or if the CI/CD environment is somehow stripping the headers. The documentation isn’t very clear on whether additional scopes are needed for pipeline deployments versus standard SDK usage.

2 Likes