Skip to main content
Glama

Teachable MCP Server & CLI

npm CI License YouTube X LinkedIn

A Teachable CLI and local MCP for school workflows: stable v1 by default, explicit beta v2, private school profiles, confirmed effects, reviewed batches and bounded private exports.

One install, one implementation on both surfaces. Teachable's official remote MCP already executes account requests and searches docs; this companion adds specific local workflows. It does not implement end-user OAuth.

Built and maintained by Navid Moazzez. Built on Slipway, which turns one definition of each tool into the MCP server and the CLI, so validation, approval and redaction are the same on both.

Two ways to use it

Command line

teachable-cli tools
teachable-cli list-courses --page 1 --per 5 --agent
teachable-cli get-operation-schema --operation create_enrollment --agent
teachable-cli <command> --help

Use it directly or through a shell agent after configuring the intended private school. Effects require explicit --confirm; presentation flags never grant approval.

MCP server, for your AI app

codex mcp add teachable -- npx -y @thenavidm/teachable-mcp-cli@latest

A supported client launches the local stdio server and discovers the same tasks. Forward private settings through the client runtime. Where the client can ask, a person approves every effect: Claude Code shows its own prompt for each call, and a client that can show forms asks with an approval form. INSTALL.md covers clients, OS paths, desktop and Docker setup.

Which one

Where you work

Surface

Codex or another shell agent

Dedicated CLI, local MCP or both

Supported local MCP app

Local stdio MCP; extension where supported

Script or CI task

CLI with private runtime credentials

URL-only hosted client

Teachable's official remote MCP is an alternative

Related MCP server: LearnWorlds MCP

Features

Capability

CLI command

MCP tool

Show Course Enrollments

teachable-cli list-enrollments

list_enrollments

Mark Lecture Complete

teachable-cli mark-lecture-complete

mark_lecture_complete

Show Quiz Responses

teachable-cli list-quiz-responses

list_quiz_responses

Show Quiz

teachable-cli get-quiz

get_quiz

List Quizzes

teachable-cli list-quizzes

list_quizzes

Show Video

teachable-cli get-video

get_video

Show Lecture

teachable-cli get-lecture

get_lecture

Course Progress

teachable-cli get-course-progress

get_course_progress

Show Course

teachable-cli get-course

get_course

List Courses

teachable-cli list-courses

list_courses

Enroll User

teachable-cli create-enrollment

create_enrollment

Show Pricing Plans

teachable-cli get-pricing-plan

get_pricing_plan

List Pricing Plans

teachable-cli list-pricing-plans

list_pricing_plans

List Transactions

teachable-cli list-transactions

list_transactions

Unenroll User

teachable-cli unenroll-user

unenroll_user

Show User

teachable-cli get-user

get_user

Update User

teachable-cli update-user

update_user

List Users

teachable-cli list-users

list_users

Create User

teachable-cli create-user

create_user

Show Webhook Events

teachable-cli get-webhook-events

get_webhook_events

List Webhooks

teachable-cli list-webhooks

list_webhooks

Get school customizations

teachable-cli v2-get-school-customizations

v2_get_school_customizations

Delete a pricing plan

teachable-cli v2-delete-pricing-plan

v2_delete_pricing_plan

Get a pricing plan

teachable-cli v2-get-pricing-plan

v2_get_pricing_plan

Update a pricing plan

teachable-cli v2-update-pricing-plan

v2_update_pricing_plan

List pricing plans for a product

teachable-cli v2-list-pricing-plans-for-product

v2_list_pricing_plans_for_product

Create a pricing plan for a product

teachable-cli v2-create-pricing-plan-for-product

v2_create_pricing_plan_for_product

Delete a coupon

teachable-cli v2-delete-coupon

v2_delete_coupon

Get a coupon

teachable-cli v2-get-coupon

v2_get_coupon

Update a coupon

teachable-cli v2-update-coupon

v2_update_coupon

List all coupons

teachable-cli v2-list-coupons

v2_list_coupons

Create a coupon

teachable-cli v2-create-coupon

v2_create_coupon

List comments for a course

teachable-cli v2-list-comments-for-course

v2_list_comments_for_course

Get compliance settings for a course

teachable-cli v2-get-compliance-settings-for-course

v2_get_compliance_settings_for_course

Update compliance settings for a course

teachable-cli v2-update-compliance-settings-for-course

v2_update_compliance_settings_for_course

Unenroll a user from a course

teachable-cli v2-unenroll-user-from-course

v2_unenroll_user_from_course

Get a user's enrollments for a course

teachable-cli v2-get-user-s-enrollments-for-course

v2_get_user_s_enrollments_for_course

Update a course enrollment

teachable-cli v2-update-course-enrollment

v2_update_course_enrollment

Enroll a user in a course

teachable-cli v2-enroll-user-in-course

v2_enroll_user_in_course

List enrollments for a course

teachable-cli v2-list-enrollments-for-course

v2_list_enrollments_for_course

Delete content (attachment) from a lesson (lecture)

teachable-cli v2-delete-content-attachment-from-lesson-lecture

v2_delete_content_attachment_from_lesson_lecture

Get content (attachment) for a lesson (lecture)

teachable-cli v2-get-content-attachment-for-lesson-lecture

v2_get_content_attachment_for_lesson_lecture

Update content (attachment) for a lesson (lecture)

teachable-cli v2-update-content-attachment-for-lesson-lecture

v2_update_content_attachment_for_lesson_lecture

List content (attachments) for a lesson (lecture)

teachable-cli v2-list-content-attachments-for-lesson-lecture

v2_list_content_attachments_for_lesson_lecture

Create content (attachment) for a lesson (lecture)

teachable-cli v2-create-content-attachment-for-lesson-lecture

v2_create_content_attachment_for_lesson_lecture

Reorder content (attachments) in a lesson (lecture)

teachable-cli v2-reorder-content-attachments-in-lesson-lecture

v2_reorder_content_attachments_in_lesson_lecture

Delete a lecture comment

teachable-cli v2-delete-lecture-comment

v2_delete_lecture_comment

Update comment moderation status

teachable-cli v2-update-comment-moderation-status

v2_update_comment_moderation_status

List comments for a lecture

teachable-cli v2-list-comments-for-lecture

v2_list_comments_for_lecture

Create a comment on a lecture

teachable-cli v2-create-comment-on-lecture

v2_create_comment_on_lecture

List responses for a lecture quiz

teachable-cli v2-list-responses-for-lecture-quiz

v2_list_responses_for_lecture_quiz

Delete a lecture quiz

teachable-cli v2-delete-lecture-quiz

v2_delete_lecture_quiz

Get a lecture quiz

teachable-cli v2-get-lecture-quiz

v2_get_lecture_quiz

List quizzes for a lecture

teachable-cli v2-list-quizzes-for-lecture

v2_list_quizzes_for_lecture

Mark lecture as not completed for a user

teachable-cli v2-mark-lecture-as-not-completed-for-user

v2_mark_lecture_as_not_completed_for_user

Get lecture completion status for a user

teachable-cli v2-get-lecture-completion-status-for-user

v2_get_lecture_completion_status_for_user

Mark lecture as completed for a user

teachable-cli v2-mark-lecture-as-completed-for-user

v2_mark_lecture_as_completed_for_user

Get video for a lecture

teachable-cli v2-get-video-for-lecture

v2_get_video_for_lecture

Delete a lecture

teachable-cli v2-delete-lecture

v2_delete_lecture

Get a lecture

teachable-cli v2-get-lecture

v2_get_lecture

Update a lecture

teachable-cli v2-update-lecture

v2_update_lecture

List lectures for a course

teachable-cli v2-list-lectures-for-course

v2_list_lectures_for_course

Create a lecture in a section

teachable-cli v2-create-lecture-in-section

v2_create_lecture_in_section

Reorder lectures in a section

teachable-cli v2-reorder-lectures-in-section

v2_reorder_lectures_in_section

Get a course section

teachable-cli v2-get-course-section

v2_get_course_section

Update a course section

teachable-cli v2-update-course-section

v2_update_course_section

Replace a course section

teachable-cli v2-replace-course-section

v2_replace_course_section

List sections for a course

teachable-cli v2-list-sections-for-course

v2_list_sections_for_course

Create a section in a course

teachable-cli v2-create-section-in-course

v2_create_section_in_course

Reorder sections in a course

teachable-cli v2-reorder-sections-in-course

v2_reorder_sections_in_course

Get course progress for a user

teachable-cli v2-get-course-progress-for-user

v2_get_course_progress_for_user

Get a course

teachable-cli v2-get-course

v2_get_course

Update a course

teachable-cli v2-update-course

v2_update_course

List all courses

teachable-cli v2-list-courses

v2_list_courses

Create a course

teachable-cli v2-create-course

v2_create_course

Delete an attachment from a digital download

teachable-cli v2-delete-attachment-from-digital-download

v2_delete_attachment_from_digital_download

Get an attachment for a digital download

teachable-cli v2-get-attachment-for-digital-download

v2_get_attachment_for_digital_download

List attachments for a digital download

teachable-cli v2-list-attachments-for-digital-download

v2_list_attachments_for_digital_download

Create an attachment for a digital download

teachable-cli v2-create-attachment-for-digital-download

v2_create_attachment_for_digital_download

Unenroll a user from a digital download

teachable-cli v2-unenroll-user-from-digital-download

v2_unenroll_user_from_digital_download

Get an enrollment for a digital download

teachable-cli v2-get-enrollment-for-digital-download

v2_get_enrollment_for_digital_download

Enroll a user in a digital download

teachable-cli v2-enroll-user-in-digital-download

v2_enroll_user_in_digital_download

List enrollments for a digital download

teachable-cli v2-list-enrollments-for-digital-download

v2_list_enrollments_for_digital_download

Delete a digital download

teachable-cli v2-delete-digital-download

v2_delete_digital_download

Get a digital download

teachable-cli v2-get-digital-download

v2_get_digital_download

Update a digital download

teachable-cli v2-update-digital-download

v2_update_digital_download

List all digital downloads

teachable-cli v2-list-digital-downloads

v2_list_digital_downloads

Create a digital download

teachable-cli v2-create-digital-download

v2_create_digital_download

Unenroll a user from a product collection

teachable-cli v2-unenroll-user-from-product-collection

v2_unenroll_user_from_product_collection

Get an enrollment for a product collection

teachable-cli v2-get-enrollment-for-product-collection

v2_get_enrollment_for_product_collection

Update a product collection enrollment

teachable-cli v2-update-product-collection-enrollment

v2_update_product_collection_enrollment

Enroll a user in a product collection

teachable-cli v2-enroll-user-in-product-collection

v2_enroll_user_in_product_collection

List enrollments for a product collection

teachable-cli v2-list-enrollments-for-product-collection

v2_list_enrollments_for_product_collection

Remove a product from a product collection

teachable-cli v2-remove-product-from-product-collection

v2_remove_product_from_product_collection

List products in a product collection

teachable-cli v2-list-products-in-product-collection

v2_list_products_in_product_collection

Add a product to a product collection

teachable-cli v2-add-product-to-product-collection

v2_add_product_to_product_collection

Delete a product collection

teachable-cli v2-delete-product-collection

v2_delete_product_collection

Get a product collection

teachable-cli v2-get-product-collection

v2_get_product_collection

Update a product collection

teachable-cli v2-update-product-collection

v2_update_product_collection

Replace a product collection

teachable-cli v2-replace-product-collection

v2_replace_product_collection

List all product collections

teachable-cli v2-list-product-collections

v2_list_product_collections

Create a product collection

teachable-cli v2-create-product-collection

v2_create_product_collection

List all products

teachable-cli v2-list-products

v2_list_products

Get a purchase

teachable-cli v2-get-purchase

v2_get_purchase

List purchases

teachable-cli v2-list-purchases

v2_list_purchases

Get a transaction

teachable-cli v2-get-transaction

v2_get_transaction

List transactions

teachable-cli v2-list-transactions

v2_list_transactions

Create pre-signed upload credentials

teachable-cli v2-create-pre-signed-upload-credentials

v2_create_pre_signed_upload_credentials

List purchases for a user

teachable-cli v2-list-purchases-for-user

v2_list_purchases_for_user

List quiz responses for a user

teachable-cli v2-list-quiz-responses-for-user

v2_list_quiz_responses_for_user

Revoke a user session

teachable-cli v2-revoke-user-session

v2_revoke_user_session

Revoke all user sessions

teachable-cli v2-revoke-user-sessions

v2_revoke_user_sessions

List user sessions

teachable-cli v2-list-user-sessions

v2_list_user_sessions

Delete a user

teachable-cli v2-delete-user

v2_delete_user

Get a user

teachable-cli v2-get-user

v2_get_user

Update a user

teachable-cli v2-update-user

v2_update_user

List users

teachable-cli v2-list-users

v2_list_users

Create a user

teachable-cli v2-create-user

v2_create_user

List private school profiles

teachable-cli list-accounts

list_accounts

Inspect native contract

teachable-cli get-operation-schema

get_operation_schema

Review ordered school effects

teachable-cli preview-school-batch

preview_school_batch

Execute reviewed school effects

teachable-cli submit-school-batch

submit_school_batch

Export bounded private metadata

teachable-cli export-resources

export_resources

Contents

1. What you can ask it

Ask for a bounded task in the intended school:

  • List the first five courses and show which are published.

  • Read this student's current enrollments before preparing a course enrollment change.

  • Preview these exact enrollment changes, then execute only the batch I approve.

  • Export up to ten pages of course metadata into a new private file and report continuation.

  • Inspect the beta lecture-list schema after I explicitly enable the version 2 profile.

  • Show the separate upload-credential and content-attachment steps; do not publish automatically.

The terminal illustrates real implemented tool names and a reviewed workflow. It is not an authenticated recording of a school account.

2. Set up your account

Use the intended school owner account to open Settings > API > Create API Key. Give the key a name and select only the permissions needed. API eligibility and beta access remain provider-controlled. Follow Teachable authentication.

Choose one source: TEACHABLE_API_KEY in private runtime settings, or TEACHABLE_CREDENTIALS_FILE pointing to an absolute owner-private regular JSON file containing api_key. Never mix them. The file must be non-symlink, at most 64 KiB and, on POSIX, owned by the process user with owner-only permissions. Restrict Windows ACLs separately. Credentials do not belong in repositories, chat, screenshots, user payloads or project MCP config.

teachable-cli login
teachable-cli list-accounts --agent
teachable-cli doctor
teachable-cli doctor --network

Login prints instructions only. Local doctor reports configuration availability without proving the key is valid. The deliberate network option performs one version-matched courses read. Success there does not establish all scopes, ownership or every native task. Keys are cached within the process; restart clients after rotation. Revoke through Settings > API > More Actions > Revoke Key.

3. Install

Use Node 22+ in the runtime that launches the server. The complete INSTALL.md follows the existing house client setup for Codex, desktop apps, editors, shell agents and all three declared desktop OSes.

npm install -g @thenavidm/teachable-mcp-cli@latest
teachable-cli --version
teachable-cli tools
teachable-cli schema list-courses
codex mcp add teachable -- npx -y @thenavidm/teachable-mcp-cli@latest
codex mcp list

Configure private credentials before the first account read. This is a local stdio MCP, without a public HTTP listener. teachable-cli install <client> writes the entry for Claude Code, Codex, Claude Desktop, Cursor, VS Code or Gemini CLI in that client's own format; add --dry-run to see it first. The desktop release is teachable-3.0.0.mcpb; use the supported host Extensions screen. It bundles production JavaScript dependencies, while the host must supply a compatible Node runtime.

4. Output and exit codes

Schemas, validation, handlers and confirmation policy are shared across both binaries. --agent selects compact JSON presentation for shell agents; --select a,b.c projects output fields. Use --json or --compact directly when appropriate. --dry-run checks a command and prints what would run, without running it. --yes never grants effect approval. Errors go to stderr as one JSON object with error, code and, where it helps, hint.

Exit

Meaning

0

Successful command

1

Unexpected error, worth an issue

2

Usage, invalid arguments or refused effect

3

Resource not found

4

Provider authentication/permission failure

5

Other API or network failure

7

Provider rate limit

10

Missing or invalid local configuration

teachable-cli list-courses --page 1 --per 5 --agent
teachable-cli get-course --course-id 7 --account intended-school --json
teachable-cli schema create-enrollment

Numeric IDs in examples are illustrative; replace them with reviewed IDs in the intended school. Native snake_case fields become dash flags. Objects and arrays use JSON. Do not mix native body flags, payload and payload_file. Native body requirements are validated before fetching, even when individual flags are optional in discovery.

5. Which surface and what each costs

CLI suits shell agents, scripts and selected tasks. MCP suits supported apps that discover and call tools directly. Both execute the same implementation.

Mode

Discovered tasks

Read operations

Confirmed effects

Stable v1 default

26

19

7

Stable read-only

19

19

0

Explicit beta enabled

123

64

59

Beta enabled read-only

64

64

0

The beta-enabled list includes both API versions plus five local helpers. Each native call still requires a matching profile version. CLI help/results enter context on demand; MCP schema loading may be deferred by the client. Discovery size alone cannot show task efficiency.

Measured 2026-10-04, 2.0.1 against 3.0.0, with tasks that need no school account, so they measure the tools' own cost rather than provider responses:

What

2.0.1

3.0.0

Claude Code 2.1.286, every tool loaded (ENABLE_TOOL_SEARCH=false)

12,576 and 12,579 tokens

12,548 and 12,550 tokens

Claude Code, default tool search

753 and 757 tokens

754 and 757 tokens

SKILL.md, read once in Claude Code

1,232 and 1,227 tokens

1,258 and 1,259 tokens

Codex 0.159.3 over MCP: preview one enrollment batch, reply with its hash

77,218 and 77,222 input tokens

77,266 and 77,274 input tokens

Codex over the CLI, the same task, median of five runs

166,358 input tokens; a failed command in every run

147,386 input tokens; no failed commands

Each Claude Code number is one short prompt with and without the server or the skill, so the difference is exactly what Claude Code sends. Codex ran gpt-6.1-sol with approval policy never and a read-only sandbox, and its numbers are total input tokens from codex exec --json. Over MCP, the 48 extra Codex tokens come from the standard confirm wording: putting the old wording back removed them. Over the CLI, 2.0.1 rejected the tasks as a JSON array, so the model retried, while 3.0.0 accepted them and which found the command. The skill's one-line description is unchanged. No schema-character estimate or borrowed benchmark is published as savings.

6. Tools

All 123 beta-enabled discovered tasks are documented below. Stable default exposes 26; beta tasks are explicitly marked and require matching version profiles. The five local workflows are not additional provider endpoints.

list_enrollments

Fetch active enrolled students and student progress for a specific course.

CLI: teachable-cli list-enrollments. Policy: read.

Native: GET /v1/courses/{course_id}/enrollments. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

Return enrollments for a specific course by the unique course ID.

enrolled_in_after

string (format=date-time)

Optional

Search for students who are enrolled after a specific date/time. Formatted in ISO8601.

enrolled_in_before

string (format=date-time)

Optional

Search for students who are enrolled before a specific date/time. Formatted in ISO8601.

sort_direction

asc, desc

Optional

Enrollments are sorted by the 'enrolled_at' datetime. You can choose the direction by including the sort_direction param.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

mark_lecture_complete

Mark a specific course lecture as complete.

CLI: teachable-cli mark-lecture-complete. Policy: explicit confirmation.

Native: POST /v1/courses/{course_id}/lectures/{lecture_id}/mark_complete. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

The unique course ID that contains the lecture.

lecture_id

integer (minimum=1, format=int32)

Required

The unique lecture ID.

user_id

integer (format=int32)

Optional

The unique ID of the user.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

user_id

integer (format=int32)

Required

The unique ID of the user.

list_quiz_responses

Fetch the responses of quiz.

CLI: teachable-cli list-quiz-responses. Policy: read.

Native: GET /v1/courses/{course_id}/lectures/{lecture_id}/quizzes/{quiz_id}/responses. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

Return results by unique course ID that contains the lecture.

lecture_id

integer (minimum=1, format=int32)

Required

Return results by unique lecture ID.

quiz_id

integer (minimum=1, format=int32)

Required

Return results by unique quiz attachment ID.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

get_quiz

Fetch a specific quiz information.

CLI: teachable-cli get-quiz. Policy: read.

Native: GET /v1/courses/{course_id}/lectures/{lecture_id}/quizzes/{quiz_id}. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

Return results by unique course ID that contains the lecture.

lecture_id

integer (minimum=1, format=int32)

Required

Return results by unique lecture ID.

quiz_id

integer (minimum=1, format=int32)

Required

Return results by unique quiz attachment ID.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

list_quizzes

Fetch an id list of quizzes in a specific course lecture.

CLI: teachable-cli list-quizzes. Policy: read.

Native: GET /v1/courses/{course_id}/lectures/{lecture_id}/quizzes. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

Return results by unique course ID that contains the lecture.

lecture_id

integer (minimum=1, format=int32)

Required

Return results by unique lecture ID.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

get_video

Fetch a specific video information.

CLI: teachable-cli get-video. Policy: read.

Native: GET /v1/courses/{course_id}/lectures/{lecture_id}/videos/{video_id}. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

Return results by unique course ID that contains the lecture.

lecture_id

integer (minimum=1, format=int32)

Required

Return results by unique lecture ID.

video_id

integer (minimum=1, format=int32)

Required

Return results by unique video attachment ID.

user_id

integer (format=int32)

Optional

Specify the user who is watching the video

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

get_lecture

Fetch content of a specific course lecture.

CLI: teachable-cli get-lecture. Policy: read.

Native: GET /v1/courses/{course_id}/lectures/{lecture_id}. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

Return results by unique course ID that contains the lecture.

lecture_id

integer (minimum=1, format=int32)

Required

Return results by unique lecture ID.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

get_course_progress

Fetch a specific user's course progress.

CLI: teachable-cli get-course-progress. Policy: read.

Native: GET /v1/courses/{course_id}/progress. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

The unique course ID that contains the lecture.

user_id

integer (format=int32)

Required

The unique ID of the user.

page

integer (format=int32)

Optional

Used in pagination when number of courses exceed the maximum amount of results per page

per

integer (format=int32)

Optional

Used in pagination to define amount of courses per page, when not defined the maximum is 20

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

get_course

Fetch a specific course by ID.

CLI: teachable-cli get-course. Policy: read.

Native: GET /v1/courses/{course_id}. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer (minimum=1, format=int32)

Required

Return a course by its unique ID.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

list_courses

Fetch all courses at your school.

CLI: teachable-cli list-courses. Policy: read.

Native: GET /v1/courses. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

name

string

Optional

Filter courses by course name

is_published

boolean

Optional

Filter courses by published status. If true, return published courses. If false, return unpublished courses.

author_bio_id

integer (format=int32)

Optional

Filter courses by a specific course author via the course author's bio ID.

created_at

string (format=date-time)

Optional

Return courses by the date & time of course creation. Formatted in ISO8601.

page

integer (format=int32)

Optional

Used in pagination when number of courses exceed the maximum amount of results per page

per

integer (format=int32)

Optional

Used in pagination to define amount of courses per page, when not defined the maximum is 20

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

create_enrollment

Enroll a user in a course.

CLI: teachable-cli create-enrollment. Policy: explicit confirmation.

Native: POST /v1/enroll. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer (format=int32)

Optional

The unique ID of the user.

course_id

integer (format=int32)

Optional

The unique ID of the course.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

user_id

integer (format=int32)

Required

The unique ID of the user.

course_id

integer (format=int32)

Required

The unique ID of the course.

get_pricing_plan

Fetch details of a specific pricing plan. Currently only supports pricing plans associated with courses.

CLI: teachable-cli get-pricing-plan. Policy: read.

Native: GET /v1/pricing_plans/{pricing_plan_id}. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

pricing_plan_id

integer (minimum=1, format=int32)

Required

Search for a pricing plan by its unique ID.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

list_pricing_plans

Fetch all the pricing plans at your school

CLI: teachable-cli list-pricing-plans. Policy: read.

Native: GET /v1/pricing_plans. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

page

integer (format=int32)

Optional

Used in pagination when number of pricing plans exceeds the maximum amount of results per page

per

integer (format=int32)

Optional

Used in pagination to define amount of pricing plans per page, when not defined the maximum is 5

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

list_transactions

Fetch a list of sales transactions made in your school. (New transactions can take up to two minutes to be returned via API call from the time of sale.)

CLI: teachable-cli list-transactions. Policy: read.

Native: GET /v1/transactions. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer (format=int32)

Optional

Native field

affiliate_id

integer (format=int32)

Optional

Native field

course_id

integer (format=int32)

Optional

Native field

pricing_plan_id

integer (format=int32)

Optional

Native field

is_fully_refunded

boolean

Optional

Native field

is_chargeback

boolean

Optional

Native field

start

string (format=date-time)

Optional

The beginning of the time period to return results for (exclusive), in ISO8601 format.

end

string (format=date-time)

Optional

The end of the time period to return results for (inclusive), in ISO8601 format.

page

integer (format=int32)

Optional

Used in pagination when number of transactions exceed the maximum amount of results per page

per

integer (format=int32)

Optional

Used in pagination to define amount of transactions per page, when not defined the maximum is 20

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

unenroll_user

Unenroll a user from a course.

CLI: teachable-cli unenroll-user. Policy: explicit confirmation.

Native: POST /v1/unenroll. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer (format=int32)

Optional

The unique ID of the user.

course_id

integer (format=int32)

Optional

The unique ID of the course.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

user_id

integer (format=int32)

Required

The unique ID of the user.

course_id

integer (format=int32)

Required

The unique ID of the course.

get_user

List a specific user and their course enrollments by user ID.

CLI: teachable-cli get-user. Policy: read.

Native: GET /v1/users/{user_id}. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer (minimum=1, format=int32)

Required

The unique ID of the user.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

update_user

Update the name or src of a user.

CLI: teachable-cli update-user. Policy: explicit confirmation.

Native: PATCH /v1/users/{user_id}. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer (minimum=1, format=int32)

Required

The unique ID of the user.

name

string

Optional

The name of the user.

src

string

Optional

The signup source of the user, which is displayed on the Information tab of the user profile. .

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Optional

The name of the user.

src

string

Optional

The signup source of the user, which is displayed on the Information tab of the user profile. .

list_users

Get a list of users

CLI: teachable-cli list-users. Policy: read.

Native: GET /v1/users. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

page

integer (format=int32)

Optional

Used in pagination when number of users exceed the maximum amount of results per page

per

integer (format=int32)

Optional

Used in pagination to define amount of users per page, when not defined the maximum is 20

email

string

Optional

Filter users by user email.

search_after

integer (format=int32)

Optional

Used when number of users exceeds 10,000 records. Use the search_after value in the parameters to search the next set of records.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

create_user

Create a new user

CLI: teachable-cli create-user. Policy: explicit confirmation.

Native: POST /v1/users. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

name

string

Optional

The name of the new user.

email

string

Optional

The email address of the new user..

src

string

Optional

The signup source of the user, Information tab of the user profile. SRC can also be used as a custom value when creating users in your school. For example, if you use any unique identifiers to help manage your users in multiple external systems (such as unique IDs, tags, etc.), you can use the src field to keep this identifier associated with your user in Teachable.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Optional

The name of the new user.

email

string

Required

The email address of the new user..

password

string

Optional

The password of the new user. Must be at least 6 characters.

src

string

Optional

The signup source of the user, Information tab of the user profile. SRC can also be used as a custom value when creating users in your school. For example, if you use any unique identifiers to help manage your users in multiple external systems (such as unique IDs, tags, etc.), you can use the src field to keep this identifier associated with your user in Teachable.

get_webhook_events

Fetch all the events for a webhook.

CLI: teachable-cli get-webhook-events. Policy: read.

Native: GET /v1/webhooks/{webhook_id}/events. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

webhook_id

integer (format=int32)

Required

The unique ID of the webhook.

response_http_status_gte

integer (format=int32)

Optional

Filter responses by HTTP status code of the webhook event, greater than or equal to the provided value (i.e., enter 200 to search for webhook events that had an HTTP status code of 200 or greater).

response_http_status_lte

integer (format=int32)

Optional

Filter responses by HTTP status of the webhook event, less than or equal to the provided value. (e.g., enter 200 to search for webhook events that had an HTTP status code of 200 or less).

created_before

string (format=date-time, default=2020-04-17T19:44:03Z)

Optional

Search for webhook events that were created before a specific date/time. Formatted in ISO 8601.

created_after

string (format=date-time, default=2020-04-17T19:44:03Z)

Optional

Search for webhook events that were created after a specific date/time. Formatted in ISO 8601.

page

integer (format=int32)

Optional

Set the page number to be returned. (i.e., If you have two pages of results with 20 results per page, set the page value to 1 to receive results 1 through 20, or set the page value to 2 to receive results 21-40).

per

integer (format=int32)

Optional

Set the maximum number of results to be returned by page. By default, each page will return 20 results.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

list_webhooks

Fetch all webhook events for your school.

CLI: teachable-cli list-webhooks. Policy: read.

Native: GET /v1/webhooks. Version: stable v1. Current source.

Argument

Type or constraint

Requirement

Meaning

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_get_school_customizations

Retrieve the current school customization (theme) settings exposed by the public API.

CLI: teachable-cli v2-get-school-customizations. Policy: read.

Native: GET /v2/customizations. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_delete_pricing_plan

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Soft-delete a pricing plan by setting is_published to false. The pricing plan record is preserved for audit purposes but will no longer be visible to end users.

CLI: teachable-cli v2-delete-pricing-plan. Policy: explicit confirmation.

