Generating long-lived API token for CI/CD pipeline keeps failing with 401

Does anyone know how to properly generate a long-lived API token for our CI/CD pipeline in Genesys Cloud?

I’m trying to set up an automated deployment script using the Python SDK. The standard OAuth client credentials flow (/api/v2/oauth/token) works fine for short-lived tokens, but our pipeline runs intermittently and I don’t want to handle token refresh logic in the build script. It feels messy. I read somewhere that you can create a long-lived token via the Admin UI or API, but I’m hitting a wall.

I tried using the genesyscloud_platformclient to generate one programmatically. Here is the snippet I’m running locally:

from platformclientv2 import PlatformClient, UserPresenceApi

client = PlatformClient()
client.login(client_id='my_client_id', client_secret='my_client_secret')

# Attempting to find an endpoint for long-lived tokens
# I don't see a direct method in the SDK docs for this
try:
 # This is pseudo-code based on some old forum posts
 token_response = client.get('/api/v2/oauth/longlivedtokens') # Endpoint might be wrong
except Exception as e:
 print(e)

The error I get is 404 Client Error: Not Found. I also tried looking at the /api/v2/users/{userId}/longlivedtokens endpoint directly via curl, authenticated with a valid short-lived token first. It returns a 403 Forbidden even though the user is a super admin in the org. The JSON response says "errors":[{"errorCode":"forbidden","message":"You do not have permission to perform this action"}].

Is there a specific role or permission set I’m missing? Or is the API endpoint different now? I’ve been stuck on this for two days. The documentation for longlivedtokens is pretty sparse compared to the OAuth docs. I just need a static token that doesn’t expire for our nightly deployment jobs. Any help would be appreciated. I’m in Asia/Tokyo timezone so my evenings are late, but I’ll check back tomorrow.

Have you tried using the /api/v2/oauth/clients endpoint to generate a dedicated client ID and secret? You’ll need oauth:client:write scope for that. Just POST with this payload to get a new client pair.

{
 "name": "ci-cd-pipeline",
 "clientType": "confidential",
 "grantTypes": ["client_credentials"],
 "scopes": ["analytics:report:read", "usermanagement:users"]
}