I’m trying to script a bulk import of users from a CSV using the Genesys Cloud Python SDK. I’ve got the authentication working via Client Credentials, but the actual create_user call is failing with a 401.
Here’s the setup. I’m following the OAuth2 Client Credentials docs:
“The client credentials grant type is used by clients to obtain an access token using a client ID and secret.”
My token fetch looks fine:
from genesyscloud.auth.api_client import ApiClient
from genesyscloud.auth.configuration import Configuration
config = Configuration(
host='https://api.mypurecloud.com',
client_id='my_client_id',
client_secret='my_client_secret',
realm_name='mypurecloud.com'
)
api_client = ApiClient(configuration=config)\ntoken = api_client.get_token()
Token prints out valid. Expiry is in the future. Scope is admin:all.
Then I iterate over my CSV and call the user API:
from genesyscloud.user.api import UserApi
user_api = UserApi(api_client=api_client)
# ... reading csv row ...
user_body = {
"name": row['name'],
"email": row['email'],
"username": row['username'],
"division_id": "my_division_id"
}
try:
user_api.post_users(body=user_body)
except Exception as e:
print(f"Failed: {e}")
The error I get is:
genesyscloud.rest_exception.RESTException: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict({'WWW-Authenticate': 'Basic realm="oauth2"', ...})
HTTP response body: {"errors":["invalid_request"],"error":"invalid_request","error_description":"The scope parameter is missing or invalid"}
Wait. I’m not passing a scope in the post_users call. The docs for POST /api/v2/users don’t mention a scope parameter in the body. They only list name, email, etc.
I checked the SDK source for UserApi. The post_users method just passes the body to the underlying ApiClient. The token was generated with admin:all. Why is the API complaining about a missing scope on a user creation request?
If I use Postman with the same token, it works. The Python SDK must be stripping the Authorization header or something. I’ve verified api_client.configuration.access_token is set correctly after get_token().
Anyone seen this? Am I missing a config flag on the UserApi instance?