A lightweight, strictly-typed Node.js wrapper for the Teachable v1 API. Built on Zod for runtime schema validation, with full TypeScript support out of the box.
Full documentation available at useoptio.dev
- ✅ Strongly typed responses via Zod schema validation
- ✅ Complete coverage of all Teachable v1 GET endpoints
- ✅ Clean versioned client (
v1) designed for forward compatibility - ✅ Helpful validation errors when the Teachable API returns unexpected data
- ✅ Intentionally read-only — safe to use in any environment
- ✅ Works with TypeScript and JavaScript
npm install optio-teachableOr via GitHub:
npm install git+ssh://git@github.com:Ellf/optio-teachable.gitTypeScript
import { TeachableClient } from 'optio-teachable';
const teachable = new TeachableClient(process.env.TEACHABLE_API_KEY);
const { users } = await teachable.v1.users.getList(1, 20);
console.log(`Fetched ${users.length} users.`);JavaScript
const { TeachableClient } = require('optio-teachable');
const teachable = new TeachableClient(process.env.TEACHABLE_API_KEY);
const { users } = await teachable.v1.users.getList(1, 20);
console.log(`Fetched ${users.length} users.`);It is strongly recommended to store your API key in an environment variable and never commit it to source control.
All methods return strongly-typed promises validated at runtime via Zod. If the Teachable API returns unexpected data or the request fails, the client throws a descriptive error indicating exactly which field failed validation.
| Method | Description |
|---|---|
getList(page?, per?, filters?) |
Paginated list of users. Filter by email or use searchAfter to paginate beyond 10,000 records |
getById(id) |
Single user with course enrolment details, tags, and sign-in metadata |
getByEmail(email) |
Search for a user by email address |
| Method | Description |
|---|---|
getList(page?, per?, filters?) |
Paginated list of courses. Filter by name, isPublished, authorBioId, or createdAt |
getById(id) |
Single course with full lecture section structure and author bio |
getEnrolments(courseId, page?, per?, filters?) |
Paginated enrolments for a course. Filter by date range and sort direction |
getProgress(courseId, userId, page?, per?) |
Progress record for a specific user on a course, including certificate and lecture completion |
getLecture(courseId, lectureId) |
Single lecture with all attachments including video, text, quiz, and embed content |
getQuizIds(courseId, lectureId) |
Array of quiz IDs attached to a lecture |
getQuiz(courseId, lectureId, quizId) |
Full quiz with all questions, answers, and grading configuration |
getQuizResponses(courseId, lectureId, quizId) |
All student responses for a quiz including grades |
getVideo(courseId, lectureId, videoId, filters?) |
Time-limited HLS stream URL and thumbnail for a lecture video |
| Method | Description |
|---|---|
getList(page?, per?, filters?) |
Paginated list of transactions. Filter by userId, courseId, affiliateId, pricingPlanId, isFullyRefunded, isChargeback, startDate, or endDate. Note: new transactions may take up to two minutes to appear. |
| Method | Description |
|---|---|
getList(page?, per?) |
Paginated list of all pricing plans across the school |
getById(id) |
Single pricing plan with full frequency configuration, free trial, and enrolment cap |
| Method | Description |
|---|---|
getList() |
All webhooks registered on the school |
getEvents(webhookId, page?, per?, filters?) |
Paginated delivery events for a webhook. Filter by HTTP status range and date |
| Method | Description |
|---|---|
teachable.v1.getRaw(endpoint, logOutput?) |
Fetch any v1 endpoint without schema validation. Useful for exploring undocumented endpoints |
All response types are exported from the SDK and can be used to type your own functions:
import type {
BasicUser,
UserDetail,
Course,
CourseDetail,
CourseProgress,
Transaction,
PricingPlan,
PricingPlanDetail,
Enrolment,
LectureDetail,
LectureAttachment,
LectureVideo,
LectureQuiz,
QuizQuestion,
QuizResponseStudent,
Webhook,
WebhookEvent,
} from 'optio-teachable';Pass true as the second argument to enable request and response logging:
const teachable = new TeachableClient(process.env.TEACHABLE_API_KEY, true);This will log all outgoing requests and full response bodies to the console, prefixed with [Teachable Debug].
This SDK covers every GET endpoint in the Teachable v1 API and intentionally implements no write operations. A read-only SDK is safe to use in scripts, reporting tools, and data pipelines without any risk of modifying your school's data. See the full explanation in the docs.
MIT — free to use, modify, and distribute.
Built by Tom Lorimer · Purple Hippo Web Studio