Python SDK: Bulk create users from CSV hitting rate limits

Hey folks,
Trying to script a bulk user import from a CSV using the Python SDK. I’m looping through the rows and calling post_users(body=user_obj) for each entry, but it’s choking on the rate limiter after like 50 users. Is there a bulk endpoint I’m missing, or do I need to implement exponential backoff in the loop?

There is no bulk endpoint for user creation. You’ll hit the wall regardless. The Python SDK has built-in rate limiting, but the default settings are usually too aggressive for simple scripts or too passive for heavy loads. You need to configure the PureCloudPlatformClientV2 with a specific RateLimiter or, more commonly, just add a manual sleep with jitter.

Don’t try to be clever with threads. The API will block you.

Here is the pattern that actually works. It uses a simple exponential backoff on 429 responses and a base delay to keep you under the radar.

import time
import random
from purecloudplatformclientv2 import ApiClient, Configuration, UsersApi
from purecloudplatformclientv2.rest import ApiException

def create_user_with_backoff(users_api, user_body, max_retries=5):
 retry_count = 0
 while retry_count < max_retries:
 try:
 # Standard call
 return users_api.post_users(body=user_body)
 except ApiException as e:
 if e.status == 429:
 # Exponential backoff: 2^retry + random jitter (0-1s)
 wait_time = (2 ** retry_count) + random.uniform(0, 1)
 print(f"Rate limited. Retrying in {wait_time:.2f}s...")
 time.sleep(wait_time)
 retry_count += 1
 else:
 # Not a rate limit, raise normally
 raise e
 raise Exception("Max retries exceeded for user creation")

# Usage inside your CSV loop
# for row in csv_data:
# user_obj = build_user_from_row(row)
# try:
# create_user_with_backoff(users_api, user_obj)
# except Exception as e:
# log_error(row, e)

If you’re processing thousands, you might also want to batch the CSV reading and process in chunks of 10-20 users with a time.sleep(0.5) between each chunk. The API limits are per-org, not per-user, so you’re sharing the pool with everyone else in that tenant.

Also check if you’re using the correct scope. user:read won’t cut it. You need user:write. Missing that gives a 403, which the backoff won’t fix, and it’ll look like a rate limit issue if you’re not logging the status code properly.