Showing results for 
Search instead for 
Did you mean: 

Python Script for Bulk User Creation via JumpCloud API

Novitiate III

Users get defined in a .csv file (sample below), then script is run from the same directory as the .csv file. You will get queried on the CLI for an admin API key (so you don't hardcode it).

It's setup for how I'm defining my users with the schema fields I care about, but you can edit/tailor based on the API doc here:

NOTE: Does not place the user in a UserGroup or assign a device. Do that manually, or write another script.


John,Doe,john,ABCabc123!,,,,John Doe,Sales Manager,1,Sales,Acme,Full-Time,US-based
Jane,Doe,jane,XYZxyz123!,,,,Jane Doe,Security Engineer,2,Security,Acme,Part-Time,International


import re
import requests
import getpass
from datetime import datetime, timedelta

# Function to create users one at a time via JC API
def create_user(api_key,now_plus_21,url,firstname,lastname,username,

    payload = {
    "activated": True,
    "alternateEmail": alternateemail,
    "company": company,
    "department": department,
    "disableDeviceMaxLoginAttempts": True,
    "displayname": displayname,
    "email": email,
    "employeeIdentifier": employeeidentifier,
    "employeeType": employeetype,
    "enable_user_portal_multifactor": True,
    "firstname": firstname,
    "jobTitle": jobtitle,
    "lastname": lastname,
    "ldap_binding_user": True,
    "location": location,
    "mfa": { "configured": True,
             "exclusion": True,
             "exclusionUntil": now_plus_21
    "password": password,
    "password_never_expires": True,
    "passwordless_sudo": True,
    "recoveryEmail": { "address": recoveryemail },
    "state": "ACTIVATED",
    "sudo": True,
    "username": username

    headers = {"x-api-key": api_key, "content-type": "application/json"}
    response = requests.request("POST", url, json=payload, headers=headers)

# Main function. Parse input csv file here and iterate over rows to call the
# create user function that uses API to create the user in JumpCloud.
def main():
    # 21 days from now, local time (likely not Zulu, but close enough)
    now =
    now_plus_21 = str(now + timedelta(days=21))
    now_plus_21 = re.sub(' ', 'T', now_plus_21)
    now_plus_21 = re.sub('\.\d+$', 'Z', now_plus_21)

    url = ""

    # Get API key from CLI using getpass so we don't hardcode it
    api_key = getpass.getpass('Enter a JumpCloud Admin API Key: ')

    # Declare list that will contain a list for each users, so list of lists
    user_list_of_lists = []

    # Users come from a file called 'users.csv' in local directory
    with open("users.csv", "r") as FH:
        for line in FH:
            user_list = line.rstrip().split(',')
    # Get rid of header row
    user_list_of_lists = user_list_of_lists[1:]

    # Iterate of each list in the list of lists
    for l in user_list_of_lists:
        print(f'Creating users with these parameter values: {l}\n')
        firstname = l[0]
        lastname = l[1]
        username = l[2]
        password = l[3]
        email = l[4]
        alternateemail = l[5]
        recoveryemail = l[6]
        displayname = l[7]
        jobtitle = l[8]
        employeeidentifier = l[9]
        department = l[10]
        company = l[11]
        employeetype = l[12]
        location = l[13]

        # Call function that creates the user
                    password,email,alternateemail,recoveryemail, displayname,

if __name__ == '__main__':



JumpCloud Alumni
JumpCloud Alumni

This is pretty neat, thanks for sharing. What are some real world scenarios that this could be used in?

If you are having to create a few (or hundreds) of users in JC, automate it instead of doing it by hand in the UI. It's much faster and easier and less error prone to populate your CSV file than do all that by hand.