Setting Up a Moodle REST API Webservice in Five Steps

Moodle ships with a full web-services layer, but the admin flow for handing out a single API token is spread across half a dozen settings pages. The first time you do it, you’ll click around for twenty minutes wondering why your token keeps returning invalidtoken. 🔐 Here’s the short version I keep in my notes so I never have to rediscover it.

The goal: a token that lets an external client call exactly one function — core_webservice_get_site_info — over the REST (Representational State Transfer) protocol. Lock it down to one function and one user, and you have a safe little health-check endpoint you can curl from anywhere.

The five steps

1. Create the user. Site Administration → Users → Accounts → Add a new user. This is the identity the token acts as, so give it only the capabilities it needs — a dedicated service account beats reusing a human login.

2. Create the external service. Site Administration → Server → Web services → External services → Add. Name it (e.g. “Test API”), tick Enabled, and tick Authorised users only. That last checkbox is the one everyone forgets — without it, your carefully-scoped service is open to any token holder.

3. Add functions to the service. On the External services list, click Functions next to your new service, then Add functions, search for core_webservice_get_site_info, and save. Only the functions you add here are callable — this is your allowlist.

4. Authorise the user. Back on the External services list, click Authorised users and move your service account from the right column to the left. Because you ticked Authorised users only in step 2, skipping this means every call returns accessexception. 🙃

5. Generate the token. Site Administration → Server → Web services → Manage tokens → Add. Pick your user, map them strictly to your new external service, and copy the token it gives you.

Calling it

Three parameters and you’re done — the token, the function name, and the response format. No headers, no OAuth dance:

1
2
3
4
curl -X POST "https://moodle.example.com/webservice/rest/server.php" \
     -d "wstoken=YOUR_TOKEN_HERE" \
     -d "wsfunction=core_webservice_get_site_info" \
     -d "moodlewsrestformat=json"

A healthy response echoes the site name, your user details, the Moodle release, and the list of functions the token is allowed to call:

1
2
3
4
5
6
7
8
9
10
11
12
{
  "sitename": "My Learning Site",
  "username": "apiservice",
  "firstname": "API",
  "lastname": "Service",
  "userid": 42,
  "release": "4.5.3 (Build: 20250317)",
  "version": "2024100703",
  "functions": [
    { "name": "core_webservice_get_site_info", "version": "2024100703" }
  ]
}

That functions array is the quickest way to confirm your allowlist took effect — if it’s empty or missing the function you expected, you skipped step 3.

One last thing worth saying out loud: a Moodle web-service token is a credential. It acts as the user you mapped it to, for every function you allowed. Treat it like a password — keep it out of version control, scope it to a throwaway account on dev environments, and rotate it the moment it leaks. A token committed to a repo is a token you no longer control. 🍻

This entry was posted in Moodle and tagged , . Bookmark the permalink.

Comments are closed.