The Enrollment Bug That Almost Ruined Our Migration

Thinkific's REST API returns all enrollments for users in a queried course — not just enrollments for that specific course. We discovered this cross-contamination bug affecting 1,439 records across 13 courses.

What went wrong with enrollment exports

During our first full migration run, the enrollment verification tool flagged inconsistencies. Course A was showing enrollment records that belonged to Course B. The numbers didn't add up — 13 courses had overlapping records that shouldn't have existed.

Root cause: Thinkific's API returns too much data

Thinkific's REST API enrollment endpoint returns all enrollments for every user who is enrolled in the queried course — not just their enrollment for that specific course. If a student is enrolled in 5 courses and you query enrollments for Course A, you get back their enrollment records for all 5 courses. The Thinkific API documentation (opens in new tab) does not explicitly warn about this behavior.

The fix: post-processing filter in EnrollmentBuilder

We added filtering logic to EnrollmentBuilder::buildDocument() that checks each enrollment record's course_id against the target course being exported. Records where the course_id doesn't match are skipped and logged. Simple fix, but without it every course's enrollment file was contaminated with records from other courses.

Verified results: 1,439 clean enrollments

After re-running the export and import with the filter in place, our verification tool showed 69 passed checks with zero failures across all 13 courses. The 1,439 total enrollments were correctly distributed — each enrollment record living only in the course it belonged to.

Last updated: