I am trying to bulk-create users from a CSV using the Genesys Cloud Python SDK. The script reads the file and calls post_users_user in a loop. It works for one user but fails on the second iteration with a 409 Conflict error. The JSON payload seems correct.
for row in reader:
body = {"name": row["name"], "email": row["email"]}
api.post_users_user(body=body)
Why does the second call fail?
The 409 conflict usually means the resource already exists, but in a fresh CSV run, it’s often because you’re reusing the same client instance without handling the response or rate limits correctly, or you’re hitting a uniqueness constraint on email that isn’t being cleared between test runs. However, looking at your snippet, the bigger issue is that post_users_user expects a full CreateUserRequest object, not just a raw dict with two fields. The SDK will throw or the API will reject it if required fields like password or routing_email aren’t present or validated.
You should also be catching the ApiException to see the actual error body. A 409 in this context often means the email is already in use. If you’re testing, ensure those emails are unique or delete them first.
Here’s how to structure the loop properly using the SDK models and proper error handling:
from platformclientv2 import ApiClient, Configuration, UsersApi, CreateUserRequest
import csv
config = Configuration()
config.host = "https://api.us.genesys.cloud"
# auth setup...
api_client = ApiClient(configuration=config)
users_api = UsersApi(api_client)
with open('users.csv', 'r') as f:
reader = csv.DictReader(f)
for row in reader:
try:
# Construct the proper request object
body = CreateUserRequest(
name=row['name'],
email=row['email'],
password="TempPass123!", # Required field
routing_email=row['email'] # Often required for login
)
user = users_api.post_users_user(body=body)
print(f"Created user: {user.id}")
except Exception as e:
print(f"Failed for {row['name']}: {e}")
Make sure your app has the user:write scope. If you’re still hitting 409s, check if the emails are being reused from a previous failed run. The API doesn’t auto-clean partial failures.