Sync Thinkific enrollments into HubSpot contacts

Every 15 minutes, push new Thinkific course enrollments into HubSpot as fresh contacts so sales and lifecycle automations see real course activity.

Deterministic Code
ThinkificHubSpotSalesOperationsData SyncLead EnrichmentOnboarding Automation

Build a code workflow that syncs new Thinkific course enrollments into HubSpot as contacts. The flow is deterministic with no judgement steps. No agent reasoning is needed because the field mapping is 1:1.

Trigger: cron, every 15 minutes. Thinkific is not in the poll providers catalog, so a cron plus list pattern is the correct shape. Keep track of the last successful run timestamp in workflow state so each run only processes enrollments created since the previous run.

Step 1. Call Thinkific List Enrollments with a date filter scoped to enrollments created since the previous run timestamp. Paginate until all new enrollments for the window have been collected.

Step 2. For each new enrollment, call Thinkific Get User by ID using the user_id on the enrollment to fetch the student's first name, last name, and email.

Step 3. Build a single batch payload of contacts, one entry per unique email seen in this run. If the same student appears on multiple enrollments in the same window, collapse them into one entry and use their most recent enrollment as the source of last_thinkific_course and last_enrollment_date. Compute total_thinkific_enrollments as the running total per student. The simplest correct approach is to read the current value of total_thinkific_enrollments from HubSpot via Batch Read Contacts before incrementing, so the count survives across runs. If the property is empty for a contact, treat it as zero.

Step 4. Call HubSpot Batch Upsert Contacts keyed on the email property. Write standard fields firstname, lastname, email, plus three custom contact properties: last_thinkific_course (string, the course name from the enrollment), last_enrollment_date (date, the enrollment created_at), and total_thinkific_enrollments (number). Use a single batch upsert per run, not per contact calls. HubSpot batch endpoints accept up to 100 inputs per call, so chunk if the window has more than 100 unique emails.

Step 5. On success, advance the stored last successful run timestamp to the start time of the current run. On failure, do not advance the cursor so the next run retries the same window.

Notes for the author. The three HubSpot custom properties (last_thinkific_course, last_enrollment_date, total_thinkific_enrollments) must already exist on the Contact object. Mention this in the setup notes the workflow surfaces to the user. Respect rate limits: Thinkific allows 120 requests per minute, HubSpot search is 4 per second, and HubSpot batch endpoints share the standard 110 per 10 seconds OAuth burst limit. Surface a clear log line per run with the count of enrollments processed and the count of contacts upserted so the user can sanity check it from the run history.

Additional information

What does this prompt do?
  • Checks Thinkific every 15 minutes for any new course enrollments since the last run.
  • Looks up the student behind each enrollment and grabs their name and email.
  • Creates or updates the matching HubSpot contact in one batch, keyed on email, so the same person never gets duplicated.
  • Writes the latest course, the date they enrolled, and a running count of total Thinkific enrollments onto the contact so your CRM views and workflows can use them.
What do I need to use this?
  • A Thinkific admin account so we can read enrollments and student profiles.
  • A HubSpot account where you can create or update contacts.
  • Three custom contact properties in HubSpot: last Thinkific course, last enrollment date, and total Thinkific enrollments. You can create them in HubSpot settings in a couple of minutes.
How can I customize it?
  • Change how often it runs. Every 15 minutes is the default, but you can dial it down to hourly if you do not need near real time.
  • Filter which courses count. For example, only sync paid courses, or skip a free intro course you do not want cluttering the CRM.
  • Tag enrolled contacts with a HubSpot lifecycle stage or list membership so your sales and marketing automations can act on them automatically.

Frequently asked questions

Will this create duplicate HubSpot contacts if a student enrolls in more than one course?
No. We match contacts on email, so the same student gets updated in place. Their last course, last enrollment date, and total enrollment count just keep refreshing.
Does this work on HubSpot Free?
Yes for the core sync. The contact create or update behavior works on every HubSpot tier. You will need custom contact properties, which are available on Free, but very large catalogs of properties are a paid feature.
What happens to existing students who enrolled before I turned this on?
By default the sync only picks up enrollments going forward. If you want to backfill history, you can run a one off catch up the first time, then let the 15 minute schedule take over.
Can I send the new enrollment to Slack or email at the same time?
Yes. This prompt focuses on the HubSpot sync, but you can extend the same workflow to post a Slack message or send a welcome email when a new enrollment lands.
What if a student updates their email in Thinkific?
The sync uses whatever email Thinkific currently has on file. If a student changes their email, future enrollments will land on the new email in HubSpot. You may end up with two contacts unless you merge them manually.

Stop manually copying Thinkific signups into HubSpot.

Connect Thinkific and HubSpot once, and Geni keeps your CRM in sync with every new course enrollment.