Back to all articles
Syncing Moodle Course Progress into Salesforce with the Web Services API
SalesforceMoodleIntegrationApexEducationStudent Success

Syncing Moodle Course Progress into Salesforce with the Web Services API

Your LMS knows exactly how far each student has progressed, but that number is stuck in Moodle. Here is how to pull course progress into Salesforce on a schedule with Moodle's Web Services API, and the design choices that keep the data trustworthy.

Mitesh Jain September 11, 2026 7 min read

If you run Moodle alongside Salesforce, your student success or support team probably has the same complaint: the CRM knows the student's grades and last login, but not how far through the course they actually are. That progress percentage is the number a coach reaches for first, and it is stuck in the LMS.

You can fix that with a scheduled sync built on Moodle's Web Services API. Here is how it works, and the design choices that decide whether the result is trustworthy or just more noise.

The gap: the CRM has everything except progress

Many Moodle-to-Salesforce setups already push some data across: GPA, lesson numbers, last login. What they usually miss is course-progress percentage, because it is a computed value rather than a stored field. So a coach who wants to know "is this student keeping up?" has to leave Salesforce, open Moodle, and check course by course. That does not scale across a caseload, and it hides the earliest sign of disengagement in a system the coaching team does not live in.

Moodle's Web Services API in brief

Moodle exposes a REST API through its Web Services layer. To use it you:

  1. Enable web services and the REST protocol in Moodle.
  2. Create a token tied to a service and a role with only the functions you need.
  3. Call REST functions such as core_enrol_get_users_courses to list a user's courses, and the grade-report functions to read progress and grades per course.

Each call is an HTTP request with the token, the function name, and parameters such as the Moodle user id. You get JSON back.

The sync pattern

A reliable design is a weekly scheduled Apex batch:

  1. Match students to Moodle users on an identifier you already store on the contact (the Moodle user id), so nothing has to be re-keyed.
  2. Read progress for each student's relevant courses from the Web Services API.
  3. Write the progress percentage onto the Salesforce records your team already reports from.
  4. Schedule it to run on the cadence your reviews actually use, weekly is usually plenty.

Batch it so you respect both Salesforce governor limits and Moodle's load, and log failures so a bad week is visible rather than silent.

Update, do not create

This is the design decision that matters most. If a push already creates the records your team reports from, do not create a second, parallel set. Instead, match the existing records and update only the field you are adding (the progress percentage). Two writers on the same field produce disagreeing numbers in reports, so contribute only what nothing else supplies, and let each field keep a single source. It is less code and far more trustworthy.

Design choices that matter

  • Send the token in the request body, not the URL. A token in a query string ends up in Moodle's web-server access logs. In the POST body it does not.
  • Make the course list configuration, not code. Programs and courses change every term. Drive the sync from a custom setting or custom metadata so a new course is a configuration change, not a deployment.
  • Parse progress defensively. Moodle grade and progress values come back as strings in varied formats. Extract the percentage with a tolerant parser rather than assuming one shape.
  • Respect security. Read only what you need with a scoped token and role, and keep the whole thing on-platform so no student data leaves your systems beyond the Moodle call itself.

Frequently asked questions

Can Salesforce read data from Moodle automatically?

Yes. Moodle's Web Services REST API lets Salesforce Apex read courses, grades, and progress on a schedule, then write the values onto Salesforce records so teams see them without logging into Moodle.

Which Moodle Web Services functions return course progress?

core_enrol_get_users_courses lists a user's courses, and the grade-report functions (such as the course-grades overview) return the grade and progress values you parse into a percentage. Completion-status functions exist too, but only work when courses have completion criteria configured.

Should the sync create new Salesforce records or update existing ones?

Update existing ones wherever a push already creates them. Contribute only the field you are adding, so each field has a single source and reports never show two disagreeing numbers.

How often should Moodle progress sync to Salesforce?

Match the cadence of your actual reviews. For most student-success and support workflows a weekly scheduled batch is enough, and it keeps load on both systems low.

From a manual check to a weekly sync

We built this for a university whose success coaches were checking progress in Moodle by hand, and brought weekly course progress onto every student record in Salesforce. The full story is in our Moodle progress-sync case study.

If your team's data is stranded in an LMS or another platform, we can bring it into Salesforce natively and keep it in sync. Book a free consultation.

MJ

Mitesh Jain

Salesforce consultant with 10 years of Sales and Service Cloud implementation experience.

Want to Learn More About Our Salesforce Solutions?

Explore how our expertise can help your business grow.

Get in Touch