Recent searches
No recent searches
Python script for creating/updating many users returning a 400 error when attempting to post
Posted Mar 06, 2025
Hello all,
First time poster here and hoping someone can shed some light on my script here.
I have a CSV file properly formatted and the JSON appears to be formatted properly if I print out the final data. If I take that printed data and post it in Postman and send it to the same URL, it works. I am a little confused and am sure it is something easy going on.
My script is based on the API code for create or update many users:
import time
import requests
import json
import pandas
# get the users from the CSV file
users = []
tags = ["sg_users"]
with open('user_list_test.csv', newline='') as csvfile:
reader = pandas.read_csv(csvfile)
for row in reader.itertuples(index=False):
fname = row.FirstName
lname = row.LastName
strname = fname + ' ' + lname
users.append(
{
'name': strname,
'email': row.Email,
'organization_id': row.OrganizationID,
'skip_verify_email': 'true',
'tags': tags,
'user_fields': {'sg_projectname_user': row.ProjectName}
}
)
# prepare the API requests
ZENDESK_SUBDOMAIN = 'domain'
ZENDESK_USER_EMAIL = 'user@corp.ext'
ZENDESK_API_TOKEN = 'TOKEN_VALUE'
auth = f'{ZENDESK_USER_EMAIL}/token', ZENDESK_API_TOKEN
url = f'https://{ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users/create_or_update_many.json'
# Slice the list of users into batches of 100
headers = {
"Content-Type": "application/json",
}
batch_size = 100
num_users = len(users)
start = 0
for start in range(0, num_users, batch_size):
stop = start + batch_size
batch = '{"users":' + json.dumps(users[start:stop]) + '}' # Get the next batch of 100 users and append formatting as a String
# Post the batch to Zendesk
response = requests.request("POST", url, json=batch, auth=auth, headers=headers)
if response.status_code == 429: # Check for rate limit
print('Rate limit reached. Please wait.')
time.sleep(int(response.headers['retry-after']))
response = requests.post(url, json=batch, auth=auth) # Retry request
if response.status_code != 200: # Check for errors other than rate limit
print(f'Import failed with status {response.status_code} - {response.reason}')
exit() # Exit on error
print('\nImport done.')
Thanks in advance,
-Stephen
0
1
1 comment
Greg Katechis
Hi Stephen! I took a look at the logs and the issue is with the formatted response that we're receiving. I see that you cleaned up some earlier problems and the one that's currently causing this is top level object that we receive is a key called “_json”. I'm not super familiar with Python, but I poked around and I think focusing on the formatting options for json.dumps will be the key to cleaning this one up.
0