Skip to main content

Sync courses and editions to your LMS

Goal: every course edition that participants can enroll in exists as a course in your LMS, named consistently, with the right dates, and is closed when the edition is canceled or completed.

Which object becomes an LMS course​

Create one LMS course per planned course (course edition). Use the parent course (template) for the name, code and description; use the planned course for dates, status and participants. See the data model if the distinction is new to you.

Only planned courses whose template is in scope get an LMS course. How you mark a template as in scope is described in Which courses get an LMS course. Check the marker in your middleware on every planned_course.* and enrollment.* event and ignore records that are out of scope.

If your LMS groups courses in a hierarchy, place the course in the node you chose in Where courses live in the LMS hierarchy.

Recommended LMS course name: <course name> - <start date or edition label>, for example Project management basics - 2026-10-05. Store the planned course id in the LMS course's external identifier field.

Fields to map​

From GET /api/v1/courses/{id}:

FieldUse it for
idLook up the template; store it if you group LMS courses by template.
nameLMS course name.
codeLMS course short name or code prefix.

From GET /api/v1/planned_courses/{id}:

FieldUse it for
idExternal identifier of the LMS course.
course_idLink to the template above.
typeFixedPlannedCourse has dates; FlexiblePlannedCourse is self-paced and gets access windows per enrollment.
statusplanned, active, completed or canceled. Create for planned and active; close or hide for completed; deactivate for canceled.
start_date, end_dateLMS course start and end date. Empty for flexible planned courses.
external_content_urlThe LMS course URL you write back later, see Show the LMS course link.

Trimmed example:

{
"id": 4211,
"course_id": 87,
"type": "FixedPlannedCourse",
"status": "planned",
"start_date": "2026-10-05",
"end_date": "2026-10-07",
"external_content_url": null,
"updated_at": "2026-09-12T09:41:03.120Z"
}

Webhook events to subscribe to​

EventWhat to do
planned_course.createdFetch the planned course and its course, create the LMS course.
planned_course.updatedFetch and update name, dates and status.
planned_course.canceledDeactivate or hide the LMS course; unenroll or deactivate its participants.
planned_course.deletedSame as canceled. Keep the LMS course for history unless it was never used.
course.updatedThe template was renamed or recoded; update every LMS course created from its planned courses.
course.deletedIts planned courses are gone too; treat like canceled.

Optional, if you also mirror meetings into an LMS calendar: meeting.created, meeting.updated, meeting.deleted, and GET /api/v1/planned_courses/{id}/meetings.