Native: DELETE /v2/products/{product_type}/{product_id}/pricing-plans/{plan_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_type

string

Required

Product type (courses, product-collections, digital-downloads, coaching, membership-tiers)

product_id

integer

Required

Product ID

plan_id

integer

Required

Pricing plan ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_pricing_plan

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a single pricing plan for a specific product across all supported product types (courses, product-collections, digital-downloads, coaching, membership-tiers).

CLI: teachable-cli v2-get-pricing-plan. Policy: read.

Native: GET /v2/products/{product_type}/{product_id}/pricing-plans/{plan_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_type

string

Required

Product type (courses, product-collections, digital-downloads, coaching, membership-tiers)

product_id

integer

Required

Product ID

plan_id

integer

Required

Pricing plan ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_pricing_plan

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Update a pricing plan. Content, visibility, access-limit, and enrollment-cap fields are applied. Read-only fields (for example price, currency) are rejected by request schema validation with 400.

CLI: teachable-cli v2-update-pricing-plan. Policy: explicit confirmation.

Native: PATCH /v2/products/{product_type}/{product_id}/pricing-plans/{plan_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_type

string

Required

Product type (courses, product-collections, digital-downloads, coaching, membership-tiers)

product_id

integer

Required

Product ID

plan_id

integer

Required

Pricing plan ID

name

string nullable

Optional

Native field

description

string nullable

Optional

Native field

detailed_description

string nullable

Optional

Native field

cc_statement_description

string nullable

Optional

Text shown on customer card statements. On schools using the new payments experience this is stored but not yet applied to statements.

is_published

boolean

Optional

Native field

access_limit_date

string nullable (format=date-time)

Optional

Native field

access_limit_interval

string nullable

Optional

Native field

access_limit_duration

integer nullable

Optional

Native field

enrollment_cap

integer nullable

Optional

Requires the school feature plan_supports_enrollment_cap. Returns 422 when enrollment_cap or enrollment_cap_expires_at is present and the feature is disabled.

enrollment_cap_expires_at

string nullable (format=date-time)

Optional

Requires the school feature plan_supports_enrollment_cap. Returns 422 when enrollment_cap or enrollment_cap_expires_at is present and the feature is disabled.

enrollment_cap_display_priority

string nullable

Optional

Native field

enrollment_cap_fulfillment_count

integer nullable

Optional

Native field

enrollment_cap_visible

boolean nullable

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string nullable

Optional

Native field

description

string nullable

Optional

Native field

detailed_description

string nullable

Optional

Native field

cc_statement_description

string nullable

Optional

Text shown on customer card statements. On schools using the new payments experience this is stored but not yet applied to statements.

is_published

boolean

Optional

Native field

access_limit_date

string nullable (format=date-time)

Optional

Native field

access_limit_interval

string nullable

Optional

Native field

access_limit_duration

integer nullable

Optional

Native field

enrollment_cap

integer nullable

Optional

Requires the school feature plan_supports_enrollment_cap. Returns 422 when enrollment_cap or enrollment_cap_expires_at is present and the feature is disabled.

enrollment_cap_expires_at

string nullable (format=date-time)

Optional

Requires the school feature plan_supports_enrollment_cap. Returns 422 when enrollment_cap or enrollment_cap_expires_at is present and the feature is disabled.

enrollment_cap_display_priority

string nullable

Optional

Native field

enrollment_cap_fulfillment_count

integer nullable

Optional

Native field

enrollment_cap_visible

boolean nullable

Optional

Native field

v2_list_pricing_plans_for_product

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a list of pricing plans for a specific product across all supported product types (courses, product-collections, digital-downloads, coaching, membership-tiers). A 400 may indicate an invalid product_type or invalid page / per_page.

CLI: teachable-cli v2-list-pricing-plans-for-product. Policy: read.

Native: GET /v2/products/{product_type}/{product_id}/pricing-plans. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_type

string

Required

Product type (courses, product-collections, digital-downloads, coaching, membership-tiers)

product_id

integer

Required

Product ID

page

integer (minimum=1)

Optional

Page number (1-based integer)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (integer)

sort_by

string

Optional

Sort field (created_at, updated_at)

sort_direction

string

Optional

Sort direction (asc, desc)

is_published

boolean

Optional

Filter by publish status. When omitted, returns both published and unpublished pricing plans.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_pricing_plan_for_product

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Create a pricing plan for a specific product across all supported product types (courses, product-collections, digital-downloads, coaching, membership-tiers).

CLI: teachable-cli v2-create-pricing-plan-for-product. Policy: explicit confirmation.

Native: POST /v2/products/{product_type}/{product_id}/pricing-plans. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_type

string

Required

Product type (courses, product-collections, digital-downloads, coaching, membership-tiers)

product_id

integer

Required

Product ID

name

string

Optional

Native field

currency

string

Optional

ISO 4217 currency code. On schools using the new payments experience this is set automatically from the school's payment settings and the submitted value is ignored. The response returns the currency that was applied.

price

integer

Optional

Native field

is_recurring

boolean

Optional

Native field

billing_interval

day, week, month, year

Optional

Required when is_recurring is true. Membership tier plans on schools using the new payments experience accept only month or year.

billing_interval_count

integer nullable

Optional

Required when is_recurring is true. Membership tier plans on schools using the new payments experience must use 1. Defaults to 1 when omitted.

description

string nullable

Optional

Native field

detailed_description

string nullable

Optional

Native field

free_trial_length

integer nullable

Optional

Native field

access_limit_date

string nullable (format=date-time)

Optional

Native field

access_limit_interval

string nullable

Optional

Native field

access_limit_duration

integer nullable

Optional

Native field

enrollment_cap

integer nullable

Optional

Requires the school feature plan_supports_enrollment_cap. Returns 422 when enrollment_cap or enrollment_cap_expires_at is present and the feature is disabled.

enrollment_cap_expires_at

string nullable (format=date-time)

Optional

Requires the school feature plan_supports_enrollment_cap. Returns 422 when enrollment_cap or enrollment_cap_expires_at is present and the feature is disabled.

enrollment_cap_display_priority

string nullable

Optional

Native field

enrollment_cap_fulfillment_count

integer nullable

Optional

Native field

enrollment_cap_visible

boolean nullable

Optional

Native field

num_payments_required

integer nullable

Optional

Native field

position

integer nullable

Optional

Native field

is_published

boolean

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Required

Native field

currency

string

Required

ISO 4217 currency code. On schools using the new payments experience this is set automatically from the school's payment settings and the submitted value is ignored. The response returns the currency that was applied.

price

integer

Required

Native field

is_recurring

boolean

Optional

Native field

billing_interval

day, week, month, year

Optional

Required when is_recurring is true. Membership tier plans on schools using the new payments experience accept only month or year.

billing_interval_count

integer nullable

Optional

Required when is_recurring is true. Membership tier plans on schools using the new payments experience must use 1. Defaults to 1 when omitted.

description

string nullable

Optional

Native field

detailed_description

string nullable

Optional

Native field

free_trial_length

integer nullable

Optional

Native field

access_limit_date

string nullable (format=date-time)

Optional

Native field

access_limit_interval

string nullable

Optional

Native field

access_limit_duration

integer nullable

Optional

Native field

enrollment_cap

integer nullable

Optional

Requires the school feature plan_supports_enrollment_cap. Returns 422 when enrollment_cap or enrollment_cap_expires_at is present and the feature is disabled.

enrollment_cap_expires_at

string nullable (format=date-time)

Optional

Requires the school feature plan_supports_enrollment_cap. Returns 422 when enrollment_cap or enrollment_cap_expires_at is present and the feature is disabled.

enrollment_cap_display_priority

string nullable

Optional

Native field

enrollment_cap_fulfillment_count

integer nullable

Optional

Native field

enrollment_cap_visible

boolean nullable

Optional

Native field

num_payments_required

integer nullable

Optional

Native field

position

integer nullable

Optional

Native field

is_published

boolean

Optional

Native field

v2_delete_coupon

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Archive a multiple-use coupon by unpublishing it (is_published becomes false). This endpoint only manages multiple-use coupons. Returns 204 if the coupon is already archived or does not exist (idempotent).

On schools using the new payments experience, archiving a coupon that has not been linked to the payments experience returns 422 "This coupon cannot be archived." This happens for coupons created before the school migrated to the new payments experience and not yet backfilled.

CLI: teachable-cli v2-delete-coupon. Policy: explicit confirmation.

Native: DELETE /v2/products/coupons/{coupon_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

coupon_id

integer

Required

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_coupon

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a single coupon by ID for the school.

CLI: teachable-cli v2-get-coupon. Policy: read.

Native: GET /v2/products/coupons/{coupon_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

coupon_id

integer

Required

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_coupon

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Update a multiple-use coupon that is not part of the student-referral program (partial update).

CLI: teachable-cli v2-update-coupon. Policy: explicit confirmation.

Native: PATCH /v2/products/coupons/{coupon_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

coupon_id

integer

Required

Native field

name

string nullable

Optional

Native field

expiration_date

string nullable (format=date-time)

Optional

Native field

number_available

integer nullable

Optional

Native field

cap_visible

boolean

Optional

Native field

display_priority

time, uses

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string nullable

Optional

Native field

expiration_date

string nullable (format=date-time)

Optional

Native field

number_available

integer nullable

Optional

Native field

cap_visible

boolean

Optional

Native field

display_priority

time, uses

Optional

Native field

v2_list_coupons

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a list of coupons for the school. Excludes single-use and student-referral coupons. Without product context, returns only school-wide (non-product-specific) coupons.

CLI: teachable-cli v2-list-coupons. Policy: read.

Native: GET /v2/products/coupons. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

is_published

boolean

Optional

Native field

pricing_plan_id

integer

Optional

Filter by pricing plan ID. Meaningful on schools not using the new payments experience; on schools using the new payments experience, matches only coupons scoped by pricing plan (typically empty).

product_type

course, coaching, creator_product, bundle, product_collection, digital_download, digital_product, membership_tier

Optional

Filter by product. On schools using the new payments experience, resolves via the product itself; otherwise resolves via the pricing plans attached to it. Must be paired with product_id.

product_id

integer

Optional

ID of the entity identified by product_type; required when product_type is present.

created_after

string

Optional

ISO8601 datetime; invalid values return 400. Date range between created_after and created_before cannot exceed 90 days.

created_before

string

Optional

ISO8601 datetime; invalid values return 400. Date range between created_after and created_before cannot exceed 90 days.

page

integer (minimum=1)

Optional

Native field

per_page

integer (minimum=1, maximum=100)

Optional

Native field

sort_by

string

Optional

Sort by field (created_at, updated_at)

sort_direction

string

Optional

Sort direction (asc, desc)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_coupon

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Create a multiple-use coupon. Use scope_type for a school-wide coupon, pricing_plan_id to restrict it to one price (schools not using the new payments experience), or product_type + product_id to restrict it to one product (schools using the new payments experience). Exactly one of the three must be set.

CLI: teachable-cli v2-create-coupon. Policy: explicit confirmation.

Native: POST /v2/products/coupons. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

code

string

Optional

Native field

name

string

Optional

On schools using the new payments experience, maximum length is 40 characters.

expiration_date

string nullable (format=date-time)

Optional

On schools using the new payments experience, this field is required, must be a future date, and must be within 5 years from now.

number_available

integer nullable

Optional

On schools using the new payments experience, this field is required and must be at least 1.

discount_amount

integer nullable

Optional

On schools using the new payments experience, exactly one of discount_percent or discount_amount is required, and the minimum is 1. When discount_amount is set, discount_currency is required.

discount_currency

string nullable

Optional

On schools using the new payments experience, required when discount_amount is set; not allowed when discount_percent is set.

discount_percent

number nullable (minimum=0, maximum=1)

Optional

On schools using the new payments experience, exactly one of discount_percent or discount_amount is required, and the minimum is 0.01%. discount_percent and discount_currency cannot be provided together.

discount_in_months

integer nullable

Optional

Required when duration_kind is "repeating". Must be blank when duration_kind is not "repeating". Minimum value is 1.

pricing_plan_id

integer nullable

Optional

Only supported on schools not using the new payments experience. Sending this field on schools using the new payments experience returns 422. Mutually exclusive with scope_type and product_type + product_id.

product_type

course, coaching, creator_product, bundle, product_collection, digital_download, digital_product, membership_tier

Optional

Only supported on schools using the new payments experience. Sending this field otherwise returns 422. Must be paired with product_id. Mutually exclusive with scope_type and pricing_plan_id.

product_id

integer nullable

Optional

Only supported on schools using the new payments experience. Must be paired with product_type.

duration_kind

forever, once, repeating

Optional

On schools using the new payments experience, when set to "repeating", discount_in_months is required.

scope_type

all_products, courses, product_collections, creator_products, digital_products, membership_tiers

Optional

Available on all schools. Mutually exclusive with pricing_plan_id and product_type + product_id.

cap_visible

boolean

Optional

Native field

display_priority

time, uses

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

code

string

Required

Native field

name

string

Required

On schools using the new payments experience, maximum length is 40 characters.

expiration_date

string nullable (format=date-time)

Optional

On schools using the new payments experience, this field is required, must be a future date, and must be within 5 years from now.

number_available

integer nullable

Optional

On schools using the new payments experience, this field is required and must be at least 1.

discount_amount

integer nullable

Optional

On schools using the new payments experience, exactly one of discount_percent or discount_amount is required, and the minimum is 1. When discount_amount is set, discount_currency is required.

discount_currency

string nullable

Optional

On schools using the new payments experience, required when discount_amount is set; not allowed when discount_percent is set.

discount_percent

number nullable (minimum=0, maximum=1)

Optional

On schools using the new payments experience, exactly one of discount_percent or discount_amount is required, and the minimum is 0.01%. discount_percent and discount_currency cannot be provided together.

discount_in_months

integer nullable

Optional

Required when duration_kind is "repeating". Must be blank when duration_kind is not "repeating". Minimum value is 1.

pricing_plan_id

integer nullable

Optional

Only supported on schools not using the new payments experience. Sending this field on schools using the new payments experience returns 422. Mutually exclusive with scope_type and product_type + product_id.

product_type

course, coaching, creator_product, bundle, product_collection, digital_download, digital_product, membership_tier

Optional

Only supported on schools using the new payments experience. Sending this field otherwise returns 422. Must be paired with product_id. Mutually exclusive with scope_type and pricing_plan_id.

product_id

integer nullable

Optional

Only supported on schools using the new payments experience. Must be paired with product_type.

duration_kind

forever, once, repeating

Required

On schools using the new payments experience, when set to "repeating", discount_in_months is required.

scope_type

all_products, courses, product_collections, creator_products, digital_products, membership_tiers

Optional

Available on all schools. Mutually exclusive with pricing_plan_id and product_type + product_id.

cap_visible

boolean

Optional

Native field

display_priority

time, uses

Optional

Native field

v2_list_comments_for_course

Retrieve a paginated list of comments across all lectures in a course. Results can be filtered by status and creation date.

Without a status filter, comments in all statuses are returned. Use the status parameter to narrow results to a specific moderation state.

CLI: teachable-cli v2-list-comments-for-course. Policy: read.

Native: GET /v2/products/courses/{course_id}/comments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

created_after

string

Optional

Filter comments created after this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

created_before

string

Optional

Filter comments created before this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

status

string

Optional

Filter by status (awaiting_review, approved, removed, denied)

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

sort_by

string

Optional

Sort by field (created_at, updated_at)

sort_direction

string

Optional

Sort direction (asc, desc)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_get_compliance_settings_for_course

Retrieve the compliance configuration for a specific course.

CLI: teachable-cli v2-get-compliance-settings-for-course. Policy: read.

Native: GET /v2/products/courses/{course_id}/compliance. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_compliance_settings_for_course

Update the compliance configuration for a specific course.

Lecture order requirement:

When either requirements.video_completion_enforced or requirements.quiz_pass_required is true, requirements.lecture_order_required must also be true. Requests that violate this return 422 validation_failed.

The rule is checked against the course's resulting state — your request merged over its stored values — so an omitted field is evaluated using what is already saved. Sending only {"requirements":{"video_completion_enforced":true}} therefore succeeds on a course that already enforces lecture order and fails on one that does not. Send lecture_order_required: true alongside either dependent field for a result that does not depend on the course's current settings.

Certificate configuration:

The certificate_settings.template_id must reference an existing certificate page (template) belonging to the school. Certificate pages are created through the school admin UI — there is no API endpoint for creating them. Use GET /v2/products/courses/{course_id}/compliance to retrieve the current template_id if one is already configured.

When template_id is set and auto_issue is true, certificates are automatically issued to students upon 100% course completion. The school's plan must also support native certificates.

CLI: teachable-cli v2-update-compliance-settings-for-course. Policy: explicit confirmation.

Native: PATCH /v2/products/courses/{course_id}/compliance. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

requirements

object

Optional

Completion requirements. When video_completion_enforced or quiz_pass_required ends up true, lecture_order_required must also be true, or the request returns 422. The rule is applied to the request body merged over the course's persisted values, so an omitted field is evaluated using its stored value rather than being ignored.

certificate_settings

object

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

requirements

object

Optional

Completion requirements. When video_completion_enforced or quiz_pass_required ends up true, lecture_order_required must also be true, or the request returns 422. The rule is applied to the request body merged over the course's persisted values, so an omitted field is evaluated using its stored value rather than being ignored.

requirements.video_completion_enforced

boolean

Optional

Native field

requirements.quiz_pass_required

boolean

Optional

Native field

requirements.quiz_minimum_score

number

Optional

Native field

requirements.quiz_maximum_retakes

integer

Optional

Native field

requirements.lecture_order_required

boolean

Optional

Must be true when video_completion_enforced or quiz_pass_required is true.

certificate_settings

object

Optional

Native field

certificate_settings.auto_issue

boolean

Optional

Native field

certificate_settings.template_id

integer

Optional

Omit to leave the certificate template unchanged. A certificate template cannot be detached through this endpoint.

v2_unenroll_user_from_course

Unenroll a user from a specific course.

CLI: teachable-cli v2-unenroll-user-from-course. Policy: explicit confirmation.

Native: DELETE /v2/products/courses/{course_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_user_s_enrollments_for_course

Retrieve a user's active enrollments for a course. A user may hold more than one active enrollment for the same course — e.g. enrollments originating from different sales/products — so results are returned as a paginated collection ordered by enrollment date (most recent first). Disabled and expired-inactive enrollments are excluded; if the user has no active enrollment, an empty collection is returned.

CLI: teachable-cli v2-get-user-s-enrollments-for-course. Policy: read.

Native: GET /v2/products/courses/{course_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

user_id

integer

Required

User ID (enrollment is keyed by user_id in this scope)

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_course_enrollment

Enroll a user in a specific course (same as PUT; supported for clients that use PATCH for upsert).

CLI: teachable-cli v2-update-course-enrollment. Policy: explicit confirmation.

Native: PATCH /v2/products/courses/{course_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_enroll_user_in_course

Enroll a user in a specific course. If the user is already enrolled, returns the existing enrollment.

CLI: teachable-cli v2-enroll-user-in-course. Policy: explicit confirmation.

Native: PUT /v2/products/courses/{course_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_list_enrollments_for_course

Retrieve a list of enrollments for a specific course. A user may appear more than once: a single user can hold multiple enrollments for the same course when they originate from different sales/products, and each enrollment is distinguished by its sale. Enrollments can be filtered by enrollment date and status. The list is returned in order of enrollment date, with the most recently enrolled users appearing first.

CLI: teachable-cli v2-list-enrollments-for-course. Policy: read.

Native: GET /v2/products/courses/{course_id}/enrollments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

enrolled_after

string

Optional

Filter enrollments after this ISO8601 datetime. Date range between enrolled_after and enrolled_before cannot exceed 90 days.

enrolled_before

string

Optional

Filter enrollments before this ISO8601 datetime. Date range between enrolled_after and enrolled_before cannot exceed 90 days.

status

string

Optional

Filter by status (active, completed, expired, disabled)

user_id

integer

Optional

Filter enrollments for a specific user

sort_by

string

Optional

Sort field (enrolled_at, completed_at)

sort_direction

string

Optional

Sort direction (asc, desc)

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_delete_content_attachment_from_lesson_lecture

Delete a content item permanently. Only content items returned by the list/get endpoints can be deleted. System-managed content is protected and will return 403.

CLI: teachable-cli v2-delete-content-attachment-from-lesson-lecture. Policy: explicit confirmation.

Native: DELETE /v2/products/courses/{course_id}/lectures/{lecture_id}/attachments/{attachment_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

attachment_id

integer

Required

Attachment ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_content_attachment_for_lesson_lecture

Retrieve a single content item for a specific lesson.

CLI: teachable-cli v2-get-content-attachment-for-lesson-lecture. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}/attachments/{attachment_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

attachment_id

integer

Required

Attachment ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_content_attachment_for_lesson_lecture

Update a single content item for a specific lesson.

CLI: teachable-cli v2-update-content-attachment-for-lesson-lecture. Policy: explicit confirmation.

Native: PATCH /v2/products/courses/{course_id}/lectures/{lecture_id}/attachments/{attachment_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

attachment_id

integer

Required

Attachment ID

embeddable

boolean

Optional

Native field

downloadable

boolean

Optional

Native field

is_published

boolean

Optional

Native field

thumbnail_url

string (maxLength=2048, format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

alt_text

string

Optional

Native field

flagged_as_decorative

boolean

Optional

Native field

text

string (maxLength=100000)

Optional

Native field

code_syntax

string (maxLength=50)

Optional

Native field

open_response_question

object

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

embeddable

boolean

Optional

Native field

downloadable

boolean

Optional

Native field

is_published

boolean

Optional

Native field

thumbnail_url

string (maxLength=2048, format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

alt_text

string

Optional

Native field

flagged_as_decorative

boolean

Optional

Native field

text

string (maxLength=100000)

Optional

Native field

code_syntax

string (maxLength=50)

Optional

Native field

open_response_question

object

Optional

Native field

open_response_question.question

string (maxLength=10000)

Optional

Native field

open_response_question.required

boolean

Optional

Native field

open_response_question.upload_enabled

boolean

Optional

Native field

open_response_question.img_url

string (maxLength=2048)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

open_response_question.img_name

string (maxLength=255)

Optional

Native field

open_response_question.img_alt_text

string (maxLength=255)

Optional

Native field

v2_list_content_attachments_for_lesson_lecture

Retrieve a list of content items for a specific lesson.

CLI: teachable-cli v2-list-content-attachments-for-lesson-lecture. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}/attachments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

page

integer (minimum=1)

Optional

Current Page

per_page

integer (minimum=1, maximum=100)

Optional

Items per Page

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_content_attachment_for_lesson_lecture

Create a new content item for a specific lesson.

CLI: teachable-cli v2-create-content-attachment-for-lesson-lecture. Policy: explicit confirmation.

Native: POST /v2/products/courses/{course_id}/lectures/{lecture_id}/attachments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

kind

text, embed, code_embed, code_display, open_response_question, image, video, audio, pdf_embed, file

Optional

Native field

text

string (maxLength=100000)

Optional

Required for text, code_embed, code_display kinds.

code_syntax

string (maxLength=50)

Optional

Native field

url

string (maxLength=2048)

Optional

Required for embed kind. External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

embeddable

boolean

Optional

Native field

downloadable

boolean

Optional

Native field

question

string (maxLength=10000)

Optional

Required for open_response_question kind.

required

boolean

Optional

Native field

upload_enabled

boolean

Optional

Native field

img_url

string (maxLength=2048)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

img_name

string (maxLength=255)

Optional

Native field

img_alt_text

string (maxLength=255)

Optional

Native field

file

object

Optional

Required for file, image, video, audio, pdf_embed kinds.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

kind

text, embed, code_embed, code_display, open_response_question, image, video, audio, pdf_embed, file

Optional

Native field

text

string (maxLength=100000)

Optional

Required for text, code_embed, code_display kinds.

code_syntax

string (maxLength=50)

Optional

Native field

url

string (maxLength=2048)

Optional

Required for embed kind. External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

embeddable

boolean

Optional

Native field

downloadable

boolean

Optional

Native field

question

string (maxLength=10000)

Optional

Required for open_response_question kind.

required

boolean

Optional

Native field

upload_enabled

boolean

Optional

Native field

img_url

string (maxLength=2048)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

img_name

string (maxLength=255)

Optional

Native field

img_alt_text

string (maxLength=255)

Optional

Native field

file

object

Optional

Required for file, image, video, audio, pdf_embed kinds.

file.url

string

Required

Native field

file.filename

string

Optional

Native field

file.mimetype

string

Required

Native field

file.size

integer

Optional

Native field

v2_reorder_content_attachments_in_lesson_lecture

Reorder all content items for a specific lesson in a single atomic operation. The request body must be a JSON array containing every content item with its new position.

CLI: teachable-cli v2-reorder-content-attachments-in-lesson-lecture. Policy: explicit confirmation.

Native: PUT /v2/products/courses/{course_id}/lectures/{lecture_id}/attachments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

data

array (minItems=1)

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

data

array (minItems=1)

Required

Native field

data.[].id

integer

Required

Native field

data.[].position

integer

Required

Native field

v2_delete_lecture_comment

Delete a specific comment from a lecture.

CLI: teachable-cli v2-delete-lecture-comment. Policy: explicit confirmation.

Native: DELETE /v2/products/courses/{course_id}/lectures/{lecture_id}/comments/{comment_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

comment_id

integer

Required

Comment ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_update_comment_moderation_status

Update the moderation status of a comment. Only the status field can be modified through this endpoint.

Allowed Values

Status

Description

Can be applied when current status is

approved

Approve the comment, making it visible to students.

awaiting_review, approved (no-op)

removed

Soft-delete the comment. It remains as a placeholder to preserve thread structure.

awaiting_review, approved, removed (no-op)

denied

Permanently reject and hide the comment. Cannot be undone.

awaiting_review, approved, removed, denied (no-op)

Setting a status that is not valid for the comment's current state returns a 422 error.

Idempotency: Setting a status equal to the comment's current status is a no-op and returns 200 OK without modifying updated_at.

CLI: teachable-cli v2-update-comment-moderation-status. Policy: explicit confirmation.

Native: PATCH /v2/products/courses/{course_id}/lectures/{lecture_id}/comments/{comment_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

comment_id

integer

Required

Comment ID

status

approved, removed, denied

Optional

New moderation status. approved: approve the comment. removed: soft-delete (kept as thread placeholder). denied: permanently hide the comment.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

status

approved, removed, denied

Required

New moderation status. approved: approve the comment. removed: soft-delete (kept as thread placeholder). denied: permanently hide the comment.

v2_list_comments_for_lecture

Retrieve a paginated list of comments for a specific lecture. Results can be filtered by status and creation date, and sorted by created_at or updated_at.

If the lecture does not have comments enabled, this endpoint returns 200 OK with an empty data array rather than an error.

Without a status filter, comments in all statuses are returned. Use the status parameter to narrow results to a specific moderation state.

Available Statuses

Status

Description

awaiting_review

The comment is pending moderation.

approved

The comment is visible to students.

removed

The comment has been soft-deleted but preserved as a thread placeholder.

denied

The comment has been permanently rejected and hidden.

CLI: teachable-cli v2-list-comments-for-lecture. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}/comments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

created_after

string

Optional

Filter comments created after this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

created_before

string

Optional

Filter comments created before this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

status

string

Optional

Filter by status (awaiting_review, approved, removed, denied)

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

sort_by

string

Optional

Sort by field (created_at, updated_at)

sort_direction

string

Optional

Sort direction (asc, desc)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_comment_on_lecture

Create a comment on a lecture. The comment is authored by the school owner and is automatically approved.

To create a reply to an existing comment, include parent_id. The parent comment must be in awaiting_review or approved status.

CLI: teachable-cli v2-create-comment-on-lecture. Policy: explicit confirmation.

Native: POST /v2/products/courses/{course_id}/lectures/{lecture_id}/comments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

body

string

Optional

Comment text

parent_id

integer nullable

Optional

Parent comment ID for replies

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

body

string

Required

Comment text

parent_id

integer nullable

Optional

Parent comment ID for replies

v2_list_responses_for_lecture_quiz

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a list of aggregated quiz responses for a lecture quiz (most recent submission per user).

CLI: teachable-cli v2-list-responses-for-lecture-quiz. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}/quizzes/{quiz_id}/responses. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

quiz_id

integer

Required

Quiz ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_delete_lecture_quiz

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Delete a specific quiz from a lecture.

CLI: teachable-cli v2-delete-lecture-quiz. Policy: explicit confirmation.

Native: DELETE /v2/products/courses/{course_id}/lectures/{lecture_id}/quizzes/{quiz_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

quiz_id

integer

Required

Quiz ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_lecture_quiz

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a quiz by ID, including questions and correct answer metadata.

CLI: teachable-cli v2-get-lecture-quiz. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}/quizzes/{quiz_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

quiz_id

integer

Required

Quiz ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_list_quizzes_for_lecture

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a list of quizzes for a specific lecture.

CLI: teachable-cli v2-list-quizzes-for-lecture. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}/quizzes. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

sort_by

string

Optional

Sort field (created_at, updated_at)

sort_direction

string

Optional

Sort direction (asc, desc)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_mark_lecture_as_not_completed_for_user

Mark a lecture as not completed for a specific user. Idempotent.

CLI: teachable-cli v2-mark-lecture-as-not-completed-for-user. Policy: explicit confirmation.

Native: DELETE /v2/products/courses/{course_id}/lectures/{lecture_id}/users/{user_id}/completion. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_lecture_completion_status_for_user

Retrieve the completion status of a lecture for a specific user.

CLI: teachable-cli v2-get-lecture-completion-status-for-user. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}/users/{user_id}/completion. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_mark_lecture_as_completed_for_user

Mark a lecture as completed for a user.

This endpoint accepts no request body. Any body sent with the request will be silently ignored. The action (marking the lecture as completed) is determined entirely by the HTTP verb (PUT) and the URL path.

To undo completion (mark the lecture as not completed), use DELETE on this same resource path — do not send a PUT with {"completed": false} or any other body content.

CLI: teachable-cli v2-mark-lecture-as-completed-for-user. Policy: explicit confirmation.

Native: PUT /v2/products/courses/{course_id}/lectures/{lecture_id}/users/{user_id}/completion. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_video_for_lecture

Retrieve details of a specific video attachment for a lecture, including its streaming URL and metadata. When user_id is provided, the response may include user-specific progress data (current_time and url_progress_tracking) if that user has playback progress for the video.

CLI: teachable-cli v2-get-video-for-lecture. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}/videos/{video_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

lecture_id

integer

Required

Lecture ID

video_id

integer

Required

Video attachment ID

user_id

integer

Optional

User ID. When provided, current_time and url_progress_tracking are populated if the user has playback progress for this video; otherwise they are null.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_delete_lecture

Delete a lecture in the requested course scope.

CLI: teachable-cli v2-delete-lecture. Policy: explicit confirmation.

Native: DELETE /v2/products/courses/{course_id}/lectures/{lecture_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID

lecture_id

string

Required

Lecture ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_lecture

Retrieve details of a specific lecture in a course.

CLI: teachable-cli v2-get-lecture. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures/{lecture_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID

lecture_id

string

Required

Lecture ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_lecture

Update a lecture in the requested course scope.

CLI: teachable-cli v2-update-lecture. Policy: explicit confirmation.

Native: PATCH /v2/products/courses/{course_id}/lectures/{lecture_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID

lecture_id

string

Required

Lecture ID

name

string (maxLength=300)

Optional

The lecture name. Must not exceed 300 characters.

is_published

boolean

Optional

Whether the lecture is published. Must be a boolean (true/false).

free_preview

boolean

Optional

Whether the lecture is available as a free preview. Must be a boolean (true/false).

student_comments_enabled

boolean

Optional

Whether student comments are enabled for this lecture. Must be a boolean (true/false).

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string (maxLength=300)

Optional

The lecture name. Must not exceed 300 characters.

is_published

boolean

Optional

Whether the lecture is published. Must be a boolean (true/false).

free_preview

boolean

Optional

Whether the lecture is available as a free preview. Must be a boolean (true/false).

student_comments_enabled

boolean

Optional

Whether student comments are enabled for this lecture. Must be a boolean (true/false).

v2_list_lectures_for_course

Retrieve a list of lectures for a specific course in the current school scope.

CLI: teachable-cli v2-list-lectures-for-course. Policy: read.

Native: GET /v2/products/courses/{course_id}/lectures. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID

section_id

integer

Optional

Filter lectures by section ID

name

string

Optional

Filter lectures by partial name

is_published

string

Optional

Filter by published state (true, false, 1, 0)

created_after

string

Optional

Filter lectures created after this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

created_before

string

Optional

Filter lectures created before this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

sort_by

string

Optional

Sort by field (position, created_at, updated_at)

sort_direction

string

Optional

Sort direction (asc, desc)

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_lecture_in_section

Create a lecture inside a specific section of a course.

CLI: teachable-cli v2-create-lecture-in-section. Policy: explicit confirmation.

Native: POST /v2/products/courses/{course_id}/sections/{section_id}/lectures. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID

section_id

string

Required

Section ID

name

string

Optional

Native field

is_published

boolean

Optional

Native field

free_preview

boolean

Optional

Native field

student_comments_enabled

boolean

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Required

Native field

is_published

boolean

Optional

Native field

free_preview

boolean

Optional

Native field

student_comments_enabled

boolean

Optional

Native field

v2_reorder_lectures_in_section

Reorder all lectures inside a specific section.

CLI: teachable-cli v2-reorder-lectures-in-section. Policy: explicit confirmation.

Native: PUT /v2/products/courses/{course_id}/sections/{section_id}/lectures. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID

section_id

string

Required

Section ID

data

array (minItems=1)

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

data

array (minItems=1)

Required

Native field

data.[].id

integer

Required

Native field

data.[].position

integer

Required

Native field

v2_get_course_section

Retrieve details for a specific section in a specific course.

CLI: teachable-cli v2-get-course-section. Policy: read.

Native: GET /v2/products/courses/{course_id}/sections/{section_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID (must be a positive integer)

section_id

string

Required

Section ID (must be a positive integer)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_course_section

Update a section name for a specific course.

CLI: teachable-cli v2-update-course-section. Policy: explicit confirmation.

Native: PATCH /v2/products/courses/{course_id}/sections/{section_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID (must be a positive integer)

section_id

string

Required

Section ID (must be a positive integer)

name

string (maxLength=300)

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string (maxLength=300)

Required

Native field

v2_replace_course_section

Update a section name (same as PATCH; some clients use PUT for updates).

CLI: teachable-cli v2-replace-course-section. Policy: explicit confirmation.

Native: PUT /v2/products/courses/{course_id}/sections/{section_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID (must be a positive integer)

section_id

string

Required

Section ID (must be a positive integer)

name

string (maxLength=300)

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string (maxLength=300)

Required

Native field

v2_list_sections_for_course

Retrieve a list of sections for a specific course. Sections are ordered by position ascending by default.

CLI: teachable-cli v2-list-sections-for-course. Policy: read.

Native: GET /v2/products/courses/{course_id}/sections. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID (must be a positive integer)

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

sort_by

position, name, created_at, updated_at

Optional

Sort field (position, name, created_at, updated_at)

sort_direction

asc, desc

Optional

Sort direction (asc, desc)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_section_in_course

Create a new section for a specific course.

CLI: teachable-cli v2-create-section-in-course. Policy: explicit confirmation.

Native: POST /v2/products/courses/{course_id}/sections. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID (must be a positive integer)

name

string (maxLength=300)

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string (maxLength=300)

Required

Native field

v2_reorder_sections_in_course

Reorder all sections for a specific course in a single atomic operation.

CLI: teachable-cli v2-reorder-sections-in-course. Policy: explicit confirmation.

Native: PUT /v2/products/courses/{course_id}/sections. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

string

Required

Course ID (must be a positive integer)

data

array (minItems=1)

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

data

array (minItems=1)

Required

Native field

data.[].id

integer

Required

Native field

data.[].position

integer

Required

Native field

v2_get_course_progress_for_user

Retrieve the course progress for a specific user in a specific course. The response includes the overall progress percentage, as well as detailed progress information for each section and lecture within the course.

CLI: teachable-cli v2-get-course-progress-for-user. Policy: read.

Native: GET /v2/products/courses/{course_id}/users/{user_id}/progress. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_get_course

Retrieve details of a specific course.

CLI: teachable-cli v2-get-course. Policy: read.

Native: GET /v2/products/courses/{course_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_course

Update an existing course (partial update).

CLI: teachable-cli v2-update-course. Policy: explicit confirmation.

Native: PATCH /v2/products/courses/{course_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

course_id

integer

Required

Course ID

name

string (minLength=1, maxLength=200)

Optional

Course name. Cannot be blank when provided.

description

string nullable (maxLength=255)

Optional

Course subtitle/heading.

is_published

boolean

Optional

Whether the course is published (accessible to students).

is_listed

boolean

Optional

Whether the course appears in the school's public catalog.

friendly_url

string (maxLength=100, pattern=^[a-zA-Z0-9-_]+$)

Optional

URL slug. Allowed characters: letters, numbers, hyphens (-), and underscores (_). Must be unique within the school.

image_url

string nullable (maxLength=2048, format=uri)

Optional

Course image URL. Must be a valid HTTP/HTTPS URL. Extension is not restricted (CDN URLs without extensions are accepted). Maximum 2048 characters. Blank or null clears the image. External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string (minLength=1, maxLength=200)

Optional

Course name. Cannot be blank when provided.

description

string nullable (maxLength=255)

Optional

Course subtitle/heading.

is_published

boolean

Optional

Whether the course is published (accessible to students).

is_listed

boolean

Optional

Whether the course appears in the school's public catalog.

friendly_url

string (maxLength=100, pattern=^[a-zA-Z0-9-_]+$)

Optional

URL slug. Allowed characters: letters, numbers, hyphens (-), and underscores (_). Must be unique within the school.

image_url

string nullable (maxLength=2048, format=uri)

Optional

Course image URL. Must be a valid HTTP/HTTPS URL. Extension is not restricted (CDN URLs without extensions are accepted). Maximum 2048 characters. Blank or null clears the image. External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

v2_list_courses

Retrieve a list of all courses. The list is returned in order of creation date, with the most recently created courses appearing first.

CLI: teachable-cli v2-list-courses. Policy: read.

Native: GET /v2/products/courses. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

is_published

boolean

Optional

Filter by published state

is_listed

boolean

Optional

Filter by catalog visibility

author_bio_id

integer

Optional

Filter by author bio ID

created_after

string

Optional

Filter courses created after this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

created_before

string

Optional

Filter courses created before this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

name

string

Optional

Filter by partial name (case-insensitive)

search

string

Optional

Search in course name and heading/description (case-insensitive)

sort_by

string

Optional

Sort field. Allowed values: name, created_at, updated_at. Defaults to created_at.

sort_direction

string

Optional

Sort direction (asc, desc)

page

integer (minimum=1)

Optional

Page number (1-based)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (max 100)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_course

Create a new course for the school.

CLI: teachable-cli v2-create-course. Policy: explicit confirmation.

Native: POST /v2/products/courses. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

name

string (minLength=1, maxLength=200)

Optional

Course name. Required.

description

string nullable (maxLength=255)

Optional

Course subtitle/heading.

is_published

boolean

Optional

Whether the course is published (accessible to students). Defaults to false.

is_listed

boolean

Optional

Whether the course appears in the school's public catalog. Defaults to false.

author_bio_id

integer

Optional

ID of an author bio belonging to the school. Required. Cannot be changed after creation.

friendly_url

string (maxLength=100, pattern=^[a-zA-Z0-9-_]+$)

Optional

URL slug for the course. Allowed characters: letters, numbers, hyphens (-), and underscores (_). If omitted, auto-generated from the course name. Must be unique within the school.

image_url

string nullable (maxLength=2048, format=uri)

Optional

Course image URL. Must be a valid HTTP/HTTPS URL. Extension is not restricted (CDN URLs without extensions are accepted). Maximum 2048 characters. Blank or null clears the image. External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string (minLength=1, maxLength=200)

Required

Course name. Required.

description

string nullable (maxLength=255)

Optional

Course subtitle/heading.

is_published

boolean

Optional

Whether the course is published (accessible to students). Defaults to false.

is_listed

boolean

Optional

Whether the course appears in the school's public catalog. Defaults to false.

author_bio_id

integer

Required

ID of an author bio belonging to the school. Required. Cannot be changed after creation.

friendly_url

string (maxLength=100, pattern=^[a-zA-Z0-9-_]+$)

Optional

URL slug for the course. Allowed characters: letters, numbers, hyphens (-), and underscores (_). If omitted, auto-generated from the course name. Must be unique within the school.

image_url

string nullable (maxLength=2048, format=uri)

Optional

Course image URL. Must be a valid HTTP/HTTPS URL. Extension is not restricted (CDN URLs without extensions are accepted). Maximum 2048 characters. Blank or null clears the image. External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

v2_delete_attachment_from_digital_download

Delete an attachment. Returns 204 on success.

CLI: teachable-cli v2-delete-attachment-from-digital-download. Policy: explicit confirmation.

Native: DELETE /v2/products/digital-downloads/{digital_download_id}/attachments/{attachment_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

attachment_id

integer

Required

Attachment ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_attachment_for_digital_download

Retrieve a single attachment for a digital download.

CLI: teachable-cli v2-get-attachment-for-digital-download. Policy: read.

Native: GET /v2/products/digital-downloads/{digital_download_id}/attachments/{attachment_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

attachment_id

integer

Required

Attachment ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_list_attachments_for_digital_download

Retrieve a list of attachments for a digital download.

CLI: teachable-cli v2-list-attachments-for-digital-download. Policy: read.

Native: GET /v2/products/digital-downloads/{digital_download_id}/attachments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

page

integer (minimum=1)

Optional

Page number (default 1, must be >= 1)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (default 20, must be >= 1, max 100)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_attachment_for_digital_download

Create an attachment (download or redirect) for a digital download. Business rules: - All attachments on a digital download must have the same kind. You cannot mix download and redirect attachments on the same product. - For kind: download: filename, url, and size_in_bytes are required. - For kind: redirect: url and button_text are required. Only one redirect attachment is allowed per digital download.

CLI: teachable-cli v2-create-attachment-for-digital-download. Policy: explicit confirmation.

Native: POST /v2/products/digital-downloads/{digital_download_id}/attachments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

filename

string nullable

Optional

Required when kind is 'download'. The name of the file.

size_in_bytes

integer nullable

Optional

Required when kind is 'download'. The size of the file in bytes (must be >= 1).

url

string nullable

Optional

Required for both kinds. External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

kind

download, redirect

Optional

The type of attachment. All attachments on a digital download must have the same kind.

button_text

string nullable

Optional

Required when kind is 'redirect'. The text displayed on the redirect button. Maximum 24 characters.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

filename

string nullable

Optional

Required when kind is 'download'. The name of the file.

size_in_bytes

integer nullable

Optional

Required when kind is 'download'. The size of the file in bytes (must be >= 1).

url

string nullable

Optional

Required for both kinds. External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

kind

download, redirect

Required

The type of attachment. All attachments on a digital download must have the same kind.

button_text

string nullable

Optional

Required when kind is 'redirect'. The text displayed on the redirect button. Maximum 24 characters.

v2_unenroll_user_from_digital_download

Ensure final state of no active access for a user in a digital download product. This operation is idempotent.

CLI: teachable-cli v2-unenroll-user-from-digital-download. Policy: explicit confirmation.

Native: DELETE /v2/products/digital-downloads/{digital_download_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_enrollment_for_digital_download

Retrieve a single enrollment for a user in a digital download product using the base enrollment contract (without progress).

CLI: teachable-cli v2-get-enrollment-for-digital-download. Policy: read.

Native: GET /v2/products/digital-downloads/{digital_download_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_enroll_user_in_digital_download

Create or ensure active access for a user in a digital download product. This operation is idempotent.

CLI: teachable-cli v2-enroll-user-in-digital-download. Policy: explicit confirmation.

Native: PUT /v2/products/digital-downloads/{digital_download_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_list_enrollments_for_digital_download

Retrieve a list of enrollments for a digital download product using the base enrollment contract (without progress).

CLI: teachable-cli v2-list-enrollments-for-digital-download. Policy: read.

Native: GET /v2/products/digital-downloads/{digital_download_id}/enrollments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

page

integer (minimum=1)

Optional

Page number (default 1, must be >= 1)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (default 25, must be >= 1, max 100)

sort_by

string

Optional

Sort field (enrolled_at only)

sort_direction

string

Optional

Sort direction (asc, desc)

enrolled_after

string

Optional

Filter enrollments with enrolled_at >= ISO8601 value. Date range between enrolled_after and enrolled_before cannot exceed 90 days.

enrolled_before

string

Optional

Filter enrollments with enrolled_at <= ISO8601 value. Date range between enrolled_after and enrolled_before cannot exceed 90 days.

status

string

Optional

Filter by status (active, expired, disabled)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_delete_digital_download

Delete a digital download.

CLI: teachable-cli v2-delete-digital-download. Policy: explicit confirmation.

Native: DELETE /v2/products/digital-downloads/{digital_download_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_digital_download

Retrieve details of a specific digital download.

CLI: teachable-cli v2-get-digital-download. Policy: read.

Native: GET /v2/products/digital-downloads/{digital_download_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_digital_download

Update an existing digital download.

CLI: teachable-cli v2-update-digital-download. Policy: explicit confirmation.

Native: PATCH /v2/products/digital-downloads/{digital_download_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

digital_download_id

integer

Required

Digital Download ID

name

string

Optional

Native field

description

string nullable

Optional

Native field

category

string nullable

Optional

Native field

is_published

boolean

Optional

Native field

image_url

string nullable (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Optional

Native field

description

string nullable

Optional

Native field

category

string nullable

Optional

Native field

is_published

boolean

Optional

Native field

image_url

string nullable (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

v2_list_digital_downloads

Retrieve a list of all digital downloads. Default order is by created_at (desc) when no sort is applied; the most recently created digital downloads appear first when sorting by created_at desc.

CLI: teachable-cli v2-list-digital-downloads. Policy: read.

Native: GET /v2/products/digital-downloads. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

page

integer (minimum=1)

Optional

Page number (default 1, must be >= 1)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (default 20, must be >= 1, max 100)

sort_by

string

Optional

Sort by field (created_at, updated_at)

sort_direction

string

Optional

Sort direction (asc, desc)

search

string

Optional

Case-insensitive search on name and description (ILIKE)

name

string

Optional

Filter by name (ILIKE partial match)

is_published

string

Optional

Filter by published state (true, false, 1, 0)

author_bio_id

integer

Optional

Filter by author bio ID

created_after

string

Optional

Filter with created_at after this time (parseable by Time.zone.parse). Date range between created_after and created_before cannot exceed 90 days.

created_before

string

Optional

Filter with created_at before this time (parseable by Time.zone.parse). Date range between created_after and created_before cannot exceed 90 days.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_digital_download

Create a new digital download.

CLI: teachable-cli v2-create-digital-download. Policy: explicit confirmation.

Native: POST /v2/products/digital-downloads. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

name

string

Optional

Native field

description

string nullable

Optional

Native field

category

string nullable

Optional

Native field

is_published

boolean

Optional

Native field

author_bio_id

integer

Optional

Native field

image_url

string nullable (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Required

Native field

description

string nullable

Optional

Native field

category

string nullable

Optional

Native field

is_published

boolean

Optional

Native field

author_bio_id

integer

Required

Native field

image_url

string nullable (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

v2_unenroll_user_from_product_collection

Disable enrollment into a product collection. Revokes access to all product collection contents. For subscriptions, the billing subscription is also canceled.

CLI: teachable-cli v2-unenroll-user-from-product-collection. Policy: explicit confirmation.

Native: DELETE /v2/products/product-collections/{product_collection_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_enrollment_for_product_collection

Retrieve an enrollment into a product collection for a specific user.

CLI: teachable-cli v2-get-enrollment-for-product-collection. Policy: read.

Native: GET /v2/products/product-collections/{product_collection_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_product_collection_enrollment

Enroll a user in a product collection (same as PUT). Creates a new enrollment when none exists, or reactivates a disabled enrollment.

CLI: teachable-cli v2-update-product-collection-enrollment. Policy: explicit confirmation.

Native: PATCH /v2/products/product-collections/{product_collection_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_enroll_user_in_product_collection

Enroll a user in a product collection. Creates a new enrollment when none exists, or reactivates a disabled enrollment. Gives access to all product collection contents.

CLI: teachable-cli v2-enroll-user-in-product-collection. Policy: explicit confirmation.

Native: PUT /v2/products/product-collections/{product_collection_id}/enrollments/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_list_enrollments_for_product_collection

Retrieve a list of enrollments into a specific product collection. Enrollments are returned in order of enrolled date, with the most recently enrolled appearing first.

CLI: teachable-cli v2-list-enrollments-for-product-collection. Policy: read.

Native: GET /v2/products/product-collections/{product_collection_id}/enrollments. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

sort_by

string

Optional

Sort field (enrolled_at)

sort_direction

string

Optional

Sort direction (asc, desc)

enrolled_after

string

Optional

Filter by enrolled_at after ISO8601 time. Date range between enrolled_after and enrolled_before cannot exceed 90 days.

enrolled_before

string

Optional

Filter by enrolled_at before ISO8601 time. Date range between enrolled_after and enrolled_before cannot exceed 90 days.

status

string

Optional

Filter by status (active, disabled)

user_id

integer

Optional

Filter by enrolled user

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_remove_product_from_product_collection

Remove a specific product from a product collection.

CLI: teachable-cli v2-remove-product-from-product-collection. Policy: explicit confirmation.

Native: DELETE /v2/products/product-collections/{product_collection_id}/products/{product_type}/{product_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

product_type

string

Required

Product Type (course, coaching, digital_download)

product_id

integer

Required

Product ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_list_products_in_product_collection

Retrieve a list of products in a specific product collection. Products are returned in order of creation date, with the most recently created products appearing first.

CLI: teachable-cli v2-list-products-in-product-collection. Policy: read.

Native: GET /v2/products/product-collections/{product_collection_id}/products. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

type

string

Optional

Filter by Product type (course, coaching, digital_download)

page

integer (minimum=1)

Optional

Page number

limit

integer (minimum=1, maximum=100)

Optional

Items per page (max 100)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_add_product_to_product_collection

Add products to a product collection. Products are returned in order of creation date, with the most recently created products appearing first.

CLI: teachable-cli v2-add-product-to-product-collection. Policy: explicit confirmation.

Native: POST /v2/products/product-collections/{product_collection_id}/products. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

data

array

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

data

array

Optional

Native field

data.[].id

integer

Required

Native field

data.[].type

string

Required

Native field

data.[].name

string

Required

Native field

data.[].href

string

Required

Native field

data.[].created_at

string (format=date-time)

Required

Native field

data.[].updated_at

string (format=date-time)

Required

Native field

v2_delete_product_collection

Delete a specific product collection.

CLI: teachable-cli v2-delete-product-collection. Policy: explicit confirmation.

Native: DELETE /v2/products/product-collections/{product_collection_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_product_collection

Retrieve details of a specific product collection by its ID.

CLI: teachable-cli v2-get-product-collection. Policy: read.

Native: GET /v2/products/product-collections/{product_collection_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_product_collection

Update details of a specific product collection.

CLI: teachable-cli v2-update-product-collection. Policy: explicit confirmation.

Native: PATCH /v2/products/product-collections/{product_collection_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

name

string

Optional

Native field

description

string nullable

Optional

Native field

image_url

string nullable (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

is_published

boolean

Optional

Native field

is_listed

boolean

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Optional

Native field

description

string nullable

Optional

Native field

image_url

string nullable (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

is_published

boolean

Optional

Native field

is_listed

boolean

Optional

Native field

v2_replace_product_collection

Update details of a specific product collection (full update via PUT, same behavior as PATCH).

CLI: teachable-cli v2-replace-product-collection. Policy: explicit confirmation.

Native: PUT /v2/products/product-collections/{product_collection_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

product_collection_id

integer

Required

Product Collection ID

name

string

Optional

Native field

description

string nullable

Optional

Native field

image_url

string nullable (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

is_published

boolean

Optional

Native field

is_listed

boolean

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Optional

Native field

description

string nullable

Optional

Native field

image_url

string nullable (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

is_published

boolean

Optional

Native field

is_listed

boolean

Optional

Native field

v2_list_product_collections

Retrieve a list of product collections for the school. Product collections are returned in order of creation date, with the most recently created collections appearing first.

CLI: teachable-cli v2-list-product-collections. Policy: read.

Native: GET /v2/products/product-collections. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

sort_by

string

Optional

Sort by field (created_at, updated_at)

sort_direction

string

Optional

Sort direction (asc, desc)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_product_collection

Create a product collection scoped to current school.

CLI: teachable-cli v2-create-product-collection. Policy: explicit confirmation.

Native: POST /v2/products/product-collections. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

name

string

Optional

Native field

description

string

Optional

Native field

image_url

string (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

is_published

boolean

Optional

Native field

is_listed

boolean

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Required

Native field

description

string

Optional

Native field

image_url

string (format=uri)

Optional

External URLs are referenced directly and are not downloaded or re-hosted by Teachable. Only files uploaded via the POST /v2/uploads endpoint are stored on Teachable's CDN. The caller is responsible for ensuring externally-hosted media remains available at the provided URL.

is_published

boolean

Optional

Native field

is_listed

boolean

Optional

Native field

v2_list_products

Retrieve a list of all products across all product types. The list is returned in order of creation date, with the most recently created products appearing first.

CLI: teachable-cli v2-list-products. Policy: read.

Native: GET /v2/products. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

page

integer (minimum=1)

Optional

Page number (1-based)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (max 100)

is_published

boolean

Optional

Filter by published state

author_bio_id

string

Optional

Filter by author bio ID

created_after

string

Optional

Filter products created after this time (parseable datetime string). Date range between created_after and created_before cannot exceed 90 days.

created_before

string

Optional

Filter products created before this time (parseable datetime string). Date range between created_after and created_before cannot exceed 90 days.

name

string

Optional

Filter by product name (partial match)

search

string

Optional

Search in product name and description (partial match)

sort_by

string

Optional

Sort field (created_at or updated_at)

sort_direction

string

Optional

Sort direction (asc or desc)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_get_purchase

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a single purchase by ID for the current school.

CLI: teachable-cli v2-get-purchase. Policy: read.

Native: GET /v2/purchases/{purchase_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

purchase_id

integer

Required

Purchase ID

user_id

integer

Optional

Filter by user ID to verify the purchase belongs to a specific user

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_list_purchases

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a paginated list of purchases for the current school.

CLI: teachable-cli v2-list-purchases. Policy: read.

Native: GET /v2/purchases. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

page

integer (minimum=1)

Optional

Page number (default: 1, min: 1)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (default: 25, min: 1, max: 100)

purchased_after

string

Optional

Filter purchases after this ISO8601 datetime. Date range between purchased_after and purchased_before cannot exceed 90 days.

purchased_before

string

Optional

Filter purchases before this ISO8601 datetime. Date range between purchased_after and purchased_before cannot exceed 90 days.

product_type

string

Optional

Filter by product type (course, digital_download, coaching, bundle, membership)

product_id

integer

Optional

Filter by product entity id; must be sent together with product_type

payment_method

stripe, paypal, free, coupon, external, admin, multi_school_bundle, voucher, external-api

Optional

Filter by payment method

is_active

boolean

Optional

Filter active/inactive purchases

is_recurring

boolean

Optional

Filter recurring/one-time purchases

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_get_transaction

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a single transaction by ID for the current school.

CLI: teachable-cli v2-get-transaction. Policy: read.

Native: GET /v2/transactions/{transaction_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

transaction_id

integer

Required

Transaction ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_list_transactions

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a paginated list of transactions for the current school.

CLI: teachable-cli v2-list-transactions. Policy: read.

Native: GET /v2/transactions. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

string

Optional

Filter by user ID

affiliate_id

string

Optional

Filter by affiliate ID

course_id

string

Optional

Filter by course ID

pricing_plan_id

string

Optional

Filter by pricing plan ID

purchase_id

string

Optional

Filter by purchase (sale) ID

is_fully_refunded

boolean

Optional

Filter fully refunded transactions

was_charged_back

boolean

Optional

Filter chargeback transactions

created_after

string

Optional

Filter transactions created after this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

created_before

string

Optional

Filter transactions created before this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

page

integer (minimum=1)

Optional

Page number

per_page

integer (minimum=1, maximum=100)

Optional

Items per page

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_pre_signed_upload_credentials

Generate pre-signed credentials for uploading files directly to cloud storage.

Workflow

  1. Request credentials: Call this endpoint with the resource type, id, purpose, and file extension

  2. Upload your file: Use the response fields to upload directly to the storage provider

  3. Update the resource: After upload completes, update the resource with the returned url (e.g., PATCH /v2/courses/{id} with thumbnail_url)

How to Upload

Build your upload request using the response fields:

  1. Send a request to upload_url using upload_method

  2. Set all headers from upload_headers (includes Content-Type)

  3. Include each key-value pair from upload_body in your request body

  4. Include your file using the field name from file_field_name

Note: Serialize upload_body according to the Content-Type header. If file_field_name is present, include your file as a field with that name alongside the upload_body fields. If file_field_name is null, send the file as the raw request body.

Example

# 1. Request upload credentials
curl -X POST "https://developers.teachable.com/v2/uploads" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "course", "id": 123, "purpose": "thumbnail", "extension": "jpg"}'

# Response:
# {
#   "upload_url": "https://api2.transloadit.com/assemblies",
#   "upload_method": "POST",
#   "upload_headers": {"Content-Type": "multipart/form-data"},
#   "upload_body": {"params": "...", "signature": "..."},
#   "file_field_name": "file",
#   "url": "https://cdn.teachablecdn.com/...",
#   "expires": "2024-01-01T13:00:00Z",
#   "upload_id": "abc-123"
# }

# 2. Upload the file using the credentials
curl -X POST "https://api2.transloadit.com/assemblies" \
  -H "Content-Type: multipart/form-data" \
  -F "params=..." \
  -F "signature=..." \
  -F "file=@/path/to/image.jpg"

# 3. Update the resource with the CDN URL
curl -X PATCH "https://developers.teachable.com/v2/courses/123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"thumbnail_url": "https://cdn.teachablecdn.com/..."}'

Response Fields

Field

Description

upload_url

The endpoint URL to send your file to

upload_method

HTTP method to use (e.g., POST, PUT)

upload_headers

Headers to include in your upload request (e.g., Content-Type)

upload_body

Key-value pairs to include in your request body (serialize per Content-Type), or null if not needed

file_field_name

The field name to use for your file (e.g., file), or null if the file is sent as the raw request body

url

The CDN URL where your file will be available after upload. Use this to update the resource.

expires

When the credentials expire (ISO 8601). Upload before this time.

upload_id

Unique identifier for this upload request

Supported Resources

Type

Purpose

Description

course

thumbnail

Course cover image

product_collection

thumbnail

Learning path cover image

digital_download

thumbnail

Digital product cover image

digital_download

attachment

Downloadable file for customers

lecture

attachment

Lecture file (PDF, video, etc.)

membership

thumbnail

Membership cover image

coaching

thumbnail

Coaching product cover image

Constraints

  • Maximum file size: 20 GB

  • Extension: 1-10 alphanumeric characters (e.g., jpg, pdf, mp4)

  • Credentials expire: 1 hour after creation

CLI: teachable-cli v2-create-pre-signed-upload-credentials. Policy: explicit confirmation.

Native: POST /v2/uploads. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

oneOf

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

output_file

string (minLength=1)

Required

Absolute NEW owner-private receipt file; exclusive0600 creation, no overwrite. Upload/public-token URLs never enter ordinary output.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

variant 1

object

Choose one

Native oneOf

variant1.type

course

Required

The resource type to upload for.

variant1.id

integer (minimum=1)

Required

The ID of the resource.

variant1.purpose

thumbnail

Required

The purpose of the upload (e.g., thumbnail, attachment).

variant1.extension

string (pattern=^[a-zA-Z0-9]{1,10}$)

Required

File extension without the dot (e.g., 'jpg', 'pdf', 'mp4'). Case-insensitive, 1-10 alphanumeric characters.

variant 2

object

Choose one

Native oneOf

variant2.type

product_collection

Required

The resource type to upload for.

variant2.id

integer (minimum=1)

Required

The ID of the resource.

variant2.purpose

thumbnail

Required

The purpose of the upload (e.g., thumbnail, attachment).

variant2.extension

string (pattern=^[a-zA-Z0-9]{1,10}$)

Required

File extension without the dot (e.g., 'jpg', 'pdf', 'mp4'). Case-insensitive, 1-10 alphanumeric characters.

variant 3

object

Choose one

Native oneOf

variant3.type

digital_download

Required

The resource type to upload for.

variant3.id

integer (minimum=1)

Required

The ID of the resource.

variant3.purpose

thumbnail, attachment

Required

The purpose of the upload (e.g., thumbnail, attachment).

variant3.extension

string (pattern=^[a-zA-Z0-9]{1,10}$)

Required

File extension without the dot (e.g., 'jpg', 'pdf', 'mp4'). Case-insensitive, 1-10 alphanumeric characters.

variant 4

object

Choose one

Native oneOf

variant4.type

lecture

Required

The resource type to upload for.

variant4.id

integer (minimum=1)

Required

The ID of the resource.

variant4.purpose

attachment

Required

The purpose of the upload (e.g., thumbnail, attachment).

variant4.extension

string (pattern=^[a-zA-Z0-9]{1,10}$)

Required

File extension without the dot (e.g., 'jpg', 'pdf', 'mp4'). Case-insensitive, 1-10 alphanumeric characters.

variant 5

object

Choose one

Native oneOf

variant5.type

membership

Required

The resource type to upload for.

variant5.id

integer (minimum=1)

Required

The ID of the resource.

variant5.purpose

thumbnail

Required

The purpose of the upload (e.g., thumbnail, attachment).

variant5.extension

string (pattern=^[a-zA-Z0-9]{1,10}$)

Required

File extension without the dot (e.g., 'jpg', 'pdf', 'mp4'). Case-insensitive, 1-10 alphanumeric characters.

variant 6

object

Choose one

Native oneOf

variant6.type

coaching

Required

The resource type to upload for.

variant6.id

integer (minimum=1)

Required

The ID of the resource.

variant6.purpose

thumbnail

Required

The purpose of the upload (e.g., thumbnail, attachment).

variant6.extension

string (pattern=^[a-zA-Z0-9]{1,10}$)

Required

File extension without the dot (e.g., 'jpg', 'pdf', 'mp4'). Case-insensitive, 1-10 alphanumeric characters.

v2_list_purchases_for_user

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a paginated list of purchases for a specific user.

CLI: teachable-cli v2-list-purchases-for-user. Policy: read.

Native: GET /v2/users/{user_id}/purchases. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer

Required

User ID

page

integer (minimum=1)

Optional

Page number (default: 1, min: 1)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (default: 25, min: 1, max: 100)

purchased_after

string

Optional

Filter purchases after this ISO8601 datetime. Date range between purchased_after and purchased_before cannot exceed 90 days.

purchased_before

string

Optional

Filter purchases before this ISO8601 datetime. Date range between purchased_after and purchased_before cannot exceed 90 days.

product_type

string

Optional

Filter by product type (course, digital_download, coaching, bundle, membership)

product_id

integer

Optional

Filter by product entity id; must be sent together with product_type

is_active

boolean

Optional

Filter active/inactive purchases

is_recurring

boolean

Optional

Filter recurring/one-time purchases

payment_method

stripe, paypal, free, coupon, external, admin, multi_school_bundle, voucher, external-api

Optional

Filter by payment method

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_list_quiz_responses_for_user

🚧 Beta: This endpoint may not be available yet and may change without notice. Contact support to request access.

Retrieve a paginated history of quiz responses for a specific user.

CLI: teachable-cli v2-list-quiz-responses-for-user. Policy: read.

Native: GET /v2/users/{user_id}/quiz-responses. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer

Required

User ID. Malformed values return 400; missing users return 404.

lecture_id

integer

Optional

Lecture ID filter; returns 404 when the lecture does not exist, 400 when the value is not an integer

course_id

integer

Optional

Course ID filter; returns 404 when the course does not exist, 400 when the value is not an integer

sort_by

string

Optional

Sort field (submitted_at, updated_at, created_at)

sort_direction

string

Optional

Sort direction (asc, desc)

include_answers

string

Optional

When true, include the submitted answers object on each quiz response. Omit or set to false to exclude answers (default).

submitted_after

string

Optional

ISO8601 datetime; invalid values return 400. Date range between submitted_after and submitted_before cannot exceed 90 days.

submitted_before

string

Optional

ISO8601 datetime; invalid values return 400. Date range between submitted_after and submitted_before cannot exceed 90 days.

page

integer (minimum=1)

Optional

Page number (default: 1, min: 1)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (default: 20, min: 1, max: 100)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_revoke_user_session

Revoke a single user session.

CLI: teachable-cli v2-revoke-user-session. Policy: explicit confirmation.

Native: DELETE /v2/users/{user_id}/sessions/{session_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer

Required

User ID

session_id

string

Required

Session ID (UUID)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_revoke_user_sessions

Revoke all active sessions for a user.

CLI: teachable-cli v2-revoke-user-sessions. Policy: explicit confirmation.

Native: DELETE /v2/users/{user_id}/sessions. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_list_user_sessions

Retrieve a paginated list of active sessions for a specific user.

CLI: teachable-cli v2-list-user-sessions. Policy: read.

Native: GET /v2/users/{user_id}/sessions. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer

Required

User ID

last_seen_after

string

Optional

ISO8601 datetime; sessions last seen at or after this time. Date range between last_seen_after and last_seen_before cannot exceed 90 days.

last_seen_before

string

Optional

ISO8601 datetime; sessions last seen at or before this time. Date range between last_seen_after and last_seen_before cannot exceed 90 days.

page

integer (minimum=1)

Optional

Page number (default: 1, min: 1)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (default: 25, min: 1, max: 100)

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_delete_user

Delete a single user for the current school.

CLI: teachable-cli v2-delete-user. Policy: explicit confirmation.

Native: DELETE /v2/users/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

v2_get_user

Retrieve a single user by id for the current school.

CLI: teachable-cli v2-get-user. Policy: read.

Native: GET /v2/users/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer

Required

User ID

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_update_user

Update a single user for the current school.

CLI: teachable-cli v2-update-user. Policy: explicit confirmation.

Native: PATCH /v2/users/{user_id}. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

user_id

integer

Required

User ID

name

string nullable

Optional

Native field

email

string nullable

Optional

Native field

role

student, owner, author, affiliate

Optional

Allowed values: student, owner, author, affiliate. Omit to preserve the current role.

allow_marketing_emails

boolean

Optional

Optional. When omitted on update, the existing preference is preserved.

author_revenue_share

number nullable

Optional

Native field

affiliate_revenue_share

number nullable

Optional

Native field

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string nullable

Optional

Native field

email

string nullable

Optional

Native field

password

string nullable

Optional

Native field

role

student, owner, author, affiliate

Optional

Allowed values: student, owner, author, affiliate. Omit to preserve the current role.

allow_marketing_emails

boolean

Optional

Optional. When omitted on update, the existing preference is preserved.

author_revenue_share

number nullable

Optional

Native field

affiliate_revenue_share

number nullable

Optional

Native field

v2_list_users

Retrieve a paginated list of users for the current school.

CLI: teachable-cli v2-list-users. Policy: read.

Native: GET /v2/users. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

page

integer (minimum=1)

Optional

Page number (default: 1, min: 1)

per_page

integer (minimum=1, maximum=100)

Optional

Items per page (default: 25, min: 1, max: 100)

sort_by

string

Optional

Sort key (id, name, email, created_at, updated_at, last_sign_in_at)

sort_direction

string

Optional

Sort direction (asc, desc)

name

string

Optional

Filter by user name

email

string

Optional

Filter by user email

role

string

Optional

Filter by user role. Allowed values: owner, author, affiliate, student, custom. Returns empty results for unrecognized values.

created_before

string

Optional

Filter users created before this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

created_after

string

Optional

Filter users created after this ISO8601 datetime. Date range between created_after and created_before cannot exceed 90 days.

user_id

string

Optional

Filter by user id

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

v2_create_user

Create a single user for the current school.

CLI: teachable-cli v2-create-user. Policy: explicit confirmation.

Native: POST /v2/users. Version: explicit beta v2. Current source.

Argument

Type or constraint

Requirement

Meaning

name

string

Optional

Native field

email

string

Optional

Native field

role

student, owner, author, affiliate

Optional

Allowed values: student, owner, author, affiliate

allow_marketing_emails

boolean

Optional

Required when role is 'student'. Optional for other roles.

notes

string nullable

Optional

Native field

author_revenue_share

number nullable

Optional

Required when role is 'author'. Decimal between 0 and 1 (e.g. 0.3 = 30%). Must not be provided for other roles.

affiliate_revenue_share

number nullable

Optional

Required when role is 'affiliate'. Decimal between 0 and 1. Must not be provided for other roles.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

payload

object

Optional

Complete current native JSON body; cannot mix with native body flags or payload_file.

payload_file

string (minLength=1)

Optional

Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

Native JSON fields below must satisfy their required fields and chosen variants. Use flat body flags, payload OR payload_file. Passwords require owner-private payload_file. Inspect the complete machine schema before effects.

Native JSON field

Type or constraint

Requirement

Meaning

name

string

Required

Native field

email

string

Required

Native field

password

string nullable

Optional

Native field

role

student, owner, author, affiliate

Required

Allowed values: student, owner, author, affiliate

allow_marketing_emails

boolean

Optional

Required when role is 'student'. Optional for other roles.

notes

string nullable

Optional

Native field

author_revenue_share

number nullable

Optional

Required when role is 'author'. Decimal between 0 and 1 (e.g. 0.3 = 30%). Must not be provided for other roles.

affiliate_revenue_share

number nullable

Optional

Required when role is 'affiliate'. Decimal between 0 and 1. Must not be provided for other roles.

list_accounts

Local labels/default/version/auth source availability only. No credential values, paths, provider identity or network.

CLI: teachable-cli list-accounts. Policy: read.

Argument

Type or constraint

Requirement

Meaning

get_operation_schema

Local reviewed native method/path/query/body/scopes/rate limit and pinned schema provenance. No provider access or authority proof.

CLI: teachable-cli get-operation-schema. Policy: read.

Argument

Type or constraint

Requirement

Meaning

operation

list_enrollments, mark_lecture_complete, list_quiz_responses, get_quiz, list_quizzes, get_video, get_lecture, get_course_progress, get_course, list_courses, create_enrollment, get_pricing_plan, list_pricing_plans, list_transactions, unenroll_user, get_user, update_user, list_users, create_user, get_webhook_events, list_webhooks, v2_get_school_customizations, v2_delete_pricing_plan, v2_get_pricing_plan, v2_update_pricing_plan, v2_list_pricing_plans_for_product, v2_create_pricing_plan_for_product, v2_delete_coupon, v2_get_coupon, v2_update_coupon, v2_list_coupons, v2_create_coupon, v2_list_comments_for_course, v2_get_compliance_settings_for_course, v2_update_compliance_settings_for_course, v2_unenroll_user_from_course, v2_get_user_s_enrollments_for_course, v2_update_course_enrollment, v2_enroll_user_in_course, v2_list_enrollments_for_course, v2_delete_content_attachment_from_lesson_lecture, v2_get_content_attachment_for_lesson_lecture, v2_update_content_attachment_for_lesson_lecture, v2_list_content_attachments_for_lesson_lecture, v2_create_content_attachment_for_lesson_lecture, v2_reorder_content_attachments_in_lesson_lecture, v2_delete_lecture_comment, v2_update_comment_moderation_status, v2_list_comments_for_lecture, v2_create_comment_on_lecture, v2_list_responses_for_lecture_quiz, v2_delete_lecture_quiz, v2_get_lecture_quiz, v2_list_quizzes_for_lecture, v2_mark_lecture_as_not_completed_for_user, v2_get_lecture_completion_status_for_user, v2_mark_lecture_as_completed_for_user, v2_get_video_for_lecture, v2_delete_lecture, v2_get_lecture, v2_update_lecture, v2_list_lectures_for_course, v2_create_lecture_in_section, v2_reorder_lectures_in_section, v2_get_course_section, v2_update_course_section, v2_replace_course_section, v2_list_sections_for_course, v2_create_section_in_course, v2_reorder_sections_in_course, v2_get_course_progress_for_user, v2_get_course, v2_update_course, v2_list_courses, v2_create_course, v2_delete_attachment_from_digital_download, v2_get_attachment_for_digital_download, v2_list_attachments_for_digital_download, v2_create_attachment_for_digital_download, v2_unenroll_user_from_digital_download, v2_get_enrollment_for_digital_download, v2_enroll_user_in_digital_download, v2_list_enrollments_for_digital_download, v2_delete_digital_download, v2_get_digital_download, v2_update_digital_download, v2_list_digital_downloads, v2_create_digital_download, v2_unenroll_user_from_product_collection, v2_get_enrollment_for_product_collection, v2_update_product_collection_enrollment, v2_enroll_user_in_product_collection, v2_list_enrollments_for_product_collection, v2_remove_product_from_product_collection, v2_list_products_in_product_collection, v2_add_product_to_product_collection, v2_delete_product_collection, v2_get_product_collection, v2_update_product_collection, v2_replace_product_collection, v2_list_product_collections, v2_create_product_collection, v2_list_products, v2_get_purchase, v2_list_purchases, v2_get_transaction, v2_list_transactions, v2_create_pre_signed_upload_credentials, v2_list_purchases_for_user, v2_list_quiz_responses_for_user, v2_revoke_user_session, v2_revoke_user_sessions, v2_list_user_sessions, v2_delete_user, v2_get_user, v2_update_user, v2_list_users, v2_create_user

Required

Native field

preview_school_batch

Validate every exact request and hash order/profile label/schema locally. No native request, credential loading, ownership check or provider preview.

CLI: teachable-cli preview-school-batch. Policy: read.

Argument

Type or constraint

Requirement

Meaning

tasks

array (minItems=1, maxItems=20)

Required

One to twenty exact ordered native effects. No signed receipts or mutable payload files. Cannot override account/confirm/output settings.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

submit_school_batch

Confirmed ordered effects; all validated/hash checked before first request. Stop on first failure with known and unattempted receipts; no retry, rollback or implicit continuation.

CLI: teachable-cli submit-school-batch. Policy: explicit confirmation.

Argument

Type or constraint

Requirement

Meaning

tasks

array (minItems=1, maxItems=20)

Required

One to twenty exact ordered native effects. No signed receipts or mutable payload files. Cannot override account/confirm/output settings.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

review_sha256

string (pattern=^[a-f0-9]{64}$)

Required

Native field

export_resources

Confirmed reviewed native page/per or page/per_page export into a new exclusive0600 file. Page/item/5MiB budgets and explicit continuation; no signed links followed or binary download. Not an atomic backup.

CLI: teachable-cli export-resources. Policy: explicit confirmation.

Argument

Type or constraint

Requirement

Meaning

operation

list_courses, list_pricing_plans, list_transactions, list_users, get_webhook_events, v2_list_pricing_plans_for_product, v2_list_coupons, v2_list_comments_for_course, v2_get_user_s_enrollments_for_course, v2_list_enrollments_for_course, v2_list_content_attachments_for_lesson_lecture, v2_list_comments_for_lecture, v2_list_quizzes_for_lecture, v2_list_lectures_for_course, v2_list_sections_for_course, v2_list_courses, v2_list_attachments_for_digital_download, v2_list_enrollments_for_digital_download, v2_list_digital_downloads, v2_list_enrollments_for_product_collection, v2_list_product_collections, v2_list_products, v2_list_purchases, v2_list_transactions, v2_list_purchases_for_user, v2_list_quiz_responses_for_user, v2_list_user_sessions, v2_list_users

Required

Native field

arguments

object

Optional

Current native list arguments; cannot override profile/policy/output.

account

string

Optional

Exact private school profile label; not a provider identity or authorization proof.

confirm

boolean

Optional

Set true only when the user asked for exactly this action.

start_offset

integer (minimum=0, maximum=99)

Optional

Native field

max_pages

integer (minimum=1, maximum=100)

Optional

Native field

max_items

integer (minimum=1, maximum=10000)

Optional

Native field

output_file

string (minLength=1)

Required

Native field

7. Writing safely

Every provider or private-output effect needs approval. In a terminal that is --confirm, which --agent and --yes never add. Over MCP a person approves each one where the client can ask: Claude Code (2.1.246 and later) shows its own prompt for the call, and a client that can show forms asks with an approval form whose one box starts unticked. Each approval is signed, bound to that exact call and works once. A client that can do neither falls back to confirm: true, which a model may pass only when the user asked for that exact action. TEACHABLE_CONFIRM=model makes confirm: true enough everywhere, for a headless agent you trust. Read-only hides and directly refuses effects, and TEACHABLE_ALLOW_DESTRUCTIVE=0 refuses them even with approval. Local confirmation does not supply provider authorization, customer permission, marketing consent or financial entitlement. TEACHABLE_AUDIT_LOG records who approved each call.

Read the intended records and inspect the operation schema before preparing effects. Course publishing, enrollment access, user deletion, session revocation and pricing changes can affect people immediately. Only carry out the action the user asked for. Teachable determines whether a key, role, scope and school plan allow it.

No operation retries automatically. A timeout or malformed receipt can leave an unknown outcome; inspect native state before deliberately repeating. Local pacing defaults to one second and a 30-second request timeout. Other processes still share provider quotas.

8. API versions and native workflows

Stable v1 remains under /v1; opt-in v2 is request-access beta under /v2. Set TEACHABLE_ENABLE_V2=1 to expose v2_ tasks and configure an explicit api_version:"2" profile. Merely enabling discovery does not grant access or change a version 1 profile.

V1 enrollment creation is POST /v1/enroll with flat user_id and course_id; it is not the legacy /enrollments wrapper. User creation uses flat email, name, password and src, with no guessed role field. Pricing lists use /v1/pricing_plans. Course enrollment listing has native enrolled_in_after/enrolled_in_before/sort_direction filters, without invented page/per arguments.

teachable-cli get-operation-schema --operation create_enrollment --agent
teachable-cli create-enrollment --course-id 7 --user-id 9 --account intended-school --confirm --agent
teachable-cli v2-list-lectures-for-course --course-id 7 --account intended-beta-school --agent

V2 route IDs retain the reviewed schema's types; some are strings. The dedicated CLI parses them accordingly. For user creation, explicit student marketing consent is required, and author/affiliate shares are native decimal fractions between 0 and 1. User passwords can only be read from a private payload file; there is no password flag or inline-payload password route.

V2 coupon deletion archives a multiple-use coupon rather than deleting its historical record. Coupon creation has mutually exclusive scope shapes, and new-payment schools have additional expiry, inventory and discount requirements. Some coupon updates on those schools only propagate name. Review the full native description and coupon reference; this package cannot infer the school's payments entitlement.

The v2_create_pre_signed_upload_credentials workflow here requests signed credentials into a new private file. Transfer bytes according to the native storage receipt separately, then use a deliberate content attachment/update step. No byte uploader or automatic course publishing is advertised.

9. Several accounts and reviewed batches

TEACHABLE_ACCOUNTS is a private array of unique named school profiles: name, api_version (1 default) and one api_key or credentials_file source. Named profiles never inherit global keys. TEACHABLE_DEFAULT_ACCOUNT and --account select exact labels. Local discovery exposes source availability and version, not keys, paths, provider identity or ownership.

Preview validates 1–20 exact ordered native effects locally. It never loads credentials or contacts a school. Mutable payload files and private output operations are excluded, and nested account/confirm/output overrides are refused.

teachable-cli preview-school-batch --tasks '{"tool":"create_enrollment","arguments":{"course_id":7,"user_id":9}}' --account intended-school --agent
teachable-cli submit-school-batch --tasks '{"tool":"create_enrollment","arguments":{"course_id":7,"user_id":9}}' --review-sha256 REVIEWED_64_CHARACTER_HASH --account intended-school --confirm --agent

The repeatable JSON task flag forms the tasks array. Use the actual hash from your preview. It binds prepared request content, order, profile label, version and pinned schema. It does not bind credential file contents or provider state, expire or guarantee single-use execution. Re-review after state or credential changes.

Execution checks all requests and the hash before fetching. It stops at the first failure with known receipts, the failed index and unattempted indices, preserving native error status. There is no transaction, rollback or implicit continuation.

10. Pagination and private exports

Native v1 pages use page/per and v2 pages use page/per_page, starting at 1. Response counters differ: v1 meta.number_of_pages and resource arrays, v2 meta.total_pages and data arrays. Only the 28 reviewed contracts with the complete pagination shape are eligible for export; course-enrollment v1 listing is excluded.

teachable-cli export-resources --operation list_courses --arguments '{"page":1,"per":100}' --max-pages 10 --max-items 1000 --output-file /absolute/private/courses.json --account intended-school --confirm --agent

Defaults are ten pages and 1,000 items; maxima are 100 pages, 10,000 items and 5 MiB. Native page size is capped locally at 100. Partial pages return a native page plus start_offset, so continuation does not silently discard remaining rows. Wrong counters, empty intermediate pages and changed offsets refuse completion claims.

V1 users document search_after for more than 10,000 records. The helper does not invent a cursor; it caps that window and preserves explicitly supplied arguments for deliberate continuation. A complete result applies only to the requested filters and provider response window.

Output uses a NEW absolute path, exclusive creation and POSIX 0600 permissions. Existing files and target symlinks are never overwritten. Failures remove the partial new file. Customer names/emails remain private metadata even after credential/signed-URL redaction. Exports are not atomic snapshots, binary downloads or guaranteed backups while data changes.

11. How it works

Slipway 0.1.17 turns one list of tools into the stdio MCP server and the CLI, and both send every call through the same path, so validation, the guard, approval and redaction cannot differ. Tool schemas derive from reviewed native parameters/body variants; Ajv validates arguments and bodies before fetching, compiling each schema on its first use. Method/path/version allowlists prevent arbitrary-host key forwarding and silent API fallback. Path-level and operation-level parameters both matter.

Five local helpers provide profile discovery, contract inspection, review/submit batches and bounded metadata exports. No community runtime or private legacy Git history is copied. The provenance file pins the transformed schema and the two original source snapshot hashes.

npm ci
npm run typecheck
npm run build
npm test
npm run check:counts
npm run check:discovery
npm run sync:api -- --check
npm run build:mcpb

CI covers Node 22/24 on macOS, Windows and Linux plus desktop packaging. These checks establish local behavior and artifacts. School account outcomes and actual GUI installation remain separately tracked; the Codex task measurement is in section 5. The sync check verifies the pinned snapshot; it never silently regenerates an unreviewed upstream contract.

12. Your data

This is local software with no hosted service or telemetry. Admin keys are sent as apiKey only to developers.teachable.com. Redirects are refused. Credentials come from private runtime settings or bounded owner-private files. Named profiles never inherit another source.

Known keys/passwords and credential-like or signed-URL fields are redacted from ordinary output and errors. Raw upload credentials are intentionally saved only to the requested new private receipt file. The helper never follows those storage URLs. Emails, names, notes, transactions and other ordinary school fields are not anonymized; keep them private.

Provider text and URLs are untrusted data, not instructions. Best-effort audit logs contain static guard decisions, without payloads or credentials. They are not account-action ledgers. Uninstalling does not revoke keys or reverse changes; revoke keys in Teachable and restart runtimes.

13. Official and community comparison

Teachable's official remote MCP already supports documentation search and authenticated account requests. Credential-free discovery found seven v1/five v2 meta-tools, including generic execute-request. These are interface counts, not native API coverage. Official Admin apiKey and separately obtained end-user OAuth bearer are distinct; the remote server does not run or refresh the end-user OAuth flow.

Requirement

This companion

Existing alternatives

Admin API tasks

21 stable plus 97 explicit beta native contracts

Official generic endpoint execution and docs search

End-user OAuth

Not implemented

Official MCP accepts a separately obtained bearer

Terminal

Dedicated schemas/help over shared handlers

Generic MCP terminal clients also exist

School selection

Exact isolated profile label and API version

Credential/client setup remains the user's responsibility

Approval

A person approves each effect where the client can ask; direct read-only refusal

Provider permissions and client approvals remain separate

Repeated effects

Exact local batch review, stop-on-failure receipts

No transaction/state-lock claim

Export

Bounded private native-page export and offset resume

No atomic backup or binary download claim

Beta

Hidden default, explicitly pinned version, no fallback

Provider request-access and new scoped key may be required

Efficiency

One matched Codex task measured, 2.0.1 against 3.0.0; none against alternatives

Tool counts are not token savings

The pinned ahmedrowaihi/teachable-mcp-server source at 5d722b2987a8b745d50e2d49f58589ca51a10002 declares 21 v1 operations and one stdio server binary, without task CLI dispatch in the reviewed source. That is not proof no CLI exists elsewhere. Generic wong2/mcp-cli is a terminal alternative; its reviewed source already supports remote interactive OAuth. See COMPARISON.md for evidence and limits.

14. Versions and migration

Component

Version or evidence

Package and desktop

3.0.1

Node runtime

>=22

Framework

Slipway 0.1.17

Native contracts

Stable v1 and request-access beta v2, checked 2026-10-04

Native operations

21 v1 / 97 v2

Shared helpers

5

Legacy compatibility

11 supported names retained; 3 unsupported v1 routes retired

Default discovery

26 tasks / 19 reads / 7 confirmed effects

Explicit beta discovery

123 tasks / 64 reads / 59 confirmed effects

Provider, GUI and task-token outcomes

Separate acceptance, never inferred from fixtures

3.0.0 moves both surfaces onto Slipway. Tool names, arguments, results and exit codes stay the same, and --version still prints the bare version. Over MCP, a person now approves each effect where the client can ask; TEACHABLE_CONFIRM=model keeps approval by confirm: true alone. Errors arrive as one JSON object instead of JSON inside a string, a command hidden by read-only mode or the beta switch says why instead of being unknown, and install <client> sets up a client. The server answers a client in 159 ms where 2.0.1 took 237 (median of 21 runs on one Mac).

Upgrade scripts by inspecting schema/--help. The old create_enrollment path/wrapper, create_user wrapper, course-scoped pricing list and guessed pagination are corrected. list_lectures becomes an explicitly enabled beta lecture-list task; there is no silent v1 fallback. create_webhook/delete_webhook are absent from reviewed current Admin contracts and are retired.

All effects now require confirmation. Passwords need private payload_file input; signed upload credentials need a new private output_file. Named profiles pin versions and never inherit global keys. Preserve the older private history separately. CHANGELOG.md records the breaking refresh.

15. Environment variables and removal

Setting

Meaning

TEACHABLE_API_KEY

Private existing Admin key, one source

TEACHABLE_CREDENTIALS_FILE

Absolute owner-private regular JSON with api_key, at most 64 KiB

TEACHABLE_ACCOUNTS

Private isolated named-profile array

TEACHABLE_DEFAULT_ACCOUNT

Exact default label

TEACHABLE_API_VERSION

Single-profile version 1 by default, or an explicit 2

TEACHABLE_ENABLE_V2

1/true exposes beta tasks; provider access still required

TEACHABLE_TOOLSETS

beta or all turns on the beta tasks, the same as TEACHABLE_ENABLE_V2

TEACHABLE_READ_ONLY

1/true hides and directly refuses effects

TEACHABLE_ALLOW_DESTRUCTIVE

0/false refuses even confirmed effects

TEACHABLE_CONFIRM

human by default: a person approves effects over MCP where the client can ask. model accepts confirm: true alone

TEACHABLE_AUDIT_LOG

Optional best-effort log of guard decisions and who approved each call

TEACHABLE_REQUEST_TIMEOUT_MS

30000 by default; 100 to 300000

TEACHABLE_MIN_REQUEST_INTERVAL_MS

1000 by default; 0 to 10000

TEACHABLE_TOOL_TIMEOUT_MS

Optional deadline for any one tool call

TEACHABLE_SURFACE

full by default; search serves three tools that find, describe and run the others

No arbitrary base-URL setting is supported. Named profiles ignore single-profile credential/version globals. To update, install @latest, inspect the changelog and reconnect. Check that package, desktop manifest and release tag versions match.

Remove the MCP entry through the client settings or codex mcp remove teachable, and uninstall the global package with npm uninstall -g @thenavidm/teachable-mcp-cli. Remove a desktop extension separately. Neither removal revokes provider keys or reverses account effects. Keep any private files under your own retention policy.

16. Risks

School keys may authorize changes that affect access, publishing and revenue. Local confirmation does not establish entitlement, customer consent or intended school identity. Beta contracts may change without notice, and a package update requires reviewed native changes.

Requests/body files are capped locally at 1 MiB and responses/exports/private receipts at 5 MiB. Local pacing and timeout are process controls rather than global provider quotas. Ambiguous failures are not retried automatically. A native receipt is not independent delivery, publication, settlement or enrollment-access proof.

Production dependencies (Slipway, the MCP SDK, Zod, Ajv) are separate from the build-only desktop packer. The reviewed packer currently depends on node-forge 1.4.0 with an unpatched signature-verification advisory; it is excluded from npm runtime and bundled production dependencies. Packaging here does not sign or verify third-party bundles. See security advisory. Do not claim a clean full development dependency audit.

17. Troubleshooting

Symptom

Check

Missing config

Select exactly one private key source in the launching runtime

API 401/403

Check revocation, key permissions, school eligibility and selected version

Beta hidden

Enable beta explicitly and obtain provider request access

Version mismatch

Choose an exact matching profile; no fallback is attempted

429

Respect provider quotas; inspect effects before deliberate retry

Unknown flag

Inspect schema/help; guessed legacy wrappers are refused

Password refused

Use an owner-private payload_file, outside repositories

Existing output

Select a new private path; the helper never overwrites

Invalid pagination

Inspect native filters/counters; no completeness claim is made

Malformed receipt/timeout

Inspect native state before repeating an effect

GUI cannot find npx

Check Node/PATH or use absolute executable and installed entry point

Claude Code asks before every change

Expected: each effect needs a person's approval

claude -p will not run a change

Headless Claude Code refuses tools that need a person; give that agent TEACHABLE_CONFIRM=model

No approval form appears

The client cannot show forms, so the model's confirm: true counts, and only for an action the user asked for

Report sanitized reproductions through issues. Use private security reporting for sensitive cases. Never attach keys, user-password files, signed receipts or school exports.

18. FAQ

A local stdio program for reviewed Teachable Admin API tasks. Stable v1 exposes 26 tasks: 21 native operations and 5 local helpers. Explicit beta opt-in exposes 123 tasks in all, adding 97 v2 Admin operations. The CLI calls the same handlers.

The same discovered tools as terminal commands, with schema-derived help, JSON output and stable exit codes. For example, list_courses is teachable-cli list-courses. No separate implementation or undocumented legacy request wrappers.

Yes. Its hosted MCP can search documentation and execute authenticated API operations. The credential-free discovery review found seven v1 and five v2 meta-tools, including generic execute-request. Those counts do not describe account-action coverage. See the official MCP guide.

Use the dedicated shared CLI, exact private school/version selection, local ordered batch reviews and bounded private exports. The official remote server is a valid alternative for hosted access and documentation search. A CLI or larger discovery count alone does not establish superiority.

Stable v1 is the default. Beta v2 requires provider request-access approval, appropriate scoped credentials, TEACHABLE_ENABLE_V2=1 (or TEACHABLE_TOOLSETS=beta) and an explicit version 2 profile. v2_ commands never silently fall back to v1, or vice versa.

The school owner uses Settings > API > Create API Key, chooses a name and appropriate permissions, then creates the key. API access remains subject to provider plans and eligibility. Revoke through the same API settings. Never put the key in a repo or chat.

No. teachable-cli login prints setup instructions only. This companion accepts existing Admin API keys and does not implement end-user OAuth consent, token exchange or refresh. The official MCP supports separately obtained OAuth tokens for current_user calls.

Local stdio clients including Codex, Claude Code, Claude Desktop, Cursor, VS Code/Copilot, Windsurf, Zed and Gemini CLI can launch the server. INSTALL.md also covers OpenCode, Copilot CLI, OpenClaw, Antigravity and Hermes. Node 22+ is required; macOS, Windows and Linux are declared. Actual GUI installation is a separate check.

Download teachable-3.0.0.mcpb from GitHub Releases and use a supported Claude Desktop Extensions screen. Choose one private key source. Stable version 1 is the default; enable beta and version 2 only after obtaining access. Bundled production dependencies do not include a Node runtime.

TEACHABLE_ACCOUNTS holds unique named profiles with a pinned api_version and one api_key or credentials_file source. --account selects an exact label. Profiles do not inherit global credentials. The label itself does not establish school identity or resource ownership.

TEACHABLE_READ_ONLY=1 hides and directly refuses all effects: 19 reads in stable discovery, or 64 reads when beta is enabled. It is a local policy, not a reduction of the provider key permissions, and does not control other clients.

All provider mutations and private output operations need approval: --confirm in CLI, and over MCP a person's approval where the client can ask, or confirm: true where it cannot. Stable mode has 7 effects; beta-enabled mode has 59. This includes enrollment/user changes, batch execution, private export and upload-credential requests. --yes and --agent never approve an effect.

Beta student creation requires an explicit allow_marketing_emails boolean. False remains false; local confirm is unrelated to marketing consent. User role and revenue-share conditions must satisfy the native contract, and provider entitlements remain separate.

Only through an absolute owner-private payload_file containing the native JSON body. There is no password command flag, and inline payload passwords are refused. Known passwords and API keys are redacted from ordinary output. Keep the payload outside repositories and restrict Windows ACLs separately.

No. Preview validates up to 20 ordered native requests and hashes order, selected profile label, API version and pinned schema. Submit requires the identical review hash and stops at the first failure. No state lock, credential binding, rollback, expiry or single-use guarantee is claimed.

No. Only 28 reviewed list contracts support this helper. It saves bounded filtered native metadata with explicit page/item/byte budgets and page/offset continuation. Other customer fields remain private data. The result is not an atomic school backup or binary download.

The reviewed beta upload operation creates signed upload credentials in a new private file. It does not transfer bytes or attach/publish content. Native POST/PUT storage details remain in the private receipt, and the subsequent upload/attachment process needs separate validation.

Those old handlers used routes absent from current reviewed Admin contracts, so they are retired. Stable v1 supports listing webhooks and their events. Configure webhook creation/removal through supported provider administration; do not guess API endpoints.

The software is free under the preserved AGPL-3.0 license. Provider fees and plans still apply. Measured against 2.0.1, the same Codex task costs about the same over MCP and 11% fewer input tokens over the CLI, and Claude Code loads the tools for 28 fewer tokens; section 5 has every number and the method. Schema counts and character estimates are not savings; help, outputs and retries also use context.

3.0.0 moves both surfaces onto Slipway: over MCP a person approves effects where the client can ask, errors are one JSON object, hidden commands say why, and the server answers sooner. Tool names, arguments and exit codes are unchanged. In 2.0.0, the old private 14-handler MCP gained shared CLI/MCP surfaces, current native validation, private profiles, mandatory effect approval, reviewed batches, exports and a desktop bundle. Eleven supported legacy names remain with corrected arguments. list_lectures has an explicit beta replacement; unsupported webhook creation/deletion are retired. Private legacy Git history is excluded.

Questions

Use issues with sanitized reproduction steps. Private security reports belong in the advisory form.

About the author

Navid Moazzez is a leading AI business strategist, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life. He creates useful free tools, MCP servers and CLIs that creators and founders can use in their own workflows.

Links

Dependencies

Dependency

What it does

License

Slipway

One tool list as the MCP server and the CLI

Apache-2.0

MCP TypeScript SDK

The MCP protocol, through Slipway

Apache-2.0

Zod

Slipway's own schemas

MIT

Ajv and ajv-formats

Validates arguments and native bodies

MIT

TypeScript, Vitest, the MCP SDK client used by the discovery check, and the desktop packer are build and test tools. Production dependency licenses ship with the desktop bundle. See THIRD_PARTY_NOTICES.md and SECURITY.md.

License

AGPL-3.0, preserved from the owned legacy source. Teachable is a separate provider; this community companion is not the official Teachable MCP.

© 2026 Navid Media. Made with ❤️ by Navid Moazzez.

Available Tools

26 tools
create_enrollmentEnroll UserC
Destructive

Enroll a user in a course.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
confirmNoSet true only when the user asked for exactly this action.
payloadNoComplete current native JSON body; cannot mix with native body flags or payload_file.
user_idNoThe unique ID of the user.
course_idNoThe unique ID of the course.
payload_fileNoAbsolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, so the safety profile is covered structurally. The description adds nothing beyond that – no mention of irreversibility, required permissions, or that enrolling may overwrite an existing enrollment.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero waste, so nothing is bloated. However, for a destructive 6-parameter tool it reads as under-specification rather than disciplined brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a destructive, non-idempotent mutation with 6 parameters, an unused confirm flag, two alternative body-passing mechanisms, and no output schema. The description covers none of those operational details, leaving an agent without enough context to invoke it safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the flat user_id/course_id, the nested payload, payload_file, confirm, and account fields are each documented in the schema. The description adds no meaning beyond that, which is the baseline 3 case; it doesn't clarify the payload-vs-flat-param choice or the confirm semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Enroll a user in a course.' That is unambiguous about the action. It does not differentiate from siblings like unenroll_user or create_user, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no preconditions, and no mention of the obvious alternative unenroll_user. There is also a confirm parameter implying a confirmation workflow that the description never explains.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_userCreate UserC
Destructive

Create a new user

ParametersJSON Schema
NameRequiredDescriptionDefault
srcNoThe [signup source](https://support.teachable.com/hc/en-us/articles/219571648#TrackSignupSourceshttps://support.teachable.com/hc/en-us/articles/219571648#TrackSignupSources) of the user, Information tab of the user profile. SRC can also be used as a custom value when creating users in your school. For example, if you use any unique identifiers to help manage your users in multiple external systems (such as unique IDs, tags, etc.), you can use the src field to keep this identifier associated with your user in Teachable.
nameNoThe name of the new user.
emailNoThe email address of the new user..
accountNoExact private school profile label; not a provider identity or authorization proof.
confirmNoSet true only when the user asked for exactly this action.
payloadNoComplete current native JSON body; cannot mix with native body flags or payload_file.
payload_fileNoAbsolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

TDQS

C2.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, and openWorldHint=true, so the safety profile is carried by structured data. The description adds nothing beyond that: it does not state permission requirements, that duplicate emails may be rejected, that creation is non-idempotent (retries could create duplicates), or what the caller receives. The schema's confirm flag ('Set true only when the user asked for exactly this action') signals a confirmation contract the description never mentions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The single sentence is front-loaded and free of padding, but it does not earn its place because it duplicates the title rather than conveying anything new. Brevity here reflects under-specification rather than efficient communication.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with seven parameters, a nested payload object, alternative body encodings (payload vs payload_file vs flat flags), zero required top-level fields, and no output schema, the description omits everything an agent needs beyond the schema: which fields are effectively required (payload requires email), which creation mode to choose, and the confirm contract. Rich schema coverage and annotations partially compensate, but the description itself is not complete enough.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every one of the seven parameters (src, name, email, account, confirm, payload, payload_file) is documented in the schema itself, including the payload/payload_file mutual exclusion. Per the rubric this sets a baseline of 3; the description adds no parameter meaning of its own, so it cannot rise above the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Create a new user" restates the tool name (create_user) and title (Create User) almost verbatim, giving no more information than the identifier itself. It names a verb and resource, but does not distinguish this tool from siblings like create_enrollment, update_user, or submit_school_batch, nor does it say what a created user gets (access, enrollment, invitation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as update_user (for existing accounts) or submit_school_batch (for bulk creation). An agent must infer entirely from the name which of the several creation/update tools applies.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_resourcesExport bounded private metadataA
Destructive

Confirmed reviewed native page/per or page/per_page export into a new exclusive0600 file. Page/item/5MiB budgets and explicit continuation; no signed links followed or binary download. Not an atomic backup.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
confirmNoSet true only when the user asked for exactly this action.
argumentsNoCurrent native list arguments; cannot override profile/policy/output.
max_itemsNo
max_pagesNo
operationYes
output_fileYes
start_offsetNo

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true, readOnlyHint=false, openWorldHint=true, idempotentHint=false, so the safety profile is largely covered. The description adds meaningful context: creates a new exclusive 0600 file, enforces page/item/5MiB budgets, supports explicit continuation, does not follow signed links or download binaries, and is not an atomic backup. These are valuable beyond annotations, though file permissions after failure and partial-write behavior are not fully clarified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Very compact: two sentences front-load the core action and constraints. Every clause carries information, though 'per/per_page' and 'exclusive0600' are compressed to the point of obscurity for an agent unfamiliar with the API.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent, open-world export tool with 8 params at 38% schema coverage and no output schema, the description covers budgets, continuation, file permissions, and limits building. But it omits operation enum semantics, confirm behavior, output_file expectations, and what happens to partial exports—gaps an agent needs to invoke it safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 38% across 8 params, so description must compensate. It mentions page/item/5MiB budgets and continuation, which aligns with max_pages/max_items/start_offset but does not name them. It does not explain operation enum variants, output_file format, account label semantics, confirm usage, or the nested arguments object. Marginal compensation for a notable coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: exporting metadata into a new exclusive file, with pagination and budgets. It distinguishes itself from sibling read tools by noting it writes a file and has budgets/continuation. However, 'per/per_page' and 'native page' phrasing is cryptic and not standard terminology, leaving the exact operation somewhat ambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is for bounded exports rather than ad-hoc reads, and warns it is 'not an atomic backup' and that signed links are not followed. But it does not explicitly say when to use export_resources instead of the many list_* siblings, nor does it state required confirm semantics in the guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_courseShow CourseB
Read-onlyIdempotent

Fetch a specific course by ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
course_idYesReturn a course by its unique ID.

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint, so the safety profile is covered. The description adds no behavioral context beyond that, such as authentication needs, rate limits, or error/return behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single, front-loaded sentence with no wasted words. The action and key identifier are clear immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only getter with full schema coverage and strong annotations, this is minimally viable. However, it omits the account parameter behavior and does not describe the return value, which matters somewhat because there is no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both course_id and account. The description only reinforces that the course is fetched by ID and adds no syntax, format, or optional-parameter guidance beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: fetch a specific course by ID. It distinguishes the tool from list-oriented siblings like list_courses by requiring an ID, but it does not name any sibling alternative explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description only says what the tool does and implies usage when a course ID is known. It provides no when-to-use guidance, no alternatives such as list_courses or get_course_progress, and no exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_course_progressCourse ProgressC
Read-onlyIdempotent

Fetch a specific user's course progress.

ParametersJSON Schema
NameRequiredDescriptionDefault
perNoUsed in pagination to define amount of courses per page, when not defined the maximum is 20
pageNoUsed in pagination when number of courses exceed the maximum amount of results per page
accountNoExact private school profile label; not a provider identity or authorization proof.
user_idYesThe unique ID of the user.
course_idYesThe unique course ID that contains the lecture.

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, covering the safety profile. The description adds nothing beyond that – no note on auth requirements, pagination semantics, or behavior of the composite lookup.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted words, but for a 5-parameter tool with pagination behavior it is arguably thinner than the surface area warrants.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should signal what progress data is returned and how pagination applies, but it says nothing about return values or the per/page params. Annotations cover safety, yet the core payload semantics are absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so course_id and user_id are fully documented by the schema, and pagination params per/page carry their own descriptions. The description's 'specific user' phrasing loosely maps to the required params but adds no syntax or format detail, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Fetch') and a clearly scoped resource ('a specific user's course progress'). An agent can tell it apart from generic get_course or get_user, but the description does not explicitly contrast this composite getter with the many sibling getters.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use context, no prerequisites, and no mention of alternatives such as get_course, list_enrollments, or mark_lecture_complete in the large sibling set. The agent is left to infer when this tool is the right choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_lectureShow LectureB
Read-onlyIdempotent

Fetch content of a specific course lecture.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
course_idYesReturn results by unique course ID that contains the lecture.
lecture_idYesReturn results by unique lecture ID.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, covering the safety profile. The description adds only that it returns lecture "content," without clarifying what that content is (text, video reference, quiz-like material) or any access constraints, so it adds minimal value beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with no waste and the key action front-loaded. It is efficient, though the brevity edges toward under-specification rather than optimal conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-required-parameter read tool with 100% schema coverage and a full annotation set, plus no output schema, the description is minimally adequate. It leaves the nature of the returned 'content' unstated, which is the main remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter carries its own description, including the subtle distinction that 'account' is a profile label and not an authorization proof. The description contributes no additional parameter meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("fetch content of a specific course lecture"), which is clear enough to distinguish from get_course and get_quiz by object. However, it does not differentiate from adjacent siblings such as get_video or mark_lecture_complete, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No indication of when to use this tool versus get_course, get_video, or get_quiz, and no prerequisites or exclusions are given beyond the implicit need for a course/lecture ID.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_operation_schemaInspect native contractC
Read-onlyIdempotent

Local reviewed native method/path/query/body/scopes/rate limit and pinned schema provenance. No provider access or authority proof.

ParametersJSON Schema
NameRequiredDescriptionDefault
operationYes

TDQS

C2.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/non-destructive/non-open-world. The description adds context beyond them: the data is 'local', 'reviewed', has 'pinned schema provenance', and explicitly does 'no provider access' and makes no 'authority proof'. That is meaningful caveat disclosure, though it does not describe the shape or completeness of the returned contract.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two terse fragments with little waste, but the front-loaded text is opaque rather than informative; a reader must parse a noun list to reconstruct the tool's job.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description bears the burden of explaining return content. It gestures at the fields returned (method/path/query/body/scopes/rate limit/schema provenance) but does not clarify structure or what an agent should do with them, and gives no guidance for a single enum-constrained param.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage at 0% and a single 'operation' parameter, the description must carry the meaning. It implies the parameter selects among native operations (method/path/etc. belong to the chosen operation), and the enum values are largely self-describing, but it never states what the parameter accepts or where its values come from.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The title 'Inspect native contract' and the description's list (method/path/query/body/scopes/rate limit/schema provenance) hint that this returns a native API operation's contract, but the description is a noun fragment with no clear verb. An agent can guess it inspects an operation's definition rather than fetching live data, yet the exact purpose is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of prerequisites, and no routing to or away from siblings. 'No provider access or authority proof' is a scope caveat rather than usage direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pricing_planShow Pricing PlansA
Read-onlyIdempotent

Fetch details of a specific pricing plan. Currently only supports pricing plans associated with courses.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
pricing_plan_idYesSearch for a pricing plan by its unique ID.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is covered. The description adds the scope limitation (course-associated plans only), which is genuinely useful, but says nothing about permissions or failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core purpose front-loaded and the scope caveat second. No wasted words, though it is minimally sized rather than richly informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A simple read-only lookup with full schema coverage and annotations covering the safety profile; no output schema means return values need not be described. The scope note is the right kind of added context for this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (account and pricing_plan_id) are already documented in the schema. The description adds no syntax, format, or constraint detail beyond what the schema provides, meeting the baseline for full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Fetch) and resource (details of a specific pricing plan), which distinguishes it from the sibling list_pricing_plans by implying single-item retrieval. It does not explicitly name the sibling, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The note 'Currently only supports pricing plans associated with courses' is a useful scoping constraint that implies when the tool applies, but there is no explicit when-to-use, when-not-to-use, or named alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_quizShow QuizC
Read-onlyIdempotent

Fetch a specific quiz information.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
quiz_idYesReturn results by unique quiz attachment ID.
course_idYesReturn results by unique course ID that contains the lecture.
lecture_idYesReturn results by unique lecture ID.

TDQS

C2.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint, so the safety profile is fully covered. The description adds nothing beyond that- no note on required IDs resolving, permissions, or failure modes. With annotations doing the work, the description contributes no incremental behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single short sentence with no wasted clauses, which is good. But the concision is achieved by under-specification rather than by front-loading dense information, so it barely clears the minimum-viable bar.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool takes three required IDs and has no output schema, so the description should at least hint at what is returned (quiz metadata, questions, etc.) and whether the account parameter is needed. None of that is present, leaving the agent to infer the result shape entirely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented in the schema (including the account label caveat and ID semantics). The description adds no syntax, format, or relationship detail beyond the schema. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Fetch') and resource ('quiz'), so the basic intent is clear. However, it offers no differentiation from siblings like list_quizzes or list_quiz_responses, and 'a specific quiz information' is grammatically loose. An agent gets the gist but must infer the singular-vs-list boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of prerequisites, and no routing to alternatives such as list_quizzes for enumerating quizzes. The only signal is that a single quiz is fetched, which the name already conveys.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_userShow UserB
Read-onlyIdempotent

List a specific user and their course enrollments by user ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
user_idYesThe unique ID of the user.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful content context by noting that course enrollments are included in the result, but says nothing about pagination, enrollment volume, or error behavior for unknown IDs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the resource and its key filter, with no filler. Only the mildly confusing 'List a specific user' phrasing keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description's mention that enrollments come back with the user is the only return-value signal provided; it does not indicate what user fields are returned or whether enrollments are nested or paginated. Adequate but thin for a tool whose response shape is otherwise undocumented.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters (account, user_id) are already documented in the schema, including the caveat that 'account' is a profile label, not authorization. The description adds nothing beyond the schema baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (a user) and its scope (course enrollments), keyed by user ID, which distinguishes it from list_users and get_course. The verb 'List' is slightly odd for a single-record fetch, but the intent is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'a specific user ... by user ID' implies this is the single-record lookup versus bulk list_users, but no alternative or when-not condition is named. An agent must infer the routing from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_videoShow VideoC
Read-onlyIdempotent

Fetch a specific video information.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
user_idNoSpecify the user who is watching the video
video_idYesReturn results by unique video attachment ID.
course_idYesReturn results by unique course ID that contains the lecture.
lecture_idYesReturn results by unique lecture ID.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond "fetch" — no note on permission/account scoping, not-found behavior, or what the returned payload contains — so it contributes little behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence, front-loaded with the verb and resource, with no wasted clauses. It is slightly ungrammatical ("a specific video information") but structurally efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, fully annotated getter with 100% schema coverage and no output schema, the description is minimally adequate. It omits any hint of the response shape or lookup-failure semantics, which is a modest gap rather than a blocking one.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with every parameter (account, user_id, video_id, course_id, lecture_id) documented in the schema itself. The description adds no parameter meaning beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ("Fetch") and resource ("video"), so an agent knows it retrieves a single video's information. It does not, however, distinguish this from neighbors like get_lecture or get_course, so sibling differentiation is absent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus get_lecture, get_course, or any listing tool, and no prerequisites or exclusions are stated. The agent must infer usage entirely from the name and schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_webhook_eventsShow Webhook EventsC
Read-onlyIdempotent

Fetch all the events for a webhook.

ParametersJSON Schema
NameRequiredDescriptionDefault
perNoSet the maximum number of results to be returned by page. By default, each page will return 20 results.
pageNoSet the page number to be returned. (i.e., If you have two pages of results with 20 results per page, set the page value to 1 to receive results 1 through 20, or set the page value to 2 to receive results 21-40).
accountNoExact private school profile label; not a provider identity or authorization proof.
webhook_idYesThe unique ID of the webhook.
created_afterNoSearch for webhook events that were created after a specific date/time. Formatted in ISO 8601.2020-04-17T19:44:03Z
created_beforeNoSearch for webhook events that were created before a specific date/time. Formatted in ISO 8601.2020-04-17T19:44:03Z
response_http_status_gteNoFilter responses by HTTP status code of the webhook event, greater than or equal to the provided value (i.e., enter 200 to search for webhook events that had an HTTP status code of 200 or greater).
response_http_status_lteNoFilter responses by HTTP status of the webhook event, less than or equal to the provided value. (e.g., enter 200 to search for webhook events that had an HTTP status code of 200 or less).

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive, so the safety profile is covered. The description adds nothing beyond that: it never mentions pagination behavior, that results are filterable by date or HTTP status, or how many events are returned by default, despite pagination params in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single short sentence with zero padding, which is front-loaded and efficient. However, it is under-specified rather than genuinely concise, omitting meaningful context that this multi-parameter tool needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter tool with pagination, date-range, and HTTP-status filtering, the description says nothing about those capabilities, and with no output schema it also fails to characterize return values. An agent would need to reverse-engineer behavior entirely from the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all eight parameters (per, page, created_after/before, response_http_status_gte/lte, etc.) are already documented in the schema. The description adds no syntax, defaulting, or format context beyond what the schema provides, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (Fetch) and resource (all the events for a webhook), which clearly distinguishes it from the sibling list_webhooks (which enumerates webhooks rather than their events). It is clear, though it offers no explicit sibling differentiation or scoping detail.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives, no mention of prerequisites (e.g., a valid webhook_id), and no conditions or exclusions. Usage must be entirely inferred from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_accountsList private school profilesC
Read-onlyIdempotent

Local labels/default/version/auth source availability only. No credential values, paths, provider identity or network.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

C2.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is fully covered. The description does add meaningful context about data minimization: it explicitly says credential values, paths, provider identity, and network are excluded, which tells the agent the output is limited to non-sensitive metadata. That is genuine value beyond annotations, though it does not describe return shape or freshness.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single compact sentence with no wasted words, which is good, but it is a fragment that doesn't front-load the core action. The most important information for an agent—that this lists account metadata—is absent rather than leading.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-argument, read-only list tool, annotations and the schema cover most of the burden, and the exclusions add useful scoping. However, the description never says what the tool actually returns (account/profile entries) or how it is distinct from the other list_* tools, leaving a real gap an agent must guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters the baseline is 4. There is nothing to document, and the description appropriately spends no space on non-existent inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

The tool is named list_accounts with title 'List private school profiles', but the description never states that it lists accounts or profiles. Instead it enumerates metadata fields ('labels/default/version/auth source availability only'), which reads more like a scoping caveat than a statement of purpose. An agent cannot confidently tell what resource is returned or how it differs from list_users or list_courses.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance and no mention of alternatives among the many list_* siblings. The only directive is a negative scope ('No credential values, paths, provider identity or network'), which tells the agent what it will NOT get but not when this tool is the right choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_coursesList CoursesC
Read-onlyIdempotent

Fetch all courses at your school.

ParametersJSON Schema
NameRequiredDescriptionDefault
perNoUsed in pagination to define amount of courses per page, when not defined the maximum is 20
nameNoFilter courses by course name
pageNoUsed in pagination when number of courses exceed the maximum amount of results per page
accountNoExact private school profile label; not a provider identity or authorization proof.
created_atNoReturn courses by the date & time of course creation. Formatted in ISO8601.
is_publishedNoFilter courses by published status. If true, return published courses. If false, return unpublished courses.
author_bio_idNoFilter courses by a specific course author via the course author's bio ID.

TDQS

C2.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds nothing beyond that — no pagination behavior (default 20 per page lives only in the schema), no rate limits, and the claim of returning "all" courses sits awkwardly against the available filters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler or repetition of the title. It is efficient, though its brevity comes at the cost of the missing scope/filter qualification.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a seven-parameter list tool with pagination and multiple filters, no output schema, and no annotation detail on result shape, the description should at least signal filtering and paging behavior. Instead it implies an unfiltered dump, leaving the agent to discover scope from the schema alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the seven parameters are fully documented in the schema itself, which sets the baseline at 3. The description adds no format, default, or interaction detail beyond the schema, and "all" slightly undercuts the filtering story.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

State a clear verb+resource ("Fetch ... courses") scoped to "your school," so an agent can tell it apart from get_course (singular read). However, "all courses" is inaccurate given the schema supports name, is_published, author_bio_id and created_at filtering, so the stated scope overpromises.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance and no mention of any alternative such as get_course for a single course. The agent is left to infer that this is the browse-everything entry point versus the single-item read.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_enrollmentsShow Course EnrollmentsB
Read-onlyIdempotent

Fetch active enrolled students and student progress for a specific course.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
course_idYesReturn enrollments for a specific course by the unique course ID.
sort_directionNoEnrollments are sorted by the 'enrolled_at' datetime. You can choose the direction by including the sort_direction param.
enrolled_in_afterNoSearch for students who are enrolled after a specific date/time. Formatted in ISO8601.
enrolled_in_beforeNoSearch for students who are enrolled before a specific date/time. Formatted in ISO8601.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds one useful behavioral fact — only 'active' enrollments are returned — but says nothing about pagination, result volume, or how progress data is shaped.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler or redundancy. It is efficient, though so terse that it omits information an agent would benefit from.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a 5-parameter schema fully documented and annotations covering the safety profile, the description is close to sufficient. But it omits return-shape/pagination expectations and leaves the 'student progress' claim unclarified relative to get_course_progress, so it is only minimally adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter (including sort_direction, enrolled_in_after/before, and account) is documented in the schema itself. The description only restates that a course is required, adding no syntax or filtering nuance beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb ('Fetch'), resource ('active enrolled students'), and scope ('for a specific course'), so the operation is understandable at a glance. It does not differentiate itself from siblings like get_course_progress or list_users, and the phrase 'and student progress' is ambiguous since a separate get_course_progress tool exists.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance is given. The description never mentions alternatives such as create_enrollment, unenroll_user, or get_course_progress, nor the condition that should pick this tool over them. Context is implied only by the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pricing_plansList Pricing PlansB
Read-onlyIdempotent

Fetch all the pricing plans at your school

ParametersJSON Schema
NameRequiredDescriptionDefault
perNoUsed in pagination to define amount of pricing plans per page, when not defined the maximum is 5
pageNoUsed in pagination when number of pricing plans exceeds the maximum amount of results per page
accountNoExact private school profile label; not a provider identity or authorization proof.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is fully covered structurally. The description adds only the school-scoping constraint; it says nothing about ordering, completeness, or pagination behavior beyond what the schema documents.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no waste and the scope constraint front-loaded. It is efficient, though minimal — nothing is reinforced or clarified beyond the bare statement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a trivial, fully-parameterized read-only list tool with annotations covering safety, the description is adequate but thin. With no output schema, one line about what a pricing plan record contains or how results are ordered would meaningfully improve it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so 'per', 'page' and 'account' are all documented in the schema itself, including the default max of 5 per page and the caution that 'account' is a label rather than an auth proof. The description adds no parameter meaning beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (fetch/list) and resource (pricing plans) and narrows scope to 'your school'. It is clear, but it does not explicitly differentiate itself from the sibling get_pricing_plan, leaving the list-vs-single distinction to be inferred from the name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of when get_pricing_plan is the better choice, and no prerequisites or exclusions. The agent is left to infer usage entirely from the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_quiz_responsesShow Quiz ResponsesC
Read-onlyIdempotent

Fetch the responses of quiz.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
quiz_idYesReturn results by unique quiz attachment ID.
course_idYesReturn results by unique course ID that contains the lecture.
lecture_idYesReturn results by unique lecture ID.

TDQS

C2.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered externally. The description adds nothing beyond that — no note on what a response record contains, whether results are paginated, scoped to course/lecture/quiz, or whether the account parameter is needed for access.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler, which is structurally clean. However, its brevity reflects under-specification rather than efficient information density — one clause cannot carry the purpose, scope and usage guidance this tool needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a read-only list operation with no output schema, so the description should at least frame what is returned (individual responses vs. aggregates, filtering scope). Given a rich sibling set and a three-key required scope, the description leaves the agent without enough to confidently choose or interpret results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each of the four parameters is documented directly in the schema (including the subtle 'account is not an authorization proof' note). The description adds no parameter meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a verb and resource ('Fetch the responses of quiz'), so the basic action is inferable, but the phrasing is awkward and it never differentiates itself from siblings like get_quiz or list_quizzes. An agent can guess what it does but gets no help distinguishing it within the quiz tool family.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisite or scope conditions, and no mention of any alternative tool. The agent must infer everything about selection from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_quizzesList QuizzesA
Read-onlyIdempotent

Fetch an id list of quizzes in a specific course lecture.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
course_idYesReturn results by unique course ID that contains the lecture.
lecture_idYesReturn results by unique lecture ID.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description usefully adds that only IDs are returned (a lightweight result), but says nothing about ordering, pagination, or empty-result behavior for what may be a remote/open-world source.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the resource and its scoping constraint are stated immediately and nothing is repeated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with no output schema, the description conveys the key return shape (an ID list) and the scope, while annotations carry the safety profile. Only secondary details like ordering or pagination are absent, which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters are already documented, including the non-obvious 'account' label semantics. The description only restates the course/lecture scoping that the schema already conveys, adding no syntax or format detail beyond it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (fetch) plus resource (quizzes) and narrows scope to a specific course lecture, and the 'id list' phrasing distinguishes it from detail-fetching siblings like get_quiz. It does not explicitly name any sibling, so an agent must infer the distinction from the resource noun alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The scoping phrase 'in a specific course lecture' implies when this tool is relevant, but there is no explicit when-to-use or when-not-to-use guidance. Nothing tells the agent how to choose between this and get_quiz or list_quiz_responses.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_transactionsList TransactionsC
Read-onlyIdempotent

Fetch a list of sales transactions made in your school. (New transactions can take up to two minutes to be returned via API call from the time of sale.)

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoThe end of the time period to return results for (inclusive), in ISO8601 format.
perNoUsed in pagination to define amount of transactions per page, when not defined the maximum is 20
pageNoUsed in pagination when number of transactions exceed the maximum amount of results per page
startNoThe beginning of the time period to return results for (exclusive), in ISO8601 format.
accountNoExact private school profile label; not a provider identity or authorization proof.
user_idNo
course_idNo
affiliate_idNo
is_chargebackNo
pricing_plan_idNo
is_fully_refundedNo

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds one genuine behavioral trait beyond the structured fields: the up-to-2-minute propagation delay for new transactions. It says nothing about pagination behavior or ordering despite 11 params.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the operation and followed by a useful caveat. No filler, though the latency note in parentheses could be more tightly integrated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter, filter-heavy list tool with no output schema and 0 required params, the description leaves too much unstated: what filters do, how pagination interacts, and what the agent gets back. Only the latency caveat is added beyond what annotations already provide.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 45%, and the description contributes no parameter meaning at all. Six filter parameters (user_id, course_id, affiliate_id, is_chargeback, pricing_plan_id, is_fully_refunded) are undocumented in both the schema and the description, so the description fails to compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Fetch a list of sales transactions') and scopes it to 'your school'. No sibling tool deals with transactions, so differentiation is automatic. Clear but could be sharper about what a returned transaction contains.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers no when-to-use or when-not-to-use guidance and names no alternative. It implies a listing purpose but says nothing about how the many optional filters (user_id, course_id, affiliate_id, etc.) map to use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_usersList UsersC
Read-onlyIdempotent

Get a list of users

ParametersJSON Schema
NameRequiredDescriptionDefault
perNoUsed in pagination to define amount of users per page, when not defined the maximum is 20
pageNoUsed in pagination when number of users exceed the maximum amount of results per page
emailNoFilter users by user email.
accountNoExact private school profile label; not a provider identity or authorization proof.
search_afterNoUsed when number of users exceeds 10,000 records. Use the search_after value in the parameters to search the next set of records.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, covering the safety profile. The description adds no behavioral context beyond that, such as pagination behavior, result limits, or authentication requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with zero waste. It is appropriately concise, though its extreme brevity means it provides no structural cues for the tool's more complex pagination and filtering behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with five optional pagination/filter parameters and no output schema, the description is incomplete. It does not explain return format, pagination limits, or filtering semantics, leaving the agent reliant solely on the schema and annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters (per, page, email, account, search_after) are fully documented in the schema. The description adds no parameter meaning beyond 'users', so the baseline of 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Get a list of users'), so an agent can tell it retrieves users rather than accounts or courses. However, it does not differentiate from sibling list tools beyond the resource name, and it leaves scope (e.g., all users vs. filtered users) unspecified.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives like get_user or list_accounts, nor any conditions or exclusions. Usage is only implied by the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_webhooksList WebhooksB
Read-onlyIdempotent

Fetch all webhook events for your school.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered structurally. The description adds only the 'for your school' scoping, and says nothing about result size, pagination, or ordering, which is a modest but non-trivial addition given the coverage already present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence that front-loads the action and resource with zero filler. Nothing could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-optional-parameter list tool with annotations covering safety, this is close to sufficient, but with no output schema the description should at least hint at return shape or volume, and it leaves the overlap with get_webhook_events unexplained. Adequate but with clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the single 'account' parameter is already well documented in the schema with a precise definition. The description adds no format, default, or filtering semantics beyond what the schema already states, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb plus resource ('Fetch all webhook events') and scopes it to the caller's school, so the operation itself is unambiguous. However, it makes no attempt to distinguish itself from the sibling tool get_webhook_events, which an agent would have to disambiguate on its own.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance about when to use this tool versus get_webhook_events or any other sibling, and no prerequisites or exclusions are stated. The agent is left to infer usage purely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mark_lecture_completeMark Lecture CompleteC
Destructive

Mark a specific course lecture as complete.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
confirmNoSet true only when the user asked for exactly this action.
payloadNoComplete current native JSON body; cannot mix with native body flags or payload_file.
user_idNoThe unique ID of the user.
course_idYesThe unique course ID that contains the lecture.
lecture_idYesThe unique lecture ID.
payload_fileNoAbsolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already disclose the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=false, openWorldHint=true), so the bar is lower, but the description adds nothing beyond them. It does not say what state changes, whether completion is reversible, or how it interacts with progress tracking.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no waste, which is good, but for a 7-parameter destructive mutation it is sized too small to be 'appropriate.' It is concise at the cost of being underspecified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a destructive, non-idempotent mutation with a nested payload, mutually exclusive payload/payload_file body flags, and no output schema, the description is materially incomplete. It omits the confirm-gating requirement and the payload-vs-payload_file exclusivity that an agent must respect to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the notable 'confirm' and 'payload' semantics, so the structured data carries the parameter burden. The description adds no parameter meaning of its own, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource: marking a given course lecture as complete. It is unambiguous about what the tool does, but it offers no differentiation from siblings such as get_lecture or get_course_progress, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus alternatives, no mention of prerequisites, and no acknowledgment of the destructive/irreversible nature. A reader cannot infer when it is appropriate to call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_school_batchReview ordered school effectsB
Read-onlyIdempotent

Validate every exact request and hash order/profile label/schema locally. No native request, credential loading, ownership check or provider preview.

ParametersJSON Schema
NameRequiredDescriptionDefault
tasksYesOne to twenty exact ordered native effects. No signed receipts or mutable payload files. Cannot override account/confirm/output settings.
accountNoExact private school profile label; not a provider identity or authorization proof.

TDQS

B3.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and a closed world, so the safety profile is covered. The description adds real value beyond that by enumerating what does NOT happen (no native request, no credential loading, no ownership check, no provider preview), warning the agent that local validation will not catch permission or ownership problems. That is meaningful behavioral context not present in the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the action front-loaded in the first clause and the exclusions compressed into the second. Nothing is wasted, though the compressed phrasing sacrifices readability for density.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a validation tool with no output schema, the agent would benefit from knowing what the validation returns (which requests failed, error shape) and whether ordering violations are reported. The description covers side effects adequately but leaves the response contract unspecified, leaving a clear gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the 'tasks' array shape and the 'account' label are already documented, including the 1-20 item bound and the note that account is not an authorization proof. The description's mention of 'exact request' and 'order/profile label/schema' only loosely echoes those fields and adds no syntax or format detail. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (Validate) over the batch of requests, and the negative clause implies it is a local dry-run rather than an execution. However, the phrasing 'hash order/profile label/schema' and 'school effects' is opaque jargon, and the tool never explicitly says it is the pre-flight check for submit_school_batch. An agent can guess the intent but not cleanly separate it from its sibling by reading the description alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance and no mention of submit_school_batch, the obvious alternative that actually performs the effects. The agent must infer from the words 'No native request... or provider preview' that this is the safe step preceding submission, which is left entirely to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

submit_school_batchExecute reviewed school effectsA
Destructive

Confirmed ordered effects; all validated/hash checked before first request. Stop on first failure with known and unattempted receipts; no retry, rollback or implicit continuation.

ParametersJSON Schema
NameRequiredDescriptionDefault
tasksYesOne to twenty exact ordered native effects. No signed receipts or mutable payload files. Cannot override account/confirm/output settings.
accountNoExact private school profile label; not a provider identity or authorization proof.
confirmNoSet true only when the user asked for exactly this action.
review_sha256Yes

TDQS

A3.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructive=true, idempotent=false, openWorld=true, but the description adds genuinely new behavioral context beyond them: validation/hash-checking happens before the first request and execution stops on first failure with no retry, rollback, or implicit continuation. This partial-failure, non-transactional semantics is exactly what an agent needs and is not derivable from the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the core scope ('Confirmed ordered effects') and then the failure contract. Every clause carries load with no filler, appropriate for a high-risk batch tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive 20-item batch tool with no output schema, key gaps remain: the shape and meaning of the returned 'receipts' (known vs unattempted) is unspecified, and routing to preview_school_batch is absent. Validation and failure behavior are well covered, so it is adequate but not complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75%: tasks, account and confirm each carry schema descriptions, while review_sha256 is only a pattern. The description adds meaning to review_sha256 ('all validated/hash checked before first request') but does not explain the hashing or how the hash is produced. Near the baseline 3 for a well-documented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description conveys that this executes a batch of previously confirmed, validated effects ('all validated/hash checked before first request'), which pairs with the name submit_school_batch and the title's 'Execute'. However it never states the verb itself and does nothing to distinguish it from the sibling preview_school_batch, so an agent must open both to tell them apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use or when-not-to-use statement. The obvious alternative, preview_school_batch, is never mentioned even though the entire description implies this is the post-review execution step; the agent is left to infer that it should preview first. Only 'Confirmed' hints at a prerequisite.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unenroll_userUnenroll UserC
Destructive

Unenroll a user from a course.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountNoExact private school profile label; not a provider identity or authorization proof.
confirmNoSet true only when the user asked for exactly this action.
payloadNoComplete current native JSON body; cannot mix with native body flags or payload_file.
user_idNoThe unique ID of the user.
course_idNoThe unique ID of the course.
payload_fileNoAbsolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false and openWorldHint=true, so the safety profile is partly covered structurally. However, the description adds nothing beyond restating the name: it never says the removal is irreversible, that a confirm gate exists, or what happens to course progress/history when a user is unenrolled. With a destructive mutation, that additional context is exactly what the description should supply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The single sentence is front-loaded and contains no filler, which is good. But for a 6-parameter destructive tool with a nested payload and a confirm gate, this is under-specification rather than genuine conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a destructive mutation with no required parameters, two competing ways to identify the target (flat ids vs payload), a payload_file alternative, a confirm flag, and no output schema, one sentence leaves the agent without enough to call it correctly. The description should at minimum explain the confirm requirement and which parameterization to prefer.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the schema already documents user_id, course_id, payload, payload_file and confirm. The description adds no meaning, and critically does not resolve the structural ambiguity between the top-level user_id/course_id and the nested payload.user_id/course_id, nor why no parameter is required.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('unenroll a user from a course'), which is unambiguous on its own. It does not, however, differentiate itself from the sibling create_enrollment or explain its relationship to list_enrollments, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of the inverse tool (create_enrollment), and no note that this is the removal counterpart to enrollment creation. The agent must infer all routing from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_userUpdate UserC
Destructive

Update the name or src of a user.

ParametersJSON Schema
NameRequiredDescriptionDefault
srcNoThe signup source of the user, which is displayed on the Information tab of the user profile. .
nameNoThe name of the user.
accountNoExact private school profile label; not a provider identity or authorization proof.
confirmNoSet true only when the user asked for exactly this action.
payloadNoComplete current native JSON body; cannot mix with native body flags or payload_file.
user_idYesThe unique ID of the user.
payload_fileNoAbsolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=false and openWorldHint=true, so the safety profile is partly covered. The description adds nothing beyond that: it does not warn that the change is destructive/irreversible, does not mention the confirm gating, and says nothing about how the payload vs. payload_file body modes behave.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence, front-loaded with the verb and resource, with zero filler. Its brevity is efficient, though it shades into under-specification for a seven-parameter destructive mutation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent, open-world mutation with seven parameters (including nested objects and mutually exclusive body modes) and no output schema, the description is far too thin. It omits risk framing, body-mode selection, and error/response expectations, leaving the agent to reconstruct all of it from schema prose and annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including clear semantics for user_id, account, confirm, payload and payload_file, so the schema carries the semantic load and baseline 3 applies. The description names only two of seven parameters, and its 'name or src' framing sits awkwardly beside the full-body 'payload'/'payload_file' parameters, but it does not actively contradict the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Update) and resource (user) plus the two headline fields (name, src). It is distinguishable from get_user/create_user at a glance, but it does not differentiate itself from the mutation siblings (unenroll_user, create_enrollment, mark_lecture_complete) beyond the resource noun.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use, when-not-to-use, or alternative routing is given. The agent is not told to prefer create_user for new users or get_user for reads, nor when this destructive op is appropriate. Usage is left entirely to inference from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updatesv3.0.1
    • Changedcreate_enrollment2 fields changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Explicit approval for this exact provider effect or local private-file operation."New value: +"Set true only when the user asked for exactly this action."
      • changedInput schema / properties / payload_file / description
        Previous value: -"Absolute regular non-symlink native JSON body file, at most1MiB. Cannot mix with payload or body flags."New value: +"Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags."
    • Changedcreate_user2 fields changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Explicit approval for this exact provider effect or local private-file operation."New value: +"Set true only when the user asked for exactly this action."
      • changedInput schema / properties / payload_file / description
        Previous value: -"Absolute regular non-symlink native JSON body file, at most1MiB. Cannot mix with payload or body flags."New value: +"Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags."
    • Changedexport_resources1 field changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Explicit approval for this exact provider effect or local private-file operation."New value: +"Set true only when the user asked for exactly this action."
    • Changedmark_lecture_complete2 fields changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Explicit approval for this exact provider effect or local private-file operation."New value: +"Set true only when the user asked for exactly this action."
      • changedInput schema / properties / payload_file / description
        Previous value: -"Absolute regular non-symlink native JSON body file, at most1MiB. Cannot mix with payload or body flags."New value: +"Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags."
    • Changedsubmit_school_batch1 field changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Explicit approval for this exact provider effect or local private-file operation."New value: +"Set true only when the user asked for exactly this action."
    • Changedunenroll_user2 fields changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Explicit approval for this exact provider effect or local private-file operation."New value: +"Set true only when the user asked for exactly this action."
      • changedInput schema / properties / payload_file / description
        Previous value: -"Absolute regular non-symlink native JSON body file, at most1MiB. Cannot mix with payload or body flags."New value: +"Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags."
    • Changedupdate_user2 fields changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Explicit approval for this exact provider effect or local private-file operation."New value: +"Set true only when the user asked for exactly this action."
      • changedInput schema / properties / payload_file / description
        Previous value: -"Absolute regular non-symlink native JSON body file, at most1MiB. Cannot mix with payload or body flags."New value: +"Absolute regular non-symlink native JSON body file, at most 1 MiB. Cannot mix with payload or body flags."
  2. 26 tool updatesv2.0.0
    • First observedcreate_enrollment
    • First observedcreate_user
    • First observedexport_resources
    • First observedget_course
    • First observedget_course_progress
    • First observedget_lecture
    • First observedget_operation_schema
    • First observedget_pricing_plan
    • First observedget_quiz
    • First observedget_user
    • First observedget_video
    • First observedget_webhook_events
    • First observedlist_accounts
    • First observedlist_courses
    • First observedlist_enrollments
    • First observedlist_pricing_plans
    • First observedlist_quiz_responses
    • First observedlist_quizzes
    • First observedlist_transactions
    • First observedlist_users
    • First observedlist_webhooks
    • First observedmark_lecture_complete
    • First observedpreview_school_batch
    • First observedsubmit_school_batch
    • First observedunenroll_user
    • First observedupdate_user

TDQS

C2.9/5.0

Scored across 26 tools

Disambiguation4/5

Most tools target distinct resources with a clear get_/list_ split, so an agent can usually tell them apart. However, list_webhooks is described as fetching 'webhook events' which overlaps confusingly with get_webhook_events, and the meta tools (list_accounts, get_operation_schema, export_resources, preview/submit_school_batch) are less obviously differentiated.

Naming Consistency4/5

Nearly all tools follow a consistent snake_case verb_noun pattern (get_course, list_users, create_user, mark_lecture_complete). Minor deviation: create_enrollment vs unenroll_user use different nouns for the same enrollment concept, but overall the convention is predictable.

Tool Count3/5

At 26 tools this is on the heavy side for a course-platform surface, and several (list_accounts, get_operation_schema, preview_school_batch, submit_school_batch, export_resources) are meta/utility tools rather than core domain operations. The count is defensible but borders on bloated.

Completeness3/5

The surface is heavily read-oriented, with rich coverage of users, courses, lectures, quizzes, enrollments, webhooks, pricing plans, and transactions. Notable gaps: no create/update/delete for courses or quizzes, no delete_user, and no quiz-response submission, so the lifecycle is incomplete for a management domain.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers