# How to Integrate Retool with Teachable

- Tool: Retool
- Difficulty: Beginner
- Time required: 20 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Teachable using a REST API Resource with API key authentication. Once configured, build admin panels that display course catalogs, enrollment data, student progress, and revenue metrics — giving course creators and operations teams a custom dashboard that goes well beyond Teachable's native reporting interface.

## Build a Custom Course Operations Dashboard on Top of Teachable

Teachable's built-in reports provide basic metrics — revenue totals, enrollment counts, and completion rates — but they are designed for individual course creators rather than operations teams managing large course catalogs. Teams quickly hit limitations when they need to cross-filter enrollments by date and course, drill into individual student progress, combine Teachable revenue data with external billing records, or build custom reports for specific stakeholders. Retool addresses this by connecting directly to Teachable's REST API and turning your school data into a fully customizable operations panel.

The connection is straightforward: generate an API key in your Teachable school settings, configure it as a Bearer token in a Retool REST API Resource, and start building queries for each data type. Teachable's API exposes courses, users, enrollments, bundles, and coupon data — all accessible through GET requests that return paginated JSON arrays. Results bind directly to Table and Chart components in Retool, and you can join data from multiple Teachable endpoints using JavaScript transformers to produce unified views that Teachable's native dashboard cannot create.

For course businesses with multiple instructors, large student cohorts, or complex enrollment workflows, this integration is particularly valuable. A Retool dashboard can surface every enrolled student, their completion percentage, last login date, and whether they have completed a certificate requirement — enabling proactive student engagement at scale. Revenue tracking across course bundles and individual courses, combined with cohort analysis by enrollment month, gives business intelligence that Teachable's analytics tab does not natively support.

## Before you start

- A Teachable school with at least one published course and existing student enrollments
- Teachable Pro plan or higher (API access is not available on the Free plan)
- A Teachable API key generated from your school's Settings → API panel
- A Retool account (Cloud or self-hosted) with permission to create Resources
- Basic familiarity with REST APIs — no coding experience required for the core setup

## Step-by-step guide

### 1. Generate a Teachable API key

To connect Retool to your Teachable school, you need an API key generated from your school's admin settings. Sign in to your Teachable school admin panel at yourschool.teachable.com/admin. In the left sidebar, navigate to Settings → General and scroll down to the API section, or go directly to Settings → API if that menu item is present in your school plan. Click 'Generate API key' or look for an existing API key if one has already been created. Teachable generates a single API key per school — it does not currently support multiple keys or scoped keys with different permission levels. Copy the API key value and store it somewhere secure temporarily. If your school is on a plan that does not show the API section in Settings, check that you are logged in as the school owner (not an admin or author role) and confirm your plan includes API access. Teachable restricts API access to Pro plan and above — if you are on a Free or Basic plan, the API section will not appear. Note that the API key provides read access to all school data including student emails and enrollment records, so treat it with the same security as a password and never share it publicly.

**Expected result:** A Teachable API key string is copied from the Settings → API page and ready to paste into Retool.

### 2. Create a REST API Resource in Retool

In Retool, navigate to the Resources tab from your organization's homepage sidebar. Click '+ Create new', scroll through the connector list, and select 'REST API'. On the configuration screen, fill in the Name field with 'Teachable API' or a more specific name like 'Teachable (School Name)' if you manage multiple schools. For the Base URL, enter https://developers.teachable.com — this is Teachable's API host for the v1 API. Under Authentication, select 'Bearer token' from the dropdown and paste your Teachable API key in the token field. In the Headers section, click 'Add header' and add a Content-Type header with value application/json for any POST request queries you create later. Click 'Test connection' to verify the resource is reachable. Because Teachable's root API endpoint may not return a success response without a valid path, a connection test might show a 404 — this is normal. Verify by running a test query in the next step instead. Click 'Save resource'. All requests through this resource are proxied server-side by Retool, so your Teachable API key is never visible in browser network traffic or Retool app users' DevTools.

**Expected result:** A REST API Resource named 'Teachable API' is saved in Retool and appears in the Resources list. The resource is available in the query editor when building queries in apps.

### 3. Query the courses endpoint

Open a Retool app (or create a new one from scratch) and navigate to the Code panel at the bottom of the canvas. Click '+ New query', select your Teachable API resource, and name the query getCourses. Set the Method to GET and the URL path to /v1/courses. Teachable's API returns a paginated list of courses in your school. Add URL parameters to control the response: set is_published to true to show only live courses (omit this to see draft courses as well), and perPage to 50 to get up to 50 courses per page. Click 'Run query' to test. The API returns a courses array where each course has fields including id, name, heading (course subtitle), description, is_published, lecture_sections, and image_url. Also check the meta object in the response, which contains total_count and number_of_pages for pagination. Add a JavaScript transformer (click Advanced → Transform results) to flatten the response into a clean array for display in a Table component. Drag a Table component from the component panel onto the canvas and set its Data source to {{ getCourses.data }} to display the course list. You now have a scrollable, sortable, filterable table of all your Teachable courses.

```
// Transformer: flatten Teachable courses response
const courses = data.courses || [];
return courses.map(course => ({
  id: course.id,
  name: course.name,
  heading: course.heading || '',
  status: course.is_published ? 'Published' : 'Draft',
  image_url: course.image_url || '',
  created_at: new Date(course.created_at).toLocaleDateString()
}));
```

**Expected result:** The getCourses query returns a JSON response with a courses array. The Table component displays all courses with columns for name, status, and creation date. Clicking a course row selects it and makes the course ID available for enrollment queries.

### 4. Fetch enrollments and calculate completion rates

To build a meaningful course performance dashboard, you need enrollment data for each course. Create a second query named getEnrollments. Select your Teachable API resource, set the Method to GET, and set the URL path to /v1/courses/{{ coursesTable.selectedRow.id }}/enrollments. This path dynamically uses the course ID from the selected row in your courses Table. Add URL parameters: set perPage to 100 (the maximum Teachable returns per page) and sort to created_at:desc to see the most recent enrollments first. Run the query by first clicking a row in the courses Table to populate the course ID. The API returns an enrollments array where each enrollment has user (nested user object with name, email, and id), course_id, created_at, completed_at (null if not finished), percentage_completed, and a lectureable_completions_count. Completion rate is available directly as percentage_completed — no calculation needed. Create a transformer that flattens the nested user data and formats the enrollment date and completion status cleanly. Drag a second Table component onto the canvas below the courses Table and bind it to {{ getEnrollments.data }} to show enrollments for the selected course. Add a Text component at the top of the enrollment panel showing the total enrollment count from {{ getEnrollments.data.meta.total_count }}.

```
// Transformer: flatten Teachable enrollments with user data
const enrollments = data.enrollments || [];
return enrollments.map(e => ({
  student_name: e.user?.name || 'N/A',
  student_email: e.user?.email || 'N/A',
  user_id: e.user?.id,
  enrolled_at: new Date(e.created_at).toLocaleDateString(),
  completed_at: e.completed_at ? new Date(e.completed_at).toLocaleDateString() : 'In Progress',
  completion_pct: `${Math.round(e.percentage_completed || 0)}%`,
  is_complete: e.completed_at !== null
}));
```

**Expected result:** Clicking a course row in the courses Table triggers getEnrollments and populates the enrollments Table below with student names, emails, enrollment dates, and completion percentages.

### 5. Build revenue metrics and a completion rate chart

To add revenue visibility to your Teachable dashboard, query the transactions endpoint and build a revenue summary alongside a Chart component showing completion rates by course. Create a query named getTransactions with Method GET and URL path /v1/courses/{{ coursesTable.selectedRow.id }}/transactions. This returns purchase transaction records for a specific course including amount, coupon_id, created_at, and user data. Add a perPage parameter of 100. Create a JavaScript query named courseRevenueSummary that accesses getTransactions.data to calculate total gross revenue by summing the amount field (in cents), total number of transactions, average transaction value, and the number of transactions using a coupon. Format amounts by dividing by 100 and converting to currency string. To build a cross-course comparison chart, create a separate query named allCourseCompletionRates that runs on page load and fetches summary data for each course. Because Teachable does not return a bulk completion rate endpoint, build this using the courses list joined with a cached enrollment aggregate — or alternatively, run getCourses first and display completion rates from a separate analytics field. Drag a Stat component from the component panel for each key metric: Total Revenue, Total Enrollments, and Completion Rate. Bind each to the relevant calculated value. For complex course business analytics combining Teachable revenue data with external payment processors or CRM systems, RapidDev's team can help design the complete Retool dashboard architecture.

```
// JavaScript query: calculate revenue summary from transactions
const transactions = getTransactions.data?.transactions || [];

const totalRevenue = transactions.reduce((sum, t) => sum + (t.amount || 0), 0);
const withCoupon = transactions.filter(t => t.coupon_id !== null).length;
const avgTransaction = transactions.length > 0 ? totalRevenue / transactions.length : 0;

return {
  gross_revenue: `$${(totalRevenue / 100).toFixed(2)}`,
  transaction_count: transactions.length,
  avg_transaction: `$${(avgTransaction / 100).toFixed(2)}`,
  coupon_count: withCoupon,
  coupon_pct: transactions.length > 0
    ? `${Math.round((withCoupon / transactions.length) * 100)}%`
    : '0%'
};
```

**Expected result:** The dashboard displays revenue summary statistics (gross revenue, average transaction, coupon usage rate) alongside the enrollment Table. The Stat components update each time a different course is selected in the courses Table.

## Best practices

- Store the Teachable API key as a secret configuration variable in Retool (Settings → Configuration Variables, marked as secret) rather than pasting it directly into the Resource — this separates the credential from the resource configuration and makes rotation straightforward.
- Implement server-side pagination for enrollment queries by binding the Teachable perPage and page parameters to Retool Table's pagination state — Teachable limits responses to 100 records per page, and courses with hundreds of students will silently return incomplete data without pagination.
- Add query caching (Query editor → Advanced → Cache results, 60-120 seconds) on getCourses and getEnrollments queries to avoid hitting Teachable's API rate limits when multiple team members use the dashboard simultaneously.
- Use Retool's event handlers to chain queries — when getCourses runs successfully, automatically trigger getEnrollments with the first course pre-selected, so the dashboard is populated without requiring a manual table row click on first load.
- Transaction amounts in Teachable's API are in the smallest currency unit (cents for USD). Always divide by 100 in transformers before displaying or calculating revenue metrics — this is the most common arithmetic error in Teachable integrations.
- For dashboards shared with non-Teachable users (executives, finance teams), use Retool's public app sharing or embedded app features to give access without requiring Teachable credentials — Retool handles the API authentication centrally.
- Build a separate 'at-risk students' view using completion thresholds as filters — set a NumberInput component for the completion threshold percentage and filter enrollments where percentage_completed is below the threshold and enrollment age exceeds a configurable number of days. This proactive view enables student success interventions.

## Use cases

### Build a course performance dashboard

You manage a Teachable school with fifteen active courses and need a dashboard showing total enrollments, completion rates, revenue generated, and average completion time for each course — information that currently requires clicking into each course individually in Teachable. The Retool app queries the Teachable courses endpoint and enriches each course with enrollment and completion data, displaying everything in a sortable Table with bar charts for revenue and completion rate comparisons.

Prompt example:

```
Build a course performance dashboard that lists all Teachable courses with their name, enrollment count, completion rate, total revenue, and average completion time. Add a bar chart showing revenue per course. Include a date range picker to filter enrollments by date and a search bar to filter by course name.
```

### Create a student progress tracker

Your coaching team needs to identify students who enrolled more than 30 days ago but have not completed more than 20% of the course content — these students are candidates for a re-engagement email. The Retool app queries Teachable enrollments, calculates percentage complete from completed_lecture_ids versus total lecture count, and filters for at-risk students. Ops staff can then export this list or trigger notifications from Retool without manual Excel work.

Prompt example:

```
Build a student progress panel that shows all enrollments for a selected course with columns for student name, email, enrollment date, percent complete, and last login date. Add filter dropdowns to show only students who are below a configurable completion threshold and enrolled more than N days ago. Include a 'Copy emails' button that copies all filtered student emails to the clipboard.
```

### Build a revenue and refund operations panel

Your finance team needs a daily view of Teachable transactions, including new enrollments, coupons applied, and any refunds issued — data that currently requires exporting CSVs from Teachable manually. The Retool app queries the transactions endpoint with date filters, displays a summary of gross revenue, discount amounts, and net revenue for any date range, and shows individual transactions in a searchable table that the team can filter without leaving Retool.

Prompt example:

```
Build a revenue dashboard that queries Teachable transaction data for a configurable date range, calculates gross revenue (sum of full_price), total discounts (sum of coupon_amount), and net revenue. Display a daily revenue line chart and a Table of individual transactions with student name, course, coupon code, and amount paid.
```

## Troubleshooting

### Query returns 401 Unauthorized

Cause: The Teachable API key is invalid, has been regenerated since it was configured in Retool, or the Bearer token in the Resource configuration is incorrect.

Solution: Go to your Teachable school admin panel, navigate to Settings → API, and verify the API key. If it has changed, copy the current key and update the Bearer token in your Retool Resource configuration: Resources tab → select Teachable API → edit the token field → Save resource. Only the school owner can view and regenerate the API key.

### API returns 403 Forbidden on certain endpoints

Cause: The Teachable API plan restriction prevents access to specific endpoints. Some endpoints like bulk transaction exports or advanced analytics require higher-tier Teachable plans (Business or higher).

Solution: Check Teachable's API documentation for plan-specific endpoint availability. Confirm your school plan level in Teachable Settings → Billing. If the endpoint requires an upgrade, consider querying a supported endpoint that provides similar data — for example, per-course transaction endpoints are available on Pro plan, while bulk school-wide transaction endpoints may require Business plan.

### Enrollment data shows incorrect or missing percentage_completed values

Cause: The percentage_completed field is calculated from lecture completions tracked by Teachable. Students who enrolled but never accessed any lecture content show 0. Students who have not completed all quizzes required for lecture completion may show lower percentages than expected.

Solution: Use the lectureable_completions_count field alongside total lecture count from the course details endpoint to independently calculate completion rate. Fetch course section details from /v1/courses/{id}/lecture_sections and count total lectures to cross-verify the percentage_completed value.

```
// Manual completion rate calculation
const completionRate = totalLectures > 0
  ? Math.round((e.lectureable_completions_count / totalLectures) * 100)
  : 0;
```

## Frequently asked questions

### Does Retool have a native Teachable connector?

No. Retool does not have a dedicated native connector for Teachable as of 2026. You connect using a generic REST API Resource with Teachable's API key as Bearer token authentication. This provides full access to all Teachable API endpoints — courses, enrollments, users, transactions, and coupons.

### Which Teachable plan is required for API access?

Teachable API access requires Pro plan or higher. The Free and Basic plans do not include API access, and the Settings → API section will not appear in the admin panel on lower-tier plans. Check Teachable's current pricing page for plan-specific API feature availability, as plan names and features have changed over time.

### Can I manage enrollments from Retool — for example, enroll or unenroll students?

Teachable's API supports creating enrollments via POST requests to /v1/courses/{course_id}/enrollments with the student's user ID. You can build a Retool Form that accepts a student email, looks up their user ID from the /v1/users endpoint, and then triggers an enrollment POST request. Revocation is not supported via the Teachable REST API as of 2026 — refunds and enrollment management must be done through the Teachable admin panel.

### How do I show student progress for all courses, not just one at a time?

Teachable's API requires querying enrollments per course — there is no bulk endpoint that returns enrollments across all courses simultaneously. To build an all-courses student view, run a JavaScript query in Retool that chains multiple enrollment queries (one per course ID from your getCourses results) using Promise.all() and concatenates the results. For schools with many courses, this generates multiple API calls and may be slow — consider running this logic in a Retool Workflow on a schedule and caching results in your own database.

---

Source: https://www.rapidevelopers.com/retool-integrations/teachable
© RapidDev — https://www.rapidevelopers.com/retool-integrations/teachable
