Sync teachers to your LMS
Goal: the teachers assigned to a course edition in Eduframe have a teaching role in the matching LMS course, and lose it when they are unassigned.
Syncing teachers is optional. Many training businesses manage teacher access in the LMS by hand, because the group is small and changes rarely. Skip this page if that is you. If teachers change often, or if the same person teaches many editions, automating it pays off quickly.
How teachers are modeled
A teacher is a user with the teacher role. Teachers are attached to a course edition through a teacher enrollment, which is separate from the participant enrollments described in Sync enrollments:
| Field | Use it for |
|---|---|
id | External identifier on the LMS enrollment, if the LMS has one. |
planned_course_id | The LMS course to give access to. |
teacher_id | The teacher. This is the user id, so you can fetch the person with GET /api/v1/users/{id} or GET /api/v1/teachers/{id}. |
teacher_role_id | The role of this teacher on this edition, for example trainer, assistant or examiner. Roles are defined per environment; list them with GET /api/v1/teacher_roles. |
List the teachers of one edition with GET /api/v1/planned_courses/{id}/teacher_enrollments, or all teacher enrollments with GET /api/v1/teacher_enrollments?planned_course_id={id}.
{
"id": 731,
"planned_course_id": 4211,
"teacher_id": 5502,
"teacher_role_id": 3,
"updated_at": "2026-09-10T13:40:07.881Z"
}
Map teacher roles to LMS roles
Decide once which Eduframe teacher role becomes which LMS role, and keep that mapping in your middleware's configuration. Unmapped roles should fall back to a read-only role or remain unenrolled.
| LMS | Full teaching role | Assisting role |
|---|---|---|
| Moodle | Teacher (editingteacher) | Non-editing teacher (teacher) |
| Blackboard Learn | Instructor | TeachingAssistant or Grader |
| Canvas | TeacherEnrollment | TaEnrollment |
| Brightspace | Instructor | Teaching assistant |
Eduframe allows you to configure as many teacher roles as needed, allowing you to differentiate LMS access based on the teacher role.
Keep the LMS in sync
Eduframe sends one event when the teachers of an edition change: planned_course.teacher_attendees_changed. It does not say which teacher was added or removed, so treat it as a signal to re-read the list:
- Fetch
GET /api/v1/planned_courses/{id}/teacher_enrollments. - Create the LMS account of every teacher who does not have one yet, exactly as for participants, see Sync users.
- Give every listed teacher the mapped role in the LMS course.
- Remove the teaching role from LMS users who had it but are no longer listed. Keep their account.
Run the same routine when you create the LMS course for a new edition, so teachers assigned before the course came into scope are picked up as well.
Teachers can also be assigned to individual meetings and subevents instead of the whole edition. If you want those teachers in the LMS as well, read the next section.
Include teachers on meetings and subevents
Eduframe lets administrators plan a teacher on the edition, on one of its meetings, or on a subevent of a meeting. Only the first shows up as a teacher enrollment. To get everyone who teaches somewhere in an edition, use the teacher attendees endpoint:
GET /api/v1/teacher_attendees?planned_course_id=4211
It returns one record per teacher with every role and source they are planned with:
[
{
"planned_course_id": 4211,
"teacher_id": 5502,
"roles": [
{ "role_id": 3, "source": "PlannedCourse" },
{ "role_id": 5, "source": "Meeting" }
]
},
{
"planned_course_id": 4211,
"teacher_id": 6110,
"roles": [
{ "role_id": 5, "source": "Planning::Event" }
]
}
]
source tells you where the teacher is planned: PlannedCourse for a teacher enrollment on the edition, Meeting for one of its meetings and Planning::Event for a subevent of a meeting. The endpoint needs the courses:read scope and is in beta.
One teacher, several roles
The same person can be planned more than once in one edition, for example as trainer on the edition and as examiner on a single meeting. Most LMSs allow one role per user per course, so you have to pick one. Eduframe gives no guarantee on the order of the roles array, so do not take the first entry.
Keep an ordered priority list of teacher role ids in your middleware's configuration, from most to least privileged, and resolve each teacher to the highest-priority role that appears anywhere in their roles:
- Configure the priority once, for example
[3, 5, 7]for trainer, examiner, assistant. - For each teacher attendee, collect the
role_idvalues fromroles, ignoringsource. - Pick the one that comes first in your priority list. If none of the roles is in the list, apply your fallback for unmapped roles.
- Map that role to the LMS role as in the table above and enroll the teacher with it.
Because the priority is yours, a teacher who is only an assistant on one subevent gets the assistant role, and a teacher who is trainer anywhere in the edition gets the trainer role, regardless of how Eduframe orders the array.
Keep meeting-level teachers in sync
Changes on any of the three levels fire their own event: planned_course.teacher_attendees_changed, meeting.teacher_attendees_changed and planning_event.teacher_attendees_changed. Handle all three the same way: resolve the planned course, re-read GET /api/v1/teacher_attendees?planned_course_id={id}, recompute each teacher's role and align the LMS course. For meeting and subevent events, fetch the meeting or subevent from the API to find its planned_course_id first.
Webhook events to subscribe to
| Event | What to do |
|---|---|
planned_course.teacher_attendees_changed | Re-read the edition's teacher enrollments and align roles in the LMS. |
meeting.teacher_attendees_changed, planning_event.teacher_attendees_changed | Only when you include meeting-level teachers. Resolve the planned course and re-read its teacher attendees. |
teacher.updated | Optional. Fetch the teacher and update name and email in the LMS, if you do not already handle user.updated. |
teacher.deleted | Remove the teaching role from all LMS courses. |