Mapping Thinkific Users to WordPress When You Already Have a User Base

If WordPress already has users — newsletter subscribers, blog commenters, old students — you can't just bulk-insert Thinkific users. Email collisions are the rule, not the exception. Here's the merge policy we use.

Why email is the only safe match key

Names collide constantly. Two real users named 'Sarah Johnson' is normal. Two real users with the same email address is essentially impossible — most email providers don't allow it, and the rare case where two people share a corporate alias is something you want to flag, not silently merge. Match on `user_email` (case-insensitive) and treat any collision as 'this is the same person on two platforms,' not 'two different people who happen to share an inbox.'

WP wins for existing fields, Thinkific fills gaps

The rule that's worked across every migration we've done: if a WordPress user with matching email already exists, keep their existing first name, last name, display name, role, and registration date. Add Thinkific data only where WP has empty fields. Concrete example: WP user is 'Rob' with no last name, Thinkific has 'Robbie Smith.' Result: 'Rob Smith.' The user typed 'Rob' deliberately on WP; we don't overwrite that with the marketing-form name from Thinkific. But the missing last name was a gap, so we filled it.

Preserve Thinkific IDs in user meta

Every imported user gets `_tf_user_id` (numeric) and optionally `_tf_user_gid` (the GraphQL ID) added to wp_usermeta. This is the key that lets you re-run the import idempotently — second pass on the same Thinkific user finds them via meta query, not via email search, which is faster and survives email changes. It also lets you reverse-trace 'which WP user is this Thinkific record?' for audit.

Passwords don't migrate (and that's fine)

Thinkific stores password hashes you cannot decrypt. WordPress hashes are not portable from Thinkific's algorithm. The right answer is: every imported user gets a randomly generated WordPress password and a one-time password-reset email at cutover, with a friendly explainer ('Your courses moved! Set your password to continue.'). We've sent this exact email at five client launches; the reset-completion rate ran 60–75% in the first 48 hours each time, and the support load was lower than the platform migration itself.

Don't import users with no real activity

Free signups with no enrollment, no login, no anything are dead weight in your wp_users table. Our default exporter behavior is to include all users so the client can decide; our default importer behavior is to filter out users with zero enrollments AND no login history AND no purchase. The client can override per-project — for one Theory Time-style content business, the founder asked us to import everyone because their email list lived on Thinkific. For another, the client asked us to import only paying customers. Don't pre-decide; let the project decide.

Custom profile fields need a mapping plan

Thinkific schools usually have a handful of custom profile fields ('Instrument', 'School Name', 'Music Teacher Email'). These come through `GET /custom_profile_field_definitions` (REST-only) with stable field IDs. We map each to a WordPress user meta key the client confirms in advance — `_tf_instrument` is fine for internal use, but if the client's theme renders 'Instrument' on a public profile page, it needs to be a key their theme already understands. This is a 30-minute conversation that prevents three hours of post-launch find-and-replace.

Last updated: