Integrate Thinkific with Lovable by creating an Edge Function that proxies Thinkific's REST API using your API key stored in Cloud → Secrets. You can build custom course storefronts, student progress dashboards, and enrollment flows. Thinkific's REST API covers courses, enrollments, users, and orders — making it well-suited for white-label education portals built on top of your existing Thinkific school.
Build custom Thinkific frontends and dashboards in Lovable
Thinkific is one of the most popular self-hosted course platforms, offering a strong free tier and a REST API that covers the core data model: courses, enrollments, users, and orders. While Thinkific provides its own storefront and student portal, many course creators want a fully branded experience — a custom marketing site, a white-labeled student dashboard, or an internal learning management view built exactly to their specification. That is exactly what this integration enables.
In Lovable, the integration follows the standard edge function pattern for authenticated APIs: your Thinkific API key lives encrypted in Cloud → Secrets, a Deno Edge Function acts as a server-side proxy to Thinkific's REST API, and your React frontend calls the Edge Function rather than Thinkific directly. This eliminates CORS errors, keeps your credentials invisible to users, and gives you full control over how Thinkific data is shaped and displayed.
Thinkific's REST API uses simple API key authentication — you include your subdomain and API key as request headers on every call. There is no OAuth dance, no token refresh, and no user-level auth required for most read operations. This makes it one of the more straightforward education platform APIs to integrate. The main complexity comes from correctly mapping Thinkific's data model (courses have chapters, chapters have contents, enrollments link users to courses) to the UI components you want to build in Lovable.
Integration method
Thinkific does not have a Lovable shared connector, so all API calls are routed through a Supabase Edge Function running on Deno. Your Thinkific API key is stored encrypted in Cloud → Secrets and accessed server-side via Deno.env.get(), keeping credentials out of your frontend entirely. The Edge Function acts as a secure proxy between your Lovable app and the Thinkific API.
Prerequisites
- A Lovable account with at least one project created and deployed
- A Thinkific account (free tier is sufficient for API access) with at least one published course
- Your Thinkific API key from Settings → Code & API → API Key in your Thinkific admin panel
- Your Thinkific subdomain (the part before .thinkific.com in your school URL)
- Basic familiarity with how Lovable's Cloud tab and Secrets panel work
Step-by-step guide
Store your Thinkific credentials in Cloud → Secrets
Store your Thinkific credentials in Cloud → Secrets
Before writing any code, store your Thinkific API key and subdomain as encrypted secrets in Lovable. These credentials will be accessed by your Edge Function via Deno.env.get() and will never appear in your frontend code, your GitHub repository, or your chat history. To access the Secrets panel, click the '+' icon at the top of the Lovable editor next to the Preview label. This opens the Cloud panel with tabs for Database, Auth, Storage, Edge Functions, AI, Secrets, Logs, and Usage. Click the Secrets tab. Click 'Add new secret' and add two secrets: - Name: THINKIFIC_API_KEY — Value: your Thinkific API key (a long alphanumeric string found in your Thinkific admin panel under Settings → Code & API → API Key) - Name: THINKIFIC_SUBDOMAIN — Value: your school's subdomain (e.g., if your school URL is myschool.thinkific.com, the subdomain is myschool) To find your API key in Thinkific, log in to your admin panel, click your account name in the top-right corner, go to Settings, then scroll down to the Code & API section. Click 'API' and you will see your API key. Click 'Show' to reveal the full key, then copy it. Critical: Never paste API keys directly into Lovable's chat prompt. On the free tier, chat history is publicly visible, and keys pasted in chat can end up in your Git commit history. Lovable's security system blocks approximately 1,200 hardcoded API keys per day — use the Secrets panel to avoid the risk entirely.
Pro tip: Your Thinkific subdomain is always lowercase and contains no spaces. If your school URL is https://learn.mybusiness.com (a custom domain), check your Thinkific admin panel URL — it still uses the original subdomain for API calls.
Expected result: Two secrets — THINKIFIC_API_KEY and THINKIFIC_SUBDOMAIN — appear in the Cloud → Secrets panel with masked values. These are now accessible from Edge Functions via Deno.env.get('THINKIFIC_API_KEY') and Deno.env.get('THINKIFIC_SUBDOMAIN').
Create the Thinkific API proxy Edge Function
Create the Thinkific API proxy Edge Function
With secrets stored, the next step is creating the Edge Function that will proxy all requests from your Lovable frontend to the Thinkific REST API. This function handles authentication by injecting your API key and subdomain as request headers, routes requests to the correct Thinkific endpoint, and returns the data to your frontend. Paste the following prompt into Lovable's chat to generate the Edge Function: 'Create a Supabase Edge Function at supabase/functions/thinkific-api/index.ts that acts as a proxy to the Thinkific REST API. It should accept a POST request with a JSON body containing: endpoint (e.g., /v1/courses), method (GET/POST/PUT), and optionally body data. The function should read THINKIFIC_API_KEY and THINKIFIC_SUBDOMAIN from environment variables and call https://{subdomain}.thinkific.com/api/public/{endpoint} with the headers: X-Auth-Token (the API key) and X-Auth-Subdomain (the subdomain). Return the Thinkific API response as JSON. Include proper CORS headers so the frontend can call it.' After Lovable generates the Edge Function, open the Code panel and review the generated file at supabase/functions/thinkific-api/index.ts. Verify that the function uses Deno.env.get() to read credentials (not hardcoded values), that CORS headers include the correct origins, and that error responses return meaningful HTTP status codes. The Thinkific API base URL is https://{subdomain}.thinkific.com/api/public — note that it uses /api/public for public/read endpoints and some authenticated endpoints. All requests must include both X-Auth-Token and X-Auth-Subdomain headers. The API follows standard REST conventions: GET for reads, POST for creates, PUT for updates, DELETE for removals.
Create a Supabase Edge Function at supabase/functions/thinkific-api/index.ts that acts as a proxy to the Thinkific REST API. It should accept a POST request with a JSON body containing: endpoint (e.g., /v1/courses), method (GET/POST/PUT), and optionally body data. The function should read THINKIFIC_API_KEY and THINKIFIC_SUBDOMAIN from environment variables and call https://{subdomain}.thinkific.com/api/public/{endpoint} with the headers: X-Auth-Token (the API key) and X-Auth-Subdomain (the subdomain). Return the Thinkific API response as JSON with proper CORS headers.
Paste this in Lovable chat
1// supabase/functions/thinkific-api/index.ts2const corsHeaders = {3 'Access-Control-Allow-Origin': '*',4 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',5};67Deno.serve(async (req) => {8 if (req.method === 'OPTIONS') {9 return new Response('ok', { headers: corsHeaders });10 }1112 try {13 const apiKey = Deno.env.get('THINKIFIC_API_KEY');14 const subdomain = Deno.env.get('THINKIFIC_SUBDOMAIN');1516 if (!apiKey || !subdomain) {17 return new Response(18 JSON.stringify({ error: 'Thinkific credentials not configured' }),19 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }20 );21 }2223 const { endpoint, method = 'GET', body: requestBody } = await req.json();2425 const thinkificUrl = `https://${subdomain}.thinkific.com/api/public${endpoint}`;2627 const fetchOptions: RequestInit = {28 method,29 headers: {30 'X-Auth-Token': apiKey,31 'X-Auth-Subdomain': subdomain,32 'Content-Type': 'application/json',33 },34 };3536 if (requestBody && method !== 'GET') {37 fetchOptions.body = JSON.stringify(requestBody);38 }3940 const response = await fetch(thinkificUrl, fetchOptions);41 const data = await response.json();4243 return new Response(JSON.stringify(data), {44 status: response.status,45 headers: { ...corsHeaders, 'Content-Type': 'application/json' },46 });47 } catch (error) {48 return new Response(49 JSON.stringify({ error: error.message }),50 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }51 );52 }53});Pro tip: Thinkific's API rate limit is 100 requests per minute per API key. If you are building a dashboard that loads multiple data sets on page load, consider batching your requests or implementing client-side caching to avoid hitting the limit.
Expected result: Lovable generates and deploys the Edge Function. It appears in the Code panel under supabase/functions/thinkific-api/index.ts. The Cloud tab's Edge Functions section shows it as active.
Build the course catalog frontend component
Build the course catalog frontend component
With the Edge Function deployed, you can now build the React frontend components that call it. The pattern is straightforward: your React component makes a POST request to the Edge Function URL, passes the desired Thinkific endpoint path, and renders the returned data. Paste this prompt into Lovable's chat to generate a course catalog component: 'Create a React component called ThinkificCourseGrid that fetches all published courses from our Thinkific API Edge Function. Call the Edge Function at /functions/v1/thinkific-api with body { endpoint: "/v1/courses?page=1&limit=25" }. Display the courses in a responsive grid showing: course thumbnail image (course_card_image_url field), course title (name), short description (first 120 characters of description), price (from product.price with currency symbol), and an Enroll button that links to course.slug on your Thinkific school domain. Add a loading skeleton state and an error state. Use Tailwind CSS for styling.' Thinkific's courses endpoint returns a paginated response with items array containing course objects. Key fields to use in your UI: name (course title), description (HTML — strip tags for short preview), course_card_image_url (thumbnail), slug (URL path), product.price (price in cents — divide by 100 for display), and product.hidden (filter these out from public catalog). For enrollment status, you will need to call the /v1/enrollments endpoint filtered by user ID. This requires knowing the Thinkific user ID for the logged-in user, which you can look up via the /v1/users endpoint filtered by email. Consider storing the Thinkific user ID in your Supabase user profile table after the first lookup to avoid repeated API calls. For complex dashboard builds or when you need help mapping Thinkific's API response structure to your custom UI, RapidDev's team can assist with configuring multi-step data flows that combine Thinkific course data with your own Supabase database tables.
Create a React component called ThinkificCourseGrid that fetches all published courses from our Thinkific API Edge Function at /functions/v1/thinkific-api with body { endpoint: '/v1/courses?page=1&limit=25', method: 'GET' }. Display courses in a responsive card grid showing thumbnail, title, description preview, price, and an Enroll button. Add loading skeleton and error states with Tailwind CSS styling.
Paste this in Lovable chat
Pro tip: Thinkific course descriptions are HTML strings. Use a simple regex or DOMParser to strip HTML tags before displaying a plain-text preview: description.replace(/<[^>]*>/g, '').slice(0, 120) + '...'
Expected result: A course catalog component appears in your Lovable app showing real courses from your Thinkific school with thumbnails, titles, prices, and enroll buttons. The data loads from the live Thinkific API via your Edge Function proxy.
Set up Thinkific webhooks for real-time enrollment events
Set up Thinkific webhooks for real-time enrollment events
Thinkific supports webhooks that fire when key events occur: enrollment creation, enrollment completion, course completion, and payment events. Setting up a webhook receiver in Lovable lets your app react in real time — updating a progress dashboard, sending a congratulations email, or marking a user as qualified in your database — without polling the Thinkific API. First, create a webhook receiver Edge Function in Lovable. Paste this prompt: 'Create a Supabase Edge Function at supabase/functions/thinkific-webhook/index.ts that receives POST requests from Thinkific webhooks. The function should parse the JSON body, check the X-Thinkific-Webhook-Token header against a THINKIFIC_WEBHOOK_TOKEN secret, and handle these event types: learner.enrolled (store enrollment in Supabase enrollments table), learner.completed_lesson (update progress), learner.completed_course (mark as complete and trigger a congratulations action). Return 200 OK for all valid events.' After Lovable generates the function, add a new secret: THINKIFIC_WEBHOOK_TOKEN — set a long random string (you will use this same value in the Thinkific webhook configuration). Deploy your app via the Publish button. Copy the Edge Function URL — it follows the pattern https://[project-ref].supabase.co/functions/v1/thinkific-webhook. In your Thinkific admin panel, go to Settings → Code & API → Webhooks. Click 'Add new Webhook'. Enter your Edge Function URL. Set the Token to the same value you stored as THINKIFIC_WEBHOOK_TOKEN. Select the events you want to receive. Save. Thinkific sends webhooks as POST requests with a JSON body. The X-Thinkific-Webhook-Token header contains the token for verification. Unlike Stripe, Thinkific does not use HMAC signature verification — it uses a simple token match, so store a strong random string and check it carefully in your Edge Function.
Create a Supabase Edge Function at supabase/functions/thinkific-webhook/index.ts that receives Thinkific webhook events. Check the X-Thinkific-Webhook-Token header against the THINKIFIC_WEBHOOK_TOKEN secret. Handle learner.enrolled events by upserting a record in a Supabase enrollments table (user_email, course_id, course_name, enrolled_at). Handle learner.completed_course events by updating the enrollment record with completed_at timestamp. Return 200 for valid events.
Paste this in Lovable chat
Pro tip: Test your webhook by using Thinkific's 'Send test notification' feature in the webhook settings, or by manually enrolling a test student in a free course in your Thinkific school and watching Cloud → Logs for the incoming event.
Expected result: The webhook Edge Function is deployed and its URL is registered in Thinkific's webhook settings. When a student enrolls in a course, a record appears in your Supabase enrollments table within seconds. Cloud → Logs shows the incoming webhook events.
Add enrollment management to your Lovable app
Add enrollment management to your Lovable app
The final step is wiring up the enrollment flow so users can enroll in courses directly from your Lovable app rather than being redirected to Thinkific's storefront. Thinkific's enrollment API lets you programmatically create enrollments via POST /v1/enrollments — useful for gating content behind your own authentication, offering discounts through your own pricing logic, or providing B2B bulk enrollment. Paste this prompt into Lovable's chat: 'Add an enrollment flow to my app: when a user clicks the Enroll button on a course card, first check if they are already enrolled by calling the Edge Function with endpoint /v1/enrollments?user_id={thinkific_user_id}&course_id={course_id}. If not enrolled, show a confirmation modal with the course price. On confirmation, call the Edge Function with a POST to /v1/enrollments with body { enrollment: { course_id: X, user_id: Y } } to create the enrollment. Handle free courses (price 0) and paid courses differently — for paid courses, redirect to the Thinkific checkout URL instead of enrolling directly.' For paid course enrollments, Thinkific requires payment to happen through their checkout flow. The programmatic enrollment endpoint (POST /v1/enrollments) only works for free enrollments or when enrolling users as part of a bundle/subscription that has already been paid. For paid one-time courses, generate a checkout URL by constructing: https://{subdomain}.thinkific.com/courses/{course_slug}/take — or use the free enrollment endpoint with a coupon code that makes the course free. Store the Thinkific user ID in your Supabase user profile table after first lookup. This avoids the overhead of looking up the user by email on every enrollment check. Add a column thinkific_user_id to your profiles table and populate it on first login or first course interaction. Make sure your Edge Function handles the case where a Thinkific user account does not exist for the logged-in Lovable user — in that case, you may need to create the user via POST /v1/users before enrolling them.
Add an enrollment function to the ThinkificCourseGrid component: when a user clicks Enroll, POST to our thinkific-api Edge Function with endpoint '/v1/enrollments', method 'POST', and body { enrollment: { course_id: courseId, user_id: thinkificUserId } }. Store the thinkific_user_id in the user's Supabase profile after first retrieval. Show a success toast on enrollment and update the button to show 'Enrolled' status.
Paste this in Lovable chat
Pro tip: Thinkific user IDs are integers, not UUIDs. If you are storing them in Supabase, use a bigint column type rather than uuid. Add an index on thinkific_user_id in your profiles table for fast lookups.
Expected result: Users can click Enroll on any free course and be enrolled programmatically. The button updates to 'Enrolled' immediately. Paid courses redirect to Thinkific's checkout. Enrollment records appear in both Thinkific's admin panel and your Supabase enrollments table.
Common use cases
Custom course catalog with enrollment tracking
Build a public-facing course catalog that pulls live data from your Thinkific school, shows course thumbnails, descriptions, and pricing, and lets visitors enroll directly. Student enrollment status is tracked and displayed in a personalized dashboard after login.
Create a course catalog page that fetches all published courses from my Thinkific school via an Edge Function and displays them in a card grid with title, thumbnail, description, price, and an Enroll button. When a logged-in user clicks Enroll, call the Thinkific enrollment API to register them. Show enrolled courses separately in a My Courses section with progress indicators.
Copy this prompt to try it in Lovable
Student progress and completion dashboard
Build an internal dashboard for course administrators to monitor student progress across all courses, view enrollment counts, track completion rates, and identify students who have stalled mid-course.
Build an admin dashboard that shows: total enrollments per course, average completion percentage per course, a list of students who enrolled more than 7 days ago but have 0% progress, and a table of recently completed courses with student names and completion dates. Fetch all this data from the Thinkific API through an Edge Function and refresh it every 5 minutes.
Copy this prompt to try it in Lovable
B2B cohort enrollment portal
Create a portal where corporate clients can enroll batches of employees into specific Thinkific courses, view their team's progress, and receive automated notifications when employees complete required training.
Create a B2B enrollment portal where a company admin can paste a list of employee email addresses and select a course, then bulk-enroll them via the Thinkific API. Show a team progress table with each employee's name, enrollment date, current progress percentage, and completion status. Send a webhook-triggered notification when any employee completes the course.
Copy this prompt to try it in Lovable
Troubleshooting
Edge Function returns 401 Unauthorized when calling the Thinkific API
Cause: The THINKIFIC_API_KEY or THINKIFIC_SUBDOMAIN secret is missing, has an extra space, or the API key has been regenerated in Thinkific without updating the secret.
Solution: Go to Cloud → Secrets and verify both THINKIFIC_API_KEY and THINKIFIC_SUBDOMAIN exist and have correct values. Then go to your Thinkific admin panel under Settings → Code & API → API Key to confirm the key matches exactly. Copy and re-paste the key to eliminate whitespace issues. After updating a secret, redeploy the Edge Function by making a small edit and saving.
CORS error appears in the browser console when calling the Thinkific API
Cause: The frontend is attempting to call the Thinkific API directly instead of going through the Edge Function proxy. Thinkific's API does not allow cross-origin requests from browsers.
Solution: Ensure all Thinkific API calls in your frontend code target your Edge Function URL (/functions/v1/thinkific-api) and not the Thinkific API URL directly. Search the Code panel for any fetch calls containing 'thinkific.com' in the frontend components and replace them with calls to your Edge Function. The Edge Function itself will call Thinkific server-side where CORS does not apply.
Courses return empty array even though courses exist in Thinkific
Cause: The API call is hitting the wrong endpoint or missing required query parameters. By default, some Thinkific endpoints only return published/active courses, and the pagination defaults may not return all courses if you have more than 25.
Solution: Check that your endpoint path is /v1/courses (not /courses or /api/v1/courses). Thinkific's base URL is https://{subdomain}.thinkific.com/api/public — so the full URL for courses should be https://{subdomain}.thinkific.com/api/public/v1/courses. Add query parameters to control pagination: ?page=1&limit=25. Check Cloud → Logs to see the full URL being called and the raw response from Thinkific.
Webhook events are not being received by the Edge Function
Cause: The webhook URL is incorrect, the app is not deployed (webhooks cannot reach Lovable's preview URL), or the THINKIFIC_WEBHOOK_TOKEN does not match what was configured in Thinkific's webhook settings.
Solution: First verify your app is deployed — webhook URLs must be the deployed Supabase Edge Function URL (https://[project-ref].supabase.co/functions/v1/thinkific-webhook), not the Lovable preview URL. In Thinkific's webhook settings, click 'Send test notification' and check Cloud → Logs to see if the request arrives. If it arrives but returns 401, the token mismatch is the cause — update the token in Thinkific's webhook settings to match THINKIFIC_WEBHOOK_TOKEN in Cloud → Secrets exactly.
Best practices
- Always store THINKIFIC_API_KEY and THINKIFIC_SUBDOMAIN in Cloud → Secrets — never hardcode them in Edge Function code or frontend components
- Cache Thinkific course data in your Supabase database and refresh it on a schedule rather than fetching live data on every page load — this avoids the 100 requests/minute rate limit and improves performance
- Store Thinkific user IDs in your Supabase profiles table after the first lookup to avoid repeated /v1/users API calls for the same user
- Use the Edge Function as a general-purpose Thinkific proxy rather than creating a separate Edge Function for each endpoint — a single proxy function with configurable endpoint routing is easier to maintain
- Verify the X-Thinkific-Webhook-Token header in your webhook receiver before processing any event data to prevent unauthorized webhook injection
- Strip HTML tags from Thinkific course descriptions before displaying them in non-code UI fields — Thinkific stores descriptions as HTML and displaying raw HTML breaks your UI layout
- Test enrollment flows with a free course before building paid course logic — Thinkific's free enrollment endpoint is simpler and helps validate your data model before adding payment complexity
- Monitor your Thinkific API usage in the Thinkific admin panel under Settings → Code & API to ensure you are not approaching rate limits, especially if you have high-traffic pages that load course data
Alternatives
Choose Teachable if your courses include coaching sessions, memberships, or you want stronger built-in payment processing with affiliate tracking.
Choose LearnWorlds if you need stronger white-label options, interactive video features, or built-in certificate generation in your course platform.
Choose Podia if you want to sell courses alongside digital downloads, webinars, and coaching from a single all-in-one storefront without separate tools.
Frequently asked questions
Does Thinkific have a native Lovable connector?
No. As of March 2026, Thinkific is not one of Lovable's 17 shared connectors. You integrate it manually using an Edge Function proxy that stores your API key in Cloud → Secrets and routes requests server-side. This is a standard pattern for authenticated third-party APIs in Lovable.
Can I use the Thinkific API on the free Thinkific plan?
Yes. Thinkific provides API access on all plans including the free tier. The API key is found in your admin panel under Settings → Code & API → API Key. Rate limits apply: 100 requests per minute. For most Lovable apps — course catalogs, dashboards, enrollment tracking — this is sufficient.
Can I enroll students in paid courses programmatically through the API?
Thinkific's POST /v1/enrollments endpoint only creates free enrollments or enrollments for users who have already purchased access through Thinkific's checkout. For paid courses, you need to redirect users to Thinkific's checkout URL. Alternatively, you can create a coupon code that makes a course free and apply it during API enrollment, which is useful for B2B bulk enrollment scenarios.
How do I keep my Lovable app's enrollment data in sync with Thinkific?
The best approach is a combination of webhooks (for real-time events like new enrollments and completions) and a periodic sync job (for bulk data consistency). Set up Thinkific webhooks pointing to a Lovable Edge Function receiver for immediate event handling. For the periodic sync, create a Supabase scheduled Edge Function that calls /v1/enrollments with a date filter to catch any events the webhook might have missed.
Why do I need an Edge Function instead of calling the Thinkific API from my frontend React code?
Two reasons: security and CORS. Calling the Thinkific API from frontend code exposes your API key in the browser, where any user can see it in the Network tab. Additionally, Thinkific's API does not allow cross-origin browser requests, so a direct frontend call would fail with a CORS error. The Edge Function solves both issues by making the API call server-side.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation