Moodle API: Create Users, Courses, and Enrol Students (Code Examples)
Formswrite Team
•
February 15, 2026

Moodle API: Create Users, Courses, and Enrol Students
This guide covers the most common Moodle API operations with complete code examples: creating users, creating courses, enrolling students, and retrieving data.
Prerequisites
Before using these examples, make sure you have:
- Web services enabled in Site Administration → Advanced features
- REST protocol enabled in Site Administration → Plugins → Web services → Manage protocols
- An API token created in Site Administration → Plugins → Web services → Manage tokens
- A web service with the required functions assigned
Create Users: core_user_create_users
The
core_user_create_users function creates one or more user accounts.Required Fields
| Field | Type | Description |
|---|---|---|
username | string | Unique login name |
password | string | Must meet password policy |
firstname | string | First name |
lastname | string | Last name |
email | string | Email address |
cURL Example
bashcurl -X POST "https://your-moodle.com/webservice/rest/server.php" \
-d "wstoken=YOUR_TOKEN" \
-d "wsfunction=core_user_create_users" \
-d "moodlewsrestformat=json" \
-d "users[0][username]=jane.smith" \
-d "users[0][password]=SecurePass123!" \
-d "users[0][firstname]=Jane" \
-d "users[0][lastname]=Smith" \
-d "users[0][email][email protected]" \
-d "users[0][auth]=manual"
Response
json[
{
"id": 15,
"username": "jane.smith"
}
]
Python: Create Multiple Users
pythonimport requests
MOODLE_URL = "https://your-moodle.com/webservice/rest/server.php"
TOKEN = "your_token"
students = [
{"username": "alice.j", "firstname": "Alice", "lastname": "Johnson", "email": "[email protected]", "password": "Pass123!"},
{"username": "bob.w", "firstname": "Bob", "lastname": "Williams", "email": "[email protected]", "password": "Pass456!"},
{"username": "carol.d", "firstname": "Carol", "lastname": "Davis", "email": "[email protected]", "password": "Pass789!"},
]
data = {
"wstoken": TOKEN,
"wsfunction": "core_user_create_users",
"moodlewsrestformat": "json",
}
for i, student in enumerate(students):
for key, value in student.items():
data[f"users[{i}][{key}]"] = value
response = requests.post(MOODLE_URL, data=data)
created_users = response.json()
for user in created_users:
print(f"Created user: {user['username']} (ID: {user['id']})")
PHP Example
php$token = 'YOUR_TOKEN';
$url = 'https://your-moodle.com/webservice/rest/server.php';
$params = [
'wstoken' => $token,
'wsfunction' => 'core_user_create_users',
'moodlewsrestformat' => 'json',
'users' => [
[
'username' => 'jane.smith',
'password' => 'SecurePass123!',
'firstname' => 'Jane',
'lastname' => 'Smith',
'email' => '[email protected]',
]
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = json_decode(curl_exec($ch));
curl_close($ch);
Get All Users: core_user_get_users
Get Users by Email
bashcurl "https://your-moodle.com/webservice/rest/server.php?wstoken=YOUR_TOKEN&wsfunction=core_user_get_users&moodlewsrestformat=json&criteria[0][key]=email&criteria[0][value][email protected]"
Get Users by Username
bashcurl "https://your-moodle.com/webservice/rest/server.php?wstoken=YOUR_TOKEN&wsfunction=core_user_get_users_by_field&moodlewsrestformat=json&field=username&values[0]=alice.j&values[1]=bob.w"
Python: List All Users
pythonresponse = requests.get(MOODLE_URL, params={
"wstoken": TOKEN,
"wsfunction": "core_user_get_users",
"moodlewsrestformat": "json",
"criteria[0][key]": "email",
"criteria[0][value]": "%@school.edu"
})
users = response.json()["users"]
for user in users:
print(f"{user['id']}: {user['firstname']} {user['lastname']} ({user['email']})")
Create Courses: core_course_create_courses
Required Fields
| Field | Type | Description |
|---|---|---|
fullname | string | Full course name |
shortname | string | Short identifier (unique) |
categoryid | int | Category ID (1 = Miscellaneous) |
cURL Example
bashcurl -X POST "https://your-moodle.com/webservice/rest/server.php" \
-d "wstoken=YOUR_TOKEN" \
-d "wsfunction=core_course_create_courses" \
-d "moodlewsrestformat=json" \
-d "courses[0][fullname]=Biology 101 - Introduction to Biology" \
-d "courses[0][shortname]=BIO101" \
-d "courses[0][categoryid]=1" \
-d "courses[0][summary]=An introductory course covering cell biology, genetics, and evolution." \
-d "courses[0][format]=topics" \
-d "courses[0][numsections]=12"
Response
json[
{
"id": 5,
"shortname": "BIO101"
}
]
Python: Create Multiple Courses
pythoncourses = [
{"fullname": "Biology 101", "shortname": "BIO101", "categoryid": 1},
{"fullname": "Chemistry 201", "shortname": "CHEM201", "categoryid": 1},
{"fullname": "Physics 301", "shortname": "PHYS301", "categoryid": 1},
]
data = {
"wstoken": TOKEN,
"wsfunction": "core_course_create_courses",
"moodlewsrestformat": "json",
}
for i, course in enumerate(courses):
for key, value in course.items():
data[f"courses[{i}][{key}]"] = value
response = requests.post(MOODLE_URL, data=data)
print(response.json())
Get All Courses: core_course_get_courses
bashcurl "https://your-moodle.com/webservice/rest/server.php?wstoken=YOUR_TOKEN&wsfunction=core_course_get_courses&moodlewsrestformat=json"
Python
pythonresponse = requests.get(MOODLE_URL, params={
"wstoken": TOKEN,
"wsfunction": "core_course_get_courses",
"moodlewsrestformat": "json"
})
for course in response.json():
print(f"Course {course['id']}: {course['fullname']} ({course['shortname']})")
Enrol Users: enrol_manual_enrol_users
Moodle Role IDs
| Role ID | Role |
|---|---|
| 1 | Manager |
| 2 | Course Creator |
| 3 | Teacher |
| 4 | Non-editing Teacher |
| 5 | Student |
cURL: Enrol a Student
bashcurl -X POST "https://your-moodle.com/webservice/rest/server.php" \
-d "wstoken=YOUR_TOKEN" \
-d "wsfunction=enrol_manual_enrol_users" \
-d "moodlewsrestformat=json" \
-d "enrolments[0][roleid]=5" \
-d "enrolments[0][userid]=15" \
-d "enrolments[0][courseid]=5"
Python: Bulk Enrol Students
pythonstudent_ids = [15, 16, 17, 18, 19]
course_id = 5
data = {
"wstoken": TOKEN,
"wsfunction": "enrol_manual_enrol_users",
"moodlewsrestformat": "json",
}
for i, uid in enumerate(student_ids):
data[f"enrolments[{i}][roleid]"] = 5
data[f"enrolments[{i}][userid]"] = uid
data[f"enrolments[{i}][courseid]"] = course_id
response = requests.post(MOODLE_URL, data=data)
print("Enrolment complete" if response.status_code == 200 else "Error")
Complete Workflow: Create Course, Users, and Enrol
pythonimport requests
MOODLE_URL = "https://your-moodle.com/webservice/rest/server.php"
TOKEN = "your_token"
# Step 1: Create the course
course_data = {
"wstoken": TOKEN,
"wsfunction": "core_course_create_courses",
"moodlewsrestformat": "json",
"courses[0][fullname]": "Biology 101",
"courses[0][shortname]": "BIO101-2026",
"courses[0][categoryid]": 1,
}
course_response = requests.post(MOODLE_URL, data=course_data).json()
course_id = course_response[0]["id"]
print(f"Created course: {course_id}")
# Step 2: Create students
students = [
{"username": "s1", "firstname": "Alice", "lastname": "A",
"email": "[email protected]", "password": "P@ss1234!"},
{"username": "s2", "firstname": "Bob", "lastname": "B",
"email": "[email protected]", "password": "P@ss1234!"},
]
user_data = {
"wstoken": TOKEN,
"wsfunction": "core_user_create_users",
"moodlewsrestformat": "json",
}
for i, s in enumerate(students):
for k, v in s.items():
user_data[f"users[{i}][{k}]"] = v
user_response = requests.post(MOODLE_URL, data=user_data).json()
user_ids = [u["id"] for u in user_response]
print(f"Created users: {user_ids}")
# Step 3: Enrol students
enrol_data = {
"wstoken": TOKEN,
"wsfunction": "enrol_manual_enrol_users",
"moodlewsrestformat": "json",
}
for i, uid in enumerate(user_ids):
enrol_data[f"enrolments[{i}][roleid]"] = 5
enrol_data[f"enrolments[{i}][userid]"] = uid
enrol_data[f"enrolments[{i}][courseid]"] = course_id
requests.post(MOODLE_URL, data=enrol_data)
print("All students enrolled!")
Adding Quizzes to Your Courses
Once your courses and users are set up via the Moodle API, the next step is adding assessments. While the Moodle API handles user and course management well, creating quiz questions programmatically is complex.
The easiest way to add quizzes is with Formswrite:
- Write your quiz in a Google Doc
- Convert to Moodle XML via the Formswrite API or web interface
- Import the XML into your course's Question Bank
This pairs perfectly with the Moodle API workflow: use the Moodle API for users and courses, and Formswrite for quiz content.
FAQ
What is core_user_create_users?
core_user_create_users is the Moodle Web Services function for creating new user accounts. It accepts an array of user objects with fields like username, password, firstname, lastname, and email.Can I create users without passwords?
No. The
password field is required and must meet your Moodle site's password policy.What role ID should I use for students?
Role ID 5 is the default Student role. Use 3 for Teachers and 1 for Managers.
Can I bulk enrol from a CSV?
The Moodle API doesn't have a CSV upload endpoint, but you can read a CSV in your script and call
enrol_manual_enrol_users with the data.Summary
The Moodle API makes it easy to automate user creation, course setup, and enrolment. For quiz content, pair it with Formswrite to convert Google Docs into Moodle XML files automatically.