Python SDK: 400 Bad Request when bulk-creating users from CSV via n8n Code Node

I can’t seem to figure out why my Python script, executed within an n8n Code Node, consistently returns a 400 Bad Request when attempting to bulk-create users from a CSV file using the Genesys Cloud Platform SDK. I have meticulously validated the CSV structure against the API documentation, ensuring all required fields like name, email, and division_id are present and correctly formatted. The workflow parses the CSV into a list of dictionaries, which I then pass to the SDK client. Despite successful authentication and correct environment variables for the Brazil region, the API rejects the payload before any user is created. I suspect there might be a subtle schema mismatch or an issue with how the SDK serializes the nested objects.

Here is the core logic within the n8n Python Code Node:

from genesyscloud import PlatformClient
from genesyscloud.user import UserApi

client = PlatformClient()
user_api = UserApi(client)

# users_data is a list of dicts from previous CSV node
for user_data in users_data:
 try:
 # Constructing the user object as per SDK docs
 user_body = {
 "name": user_data['name'],
 "email": user_data['email'],
 "division_id": user_data['division_id'],
 "roles": [{"id": user_data['role_id']}]
 }
 response = user_api.post_users(body=user_body)
 yield {"status": "success", "id": response['id']}
 except Exception as e:
 yield {"status": "error", "message": str(e)}

The error response body consistently shows:

{
 "message": "Invalid request",
 "status": 400
}

I have verified the division_id and role_id exist in our tenant. Is the post_users method expecting a different structure for the roles array, or is there a known limitation with the Python SDK version 1.0.47 regarding nested object serialization in batch-like loops? Any insights on debugging the exact field causing the validation failure would be appreciated.

I use GetRESTProxy in Studio for this. The Python SDK often mishandles bulk headers. Try this direct API call instead:

requests.post(f"{base_url}/api/v2/users", json=user_data, headers=headers)

Check these:

  • OAuth scope user:write
  • Division ID validity
  • Email uniqueness

This is actually a known issue with the synchronous SDK in constrained environments. Switch to httpx with async batching to bypass the n8n execution timeout and handle rate limits gracefully.

async def batch_create(client: httpx.AsyncClient, users: list):
 tasks = [client.post("/api/v2/users", json=u) for u in users]
 return await asyncio.gather(*tasks, return_exceptions=True)