Python Platform SDK: Bulk user creation failing with 409 Conflict on email uniqueness

I’m trying to automate the onboarding of a batch of agents by reading a CSV and hitting the /api/v2/users endpoint using the Python SDK (genesyscloud package v2.8.10).

The logic is straightforward: read the row, check if the user exists, if not, create them. The issue is that the user_api.get_user_by_email call seems to be throttling or timing out when I run this in a loop for ~50 users, and even when it succeeds, the subsequent create call throws a 409 Conflict claiming the email is already in use, despite the check returning None.

Here’s the snippet I’m using for the creation logic:

from genesyscloud import PlatformClientConfiguration, UserApi
import csv

config = PlatformClientConfiguration(
 client_id=CLIENT_ID,
 client_secret=CLIENT_SECRET,
 base_url="https://myorg.mygenesyscloud.com"
)

user_api = UserApi(config)

with open('new_agents.csv', 'r') as f:
 reader = csv.DictReader(f)
 for row in reader:
 email = row['email']
 # Check existence
 try:
 existing, resp = user_api.get_user_by_email(email=email, expand=['addresses'])
 if resp.status_code == 200:
 print(f"User {email} exists. Skipping.")
 continue
 except Exception as e:
 if e.status == 404:
 pass # User doesn't exist, proceed
 else:
 print(f"Error checking user: {e}")
 continue

 # Create user
 user_body = {
 "email": email,
 "name": row['name'],
 "email_addresses": [{
 "email": email,
 "type": "work"
 }]
 }
 
 try:
 created_user, resp = user_api.post_users(body=user_body)
 print(f"Created user: {created_user.id}")
 except Exception as e:
 print(f"Failed to create {email}: {e.status} - {e.body}")

The error I’m getting is consistently a 409 with the body:

{
 "message": "Conflict",
 "errors": [
 {
 "code": "duplicate.email",
 "message": "The email address is already in use."
 }
 ]
}

I’ve added a time.sleep(1) between iterations to avoid rate limiting, but the conflict persists. Is there a better way to batch create users, or am I missing a specific header or parameter to handle the uniqueness check correctly? The post_users method doesn’t seem to have an ignore_if_exists flag.

Also, I noticed the SDK documentation mentions put_users for updates, but I don’t see a bulk endpoint like post_users_batch. Is that intentional or am I looking in the wrong API group?

You might be hitting the rate limit wall because you’re doing sequential lookups. The get_user_by_email endpoint isn’t built for high-throughput loops. It’s also worth noting that checking existence before creation is a race condition anyway. If two scripts run at the same time, both might see the user as missing and try to create it, leading to that 409.

Instead of checking first, just try to create the user and catch the exception. The Python SDK handles the HTTP status codes cleanly. If the user already exists, you get a 409, which you can ignore or log. If it’s a different error, you handle that. This removes the extra API call entirely.

Here is how I’d structure the loop in Python:

from genesyscloud import users_api
from genesyscloud.users.model.user import User

user_api = users_api.UsersApi(platform_client)

for row in csv_data:
 try:
 user_body = User(
 email=row['email'],
 name=row['name'],
 external_id=row['external_id'] # Good for idempotency
 )
 user_api.post_user(body=user_body)
 print(f"Created: {row['email']}")
 except Exception as e:
 if e.status_code == 409:
 print(f"User already exists: {row['email']}")
 else:
 print(f"Error creating {row['email']}: {e}")

Make sure your OAuth token has user:write scope. Also, if you are creating more than 50 users, add a small sleep between iterations. The API has a limit of 10 requests per second per client ID. If you go faster, you’ll get 429s. A sleep of 0.1 seconds is usually safe for bulk operations. This approach is simpler and avoids the timeout issue you mentioned. The get_user_by_email call is slow because it’s doing a directory search, whereas the POST is a direct write. Just catch the conflict and move on. It’s cleaner code too.