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

image avatar

Greg Katechis

Zendesk Developer Advocacy

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


Please sign in to leave a comment.

Didn't find what you're looking for?

New post