Migrate your courses.
Keep everything.
API-driven migration from Thinkific and LearnWorlds to WordPress LMS plugins or Laravel. Every video, PDF, quiz, enrollment, and user record — transferred with zero data loss.
"The migration preserved every enrollment date, every quiz, every video. Our students didn't notice a thing — except the site got faster."
Music Education Platform Director — 13 courses, 691 videos migrated from Thinkific to LearnDash
What platforms do we migrate?
We only work with platforms providing full API access to course content, video assets, users, and enrollments. No scraping. No CSV guesswork.
How much does LMS migration cost?
Fixed-price per migration. No hourly billing. You know the total before we start.
How do we protect your video content after migration?
Vimeo-equivalent protection without monthly fees. Seven layers from infrastructure to player. Built on AWS CloudFront.
Engineers, not salespeople
migratelms.com is a deliberately small operation. Every migration is scoped, built, and QA'd by the same two people — the ones whose names are on this page. No account managers, no outsourced work, no hand-offs. If your migration hits a weird Thinkific GraphQL edge case, you're talking to the engineer who'll fix it.
Senior PHP developer specializing in LMS platform architecture, WordPress/LearnDash internals, and AWS infrastructure. Built the Thinkific export pipeline and LearnDash import system from the ground up. Expertise in API integration, video asset migration, and content protection engineering. Brings systems-level engineering experience to make complex migrations reliable, repeatable, and easier to validate.
Senior WordPress developer and instructional designer specializing in LMS migrations, course architecture, and content modeling. Experienced with WordPress internals, LearnDash structures, Thinkific APIs, course access logic, block editor workflows, and accessibility. Brings technical judgment and a course-builder’s perspective to preserve course flow, learner experience, and long-term maintainability.
Because the team is two engineers, we take on a limited number of migrations at a time. That means your project gets real attention, not a runbook handed to a junior. Read more about the team →
Which LMS platform is right for you?
Migration engineering insights
How We Migrated 691 Videos from Thinkific to S3 Without Vimeo
Thinkific's GraphQL API exposes direct MP4 CDN URLs through VideoContent types. Here's how we used that to bypass Vimeo entirely and migrate 691 course videos to self-hosted S3 with CloudFront delivery.
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.
Why Vimeo Upload Quotas Make S3 the Better Choice for Course Videos
At $65/month, Vimeo Advanced limits you to 240 video uploads per year per seat. With 1,000+ course videos, that's nearly two years of uploading. S3 has no upload limits and costs a fraction per GB.
Video Protection Without DRM: A Layered Approach for Course Creators
Full DRM is overkill for educational content. Here's our layered stack: S3 bucket policies with referrer restrictions, HTML5 controlsList attributes, CloudFront signed cookies, and player-level hardening.
Frequently asked questions about LMS migration
A typical migration with 50–100 lessons and under 500 enrollments completes in 2–3 business days. Larger catalogs with 500+ lessons and thousands of enrollments take 5–7 business days. Our pipeline is automated — the bottleneck is verification and QA, not the migration itself.
Yes. We extract video URLs directly from your source platform's API — including Thinkific's GraphQL VideoContent endpoints that expose direct MP4 CDN links. Videos are migrated to your own AWS S3 bucket with CloudFront delivery, eliminating monthly hosting costs and upload quota restrictions.
No. We migrate all enrollment records with original start dates, expiration dates, and enrollment keys intact. We run the migration on staging first, verify every enrollment, then cut over — zero downtime.
Full quiz migration including question types, answer options, and scoring logic. We map source quiz formats to your destination platform's native quiz engine — LearnDash ProQuiz, LifterLMS quizzes, or Tutor LMS assessments.
Layered protection: S3 bucket policies with referrer restrictions, HTML5 controlsList to disable downloads, optional CloudFront signed cookies for session-based access, and player-level hardening. Vimeo-equivalent protection without the monthly fees.
Yes. LearnWorlds provides a REST v2 API with OAuth2 covering courses, users, enrollments, progress, assessments, and certifications across 15+ endpoint categories — comparable to Thinkific's depth.
Absolutely. Laravel destinations are simpler than WordPress — you control the database schema directly with Eloquent. No plugin quirks, no hook conflicts. We also support Academy LMS and Edulab LMS as pre-built Laravel destinations.
Everything: course structures, video content migrated to S3, PDFs and downloads, quizzes and assessments, user accounts matched by email, enrollment records with date ranges, and S3/CloudFront infrastructure setup with video protection.
Their APIs don't expose lesson-level content or video URLs. Teachable's public API covers courses and enrollments but not lesson content. Kajabi has no documented public API. We only migrate from platforms where API access guarantees complete, reliable data extraction — no scraping.
Fixed-price per migration: a volume tier sets the base price, and any à la carte add-ons stack on top. Volume tiers — Starter: $1,500–$3,000 for 1–5 courses (hosted video with basic protection, migration audit report). Professional: $3,000–$7,500 for 5–20 courses (player-locked videos, CDN-accelerated playback). Enterprise: $7,500+ for 20+ courses (per-student secure video access, custom destination integration, priority support). Add-ons available at any tier — quiz migration ($50/quiz, capped at $1,500), 30/60/90-day post-launch watch ($500/$900/$1,200), dedicated Slack channel ($250/month with 30-day minimum), multi-site setup ($2,000), custom in-house destination (starts at $1,500). To get a quote, email hello@migratelms.com with your source platform, destination, course count, video count, and enrolled user count. Quote delivered within 24 hours. Or book a free 15-minute scoping call at calendly.com/mgratch/consultation.
CSV exports lose course structures, quiz logic, and video associations. Manual rebuild is impractical beyond 10 lessons. Scraping breaks when the platform updates and often violates terms of service. API extraction pulls the exact same structured data the platform uses internally — complete, accurate, and reliable.
Three ways to start: (1) Email hello@migratelms.com with your source platform (Thinkific or LearnWorlds), destination platform, number of courses, number of videos, and number of enrolled users — we'll send a fixed-price quote within 24 hours. (2) Fill out the form at migratelms.com/contact with the same information. (3) Book a free 15-minute scoping call at calendly.com/mgratch/consultation. Every migration starts with a fixed-price quote — no hourly billing, no commitments until you approve the scope.
Yes — but only if your migration tool understands the data-model mismatch. In Thinkific a quiz is a lesson type (curriculum-peer to videos and PDFs); in LearnDash sfwd-quiz is a separate post type that attaches to a lesson. We handle this with the quiz-holder lesson pattern: each Thinkific quiz becomes an sfwd-lessons placeholder with the sfwd-quiz attached to it, preserving the original reading order. Naive importers that don't bridge this silently drop every quiz.
Quiz questions, answers, and scoring logic — yes, fully. Per-student quiz attempt history and lesson-by-lesson completion progress — usually no, and we recommend against it. The work to reliably map every historical attempt to LearnDash's user-quiz-meta serialized format costs more than rebuilding it is worth for most clients, and the data is rarely used after the cutover. We have done it on request for compliance-regulated content; budget on it accordingly.
No — Thinkific's password hashes are not portable to WordPress's hashing scheme. We assign each imported user a random WordPress password and send a friendly one-time password-reset email at cutover ("Your courses moved! Set your password to continue."). In our experience 60–75% of users complete the reset within the first 48 hours.
Thinkific's GraphQL has two ceilings: 1000 cost-units per query and 2000 cost-units per rolling minute. Our exporter paces queries automatically, tunes the `first` argument on each Connection to stay under per-query budget (we run lessonFirst around 40, chapterFirst around 30), and splits course-structure exports from data-exports across separate runs when needed. Rate-limit cascades — where every course after the first fails because the first burned the minute budget — are handled by spacing, not retrying.
We render PDFs inline via PDF.js with the text layer enabled, which makes content available to screen readers and search-in-page. If the source PDFs are tagged (have a StructTreeRoot), full semantic structure is preserved. If they're untagged — common for older course materials — we can render them readably but cannot retroactively add accessibility markup. If your courses require WCAG-compliant PDFs, plan on a remediation pass with a tool like Adobe Acrobat Pro before launch.
Yes — duplicate-email handling is one of the first things we configure with you. Our default rule: if a WordPress user with matching email already exists, keep their existing first name, last name, role, and registration date. Add Thinkific data only where WP has empty fields. The original Thinkific user ID is persisted to user meta (_tf_user_id) so re-runs find the same user reliably even if email changes later.
We back-date course access in LearnDash to the original Thinkific activation date. If a student bought a 1-year subscription on July 15 and the migration runs in October, LearnDash records them as having accessed since July 15 — so their access expires the following July, not a year from migration day. This is done through `ld_update_course_access()` (the LearnDash API), not direct postmeta writes, because LearnDash recalculates internal state and direct writes get clobbered.
Ready to migrate?
Fixed-price quote within 24 hours. Or book a free 15-minute scoping call.