Moodle Tool
Read Moodle courses, rosters, assignments, submissions and grades through Moodle's web services API. This is the tool for questions about who is enrolled, who handed work in, and what they scored — the place where genuinely institution-specific automation lives, because an under-enrolment alert is only real when it reads a live roster.
Tool ID
moodle
Credential Required
Yes — a moodle credential. The secret is a web service token (wstoken) issued by a
Moodle administrator, not a password.
The token is passed as a query parameter, which is Moodle's design rather than a choice made here. Two consequences worth knowing: the token can appear in web-server access logs on the Moodle side, and it carries the capabilities of the web-service USER it was created for. A token cannot see a course its user cannot see, so an empty result is more often a permissions answer than an absence of data.
Credential Properties
| Property | Type | Default | Description |
|---|---|---|---|
secret |
string | — | Required. The wstoken issued by the Moodle administrator. |
Moodle setup
- Site administration → Server → Web services → Overview, and work down that page — Moodle will not serve a single call until web services are enabled globally.
- Enable the REST protocol. It is off by default.
- Create a dedicated web-service user, and give it only the capabilities the automation needs. Its permissions are the ceiling on everything this connector can read.
- Create an external service, add the functions listed under Operations below, and authorise
the user against it. A function that is not added to the service returns
accessexceptionno matter what the user is allowed to do. - Create a token for that user and service. That token is the credential secret.
- Verify with
get_site_infobefore anything else — it is the cheapest call that proves the token works, and it returns the site name and the Moodle version.
Permissions
Whatever the web-service user holds, narrowed further by which functions were added to the external service. moodle/course:view, moodle/user:viewdetails and the gradereport capabilities cover the operations here; assignment functions additionally need mod/assign:grade or equivalent to see other people's submissions.
Operations
1. list_courses — List courses
Every course the token's user can see. On a large site this is a big response; prefer get_courses_by_field when you know what you are looking for. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_course_get_courses.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_courses |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
2. get_courses_by_field — Find courses by field
Narrow server-side instead of filtering afterwards — pass field (one of id, ids, shortname, idnumber, category) and value. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_course_get_courses_by_field.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_courses_by_field |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
3. list_categories — List course categories
The category tree courses are organised under — department, term, or however this site models it. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_course_get_categories.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_categories |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
4. list_course_contents — List a course's contents
Sections and activities inside one course. Needs courseid. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_course_get_contents.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_course_contents |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
5. list_enrolled_users — List a course's roster
THE enrolment answer: the actual people in one course, with their roles. This is what an under-enrolment or class-size report reads, and what makes such a report real rather than a fixture. Needs courseid. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_enrol_get_enrolled_users.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_enrolled_users |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
6. list_users_courses — List one user's courses
The inverse view — everything one person is enrolled in. Needs userid. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_enrol_get_users_courses.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_users_courses |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
7. get_users — Search users
Find users by criteria such as email or lastname. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_user_get_users.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_users |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
8. get_users_by_field — Get users by field
Resolve a known list of ids, usernames or email addresses to full user records — the call to use when another system hands you identifiers. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_user_get_users_by_field.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_users_by_field |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
9. list_assignments — List assignments
Assignments in the given courses, with their due dates. Needs courseids[0]-style parameters. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=mod_assign_get_assignments.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_assignments |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
10. list_submissions — List submissions
What students actually handed in, with timestamps and status — the basis of a late-or-missing report. Needs assignmentids[0]-style parameters. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=mod_assign_get_submissions.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. list_submissions |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
11. get_grade_items — Get a course's grade items
The grade breakdown for users in a course — every graded item rather than a single total. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=gradereport_user_get_grade_items.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_grade_items |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
12. get_grades_overview — Get a user's grades across courses
One person's final grade in each of their courses, which is the view an advising or early-alert report wants. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=gradereport_overview_get_course_grades.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_grades_overview |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
13. get_site_info — Check the token and read site identity
Site name, Moodle version, and the functions this token is allowed to call. Call it first when a credential is in doubt — it is the cheapest possible proof that the token, the protocol and the service are all set up. Calls GET /webservice/rest/server.php?moodlewsrestformat=json&wsfunction=core_webservice_get_site_info.
Properties:
| Property | Type | Default | Description |
|---|---|---|---|
operation |
string | — | Required. get_site_info |
host |
string | — | Required. Your Moodle hostname, e.g. moodle.example.edu. Required by every operation. No scheme, no trailing slash, no /webservice path — this connector adds it. |
query |
string | — | Optional. Function parameters as a JSON object string, sent as query parameters. Most functions need them: {"courseid": 42} for list_enrolled_users, {"userid": 7} for list_users_courses, {"field": "shortname", "value": "CPSC-110"} for get_courses_by_field, {"assignmentids[0]": 3} for list_submissions. Moodle's array syntax uses indexed keys such as courseids[0], so write them out literally. |
Published Outputs:
- result — the JSON response body
- status — HTTP status code
Paging
Moodle's web service functions return their full result set in one response and offer no continuation link, so the shared REST executor's paging does not engage and nothing is truncated behind your back.
Where a response would be very large — every course on a busy site, or every submission for a
popular assignment — narrow it at the source with the function's own parameters through query
(get_courses_by_field rather than list_courses, specific courseids rather than all of them)
rather than fetching everything and filtering afterwards.
Notes
Moodle reports failure inside an HTTP 200. A wrong or expired token returns
{"exception": "moodle_exception", "errorcode": "invalidtoken", ...} with a 200 status line.
A connector that judged success by status code alone would call that a success and publish the
error object downstream as though it were course data. This connector detects the error envelope
and fails the step instead. Common errorcode values worth recognising: invalidtoken (bad or
revoked token), accessexception (the function was not added to the external service, or the user
lacks the capability), and webservicesnotenabled.
Moodle's array parameters use indexed keys. Many functions take lists, and they are written out
literally — {"courseids[0]": 42, "courseids[1]": 43}, not a JSON array. This trips up every first
integration.
Ids are site-specific. A course id is meaningful only on the Moodle it came from; resolve
shortnames through get_courses_by_field rather than hardcoding numbers that will not survive a
migration or a test-to-production move.
Not yet proven against a live site. Every function name here is from Moodle's published web services API and the connector compiles and loads, but no operation in this README has been run against a real Moodle instance. Treat it as documented rather than verified until it has.
Self-Contained JAR
The jar bundles all runtime dependencies; only intouch-tool-api is provided by the server.
Publishes
The keys a later task may reference as {{taskName.key}}. Referencing anything not listed here resolves to nothing at run time.
completeoperationresultstatuswarning
Fields not documented above
Generated from this tool's own schema and published outputs on 2026-09-03. A field the README omits is discoverable only by reading the source, and a published key nothing documents is a capability nobody can reference.
Also published: complete, warning