Use this page to look up every CLI command that generates, reads, or deletes content, follows runs, and grades answers.
These commands call the Content API at /v1/content/classrooms/{classroomId}/...
and need a tf_content_ key. Each one acts in the classroom chosen as described in
Choose the Classroom;
pass the global --classroom <id> to pick one. webhook and credits act on the
organization, not a classroom.
The commands on this page describe @tutorflow/cli 0.5.0. Run
tutorflow <command> --help for the flags of your installed version.
Commands Every Resource Shares
course, slide, test, module, video, game, and simulation each have
these subcommands:
| Subcommand | What it does |
|---|---|
list | Lists the classroom's resources. -l, --limit <n> (default 20, max 100), -p, --page <n> (default 1), -s, --search <text>. |
get <id> | Prints one resource. |
open <id> | Prints id, editorUrl, and publicUrl. On a terminal, outside JSON mode, it also opens the public page, or the editor when there is none or you pass --editor. |
delete <id> | Deletes the resource and prints { "id": "...", "deleted": true }. Asks for confirmation, or takes -y, --yes, which is required without a terminal or in JSON mode. |
share <id> | Makes the resource open by link and prints id, its visibility, publicUrl, and editorUrl. JSON mode prints the whole update answer. --listed on video and test only. |
visibility <id> <value> | Sets the visibility to <value>, in any case. Prints the same as share. |
share and visibility send PATCH with visibility, or isPublic for a module:
| Resource | share sets | visibility values |
|---|---|---|
video, test | UNLISTED: opens by link, not listed or searchable. --listed sets PUBLIC. | PUBLIC, UNLISTED, PRIVATE |
slide, game, simulation | PUBLIC | PUBLIC, PRIVATE |
course | PUBLIC | PUBLIC, PRIVATE, ORGANIZATION, CLASSROOM, COURSE |
module | isPublic: true | PUBLIC, PRIVATE, sent as isPublic |
publicUrl stays null until a video is rendered, a game or simulation is built, or
a course is published, and always in the sandbox classroom of a test key. In text
mode share says which applies. A value the resource does not take exits 2 with
EINVAL before any request.
tutorflow course list --search python --limit 50
tutorflow --json slide get 00000000-0000-4000-8000-000000000301
tutorflow test delete 00000000-0000-4000-8000-000000000401 --yes
tutorflow --json video share 00000000-0000-4000-8000-000000000601 | jq -r .publicUrlIn text mode, list prints a table of ID, title, status, and the updated date. In
JSON mode it prints the API page as returned.
Generate Courses, Slides, Tests, and Modules
course, slide, test, and module have generate [prompt], with the alias
create. The prompt is the first argument. On a terminal the CLI asks for it when
you leave it out; otherwise the command fails with ENOINTERACTIVE.
Flags all four share:
| Flag | Meaning |
|---|---|
-l, --language <lang> | Language code of the content. Default en. |
-w, --wait | Wait for the run to finish and print the result. |
--timeout <seconds> | Stop waiting after this many seconds. Default 900. |
--idempotency-key <key> | Sent as Idempotency-Key, so a retried call does not start a second run. |
tutorflow course generate
Generates a course with every lesson. The CLI's help lists the price as 3 credits for the outline plus 3 per lesson.
tutorflow course generate "Beginner Python for analysts" --lessons 5 --level beginner --wait| Flag | Request field |
|---|---|
[prompt] | prompt |
-n, --lessons <n> | lessonCount |
--level <level> | level |
--title <title> | title (generated when omitted) |
--description <text> | description |
tutorflow slide generate
Generates a slide deck with every page, charged per page.
tutorflow slide generate "Photosynthesis" --count 8 --text-length concise --wait| Flag | Request field |
|---|---|
[prompt] | topic |
-n, --count <n> | slideCount |
-t, --theme <themeId> | themeId |
--instructions <text> | instructions |
--text-length <length> | textLength: concise or detailed |
tutorflow test generate
Generates a test with auto-graded items (3 credits).
tutorflow test generate "Algebra basics" --items 3 --item-types select,blank,open-ended --wait| Flag | Request field |
|---|---|
[prompt] | topic |
-n, --items <n> | itemCount |
--item-types <list> | itemTypes: comma-separated, one per question, from select, blank, open-ended, true-false, submission. The API expects as many types as items. |
--level <level> | level |
--instructions <text> | instructions |
--total-score <n> | totalScore |
tutorflow test results <testId> lists learners' results, with -l, --limit <n>
(default 20) and --cursor <cursor> (the meta.nextCursor of the previous page).
tutorflow module generate
Generates an interactive lesson module (3 credits).
tutorflow module generate "Fractions for 5th grade" --type flashcard --wait| Flag | Request field |
|---|---|
[prompt] | topic |
--type <type> | type, for example markdown, ai-tutor, flashcard, or coding-lesson. Chosen from the topic when omitted. |
--reference <text> | referenceText: material the module should be based on |
What generate prints
Without --wait, generate prints the run the API accepted and returns at once:
{
"runId": "00000000-0000-4000-8000-000000000b01",
"status": "queued",
"kind": "course",
"estimatedCredits": 21,
"statusUrl": "/v1/content/classrooms/00000000-0000-4000-8000-000000000010/runs/00000000-0000-4000-8000-000000000b01"
}With --wait, the CLI polls the run every 3 seconds (set
TUTORFLOW_POLL_INTERVAL_MS to change it) and prints progress to stderr in text
mode. It rides out up to five transient failures in a row (network errors, 429,
5xx). When the run completes, JSON mode prints the run and the resource it made:
{
"run": {
"runId": "00000000-0000-4000-8000-000000000b01",
"kind": "course",
"status": "completed",
"resourceId": "00000000-0000-4000-8000-000000000201",
"creditsCharged": 18
},
"resource": {
"id": "00000000-0000-4000-8000-000000000201",
"title": "Beginner Python for analysts",
"editorUrl": "https://...",
"publicUrl": "https://..."
}
}The run and resource are abridged here. resource is null when the follow-up
read fails; the run is still reported. Text mode prints runId, status,
creditsCharged, resourceId, title, editorUrl, and publicUrl.
If the run fails, the command exits 1 with ERUNFAILED; for a course the hint
names tutorflow run resume <runId>. If --timeout passes first, it exits 1 with
ETIMEOUT, and the run keeps going: pick it up with tutorflow run wait <runId>.
See Generation Runs for the run fields, stages, and time limits.
Follow Generation Runs
| Command | What it does |
|---|---|
tutorflow run list | Lists the classroom's runs, newest first. --kind course|slide|test|module, --status queued|running|completed|failed, -l, --limit <n>, --cursor <cursor>. |
tutorflow run get <runId> | Prints a run. |
tutorflow run wait <runId> | Waits like generate --wait and prints the same result. Takes --timeout <seconds> (default 900). |
tutorflow run resume <runId> | Resumes a failed course run. The new run writes only the unfinished lessons. Takes --idempotency-key. |
tutorflow --json run wait 00000000-0000-4000-8000-000000000b01 --timeout 1800Videos
tutorflow video create
Creates a video. Each --scene <script> adds a scene with that narration script,
in order. With scenes, the command prints the video after the last scene is added;
without, it prints the created video.
tutorflow video create --title "How rainbows form" \
--scene "Sunlight looks white, but it holds every color." \
--scene "Raindrops bend each color by a different amount."| Flag | Meaning |
|---|---|
--title <title> | Required. |
--description <text> | Description. |
--visibility <visibility> | PUBLIC, UNLISTED, or PRIVATE. |
--scene <script> | Repeatable. Adds a scene with this script. |
--idempotency-key <key> | Sent with the create call only. |
If a scene fails, the video still exists. The error names the videoId and how
many scenes were added, and the hint shows the video scene add command for the
rest.
Scenes
| Command | What it does |
|---|---|
tutorflow video scene add <videoId> | Adds a scene at the end, or after --after <sceneId>, and sets the fields you pass. |
tutorflow video scene update <videoId> <sceneId> | Changes a scene. Pass at least one field. |
tutorflow video scene delete <videoId> <sceneId> | Deletes a scene. Takes -y, --yes. |
add and update take --script <text> (narration), --display-text <text>
(text on screen), and --duration <seconds>.
Narrate and render
| Command | What it does |
|---|---|
tutorflow video narrate <videoId> | Generates narration for every scene without one, or only for --scene <sceneId>. 1 credit per scene. Takes --idempotency-key. |
tutorflow video render <videoId> | Starts an mp4 render. --generate-missing-narration narrates scenes without narration first. -w, --wait and --timeout <seconds> (default 1800). |
tutorflow video render-status <videoId> | Prints the render status and, once rendered, the video URL. |
tutorflow video render-cancel <videoId> | Cancels a running render. |
tutorflow video render 00000000-0000-4000-8000-000000000601 --generate-missing-narration --waitWith --wait, the command prints the final render status once renderStatus is
COMPLETED. A FAILED render, or one that goes back to IDLE after rendering
(cancelled), exits 1 with ERUNFAILED. Completion also arrives as the
video.render.completed webhook. See Video Render.
Games and Simulations
game and simulation share one flow: create, plan with brief, then build, and
revise later.
| Command | What it does |
|---|---|
create | Creates an empty game or simulation. --title <title> (required), --description <text>, --visibility PUBLIC|PRIVATE (default PRIVATE), --idempotency-key. |
brief <id> | Plans it (1 credit). --reference <markdown> passes reference material. |
build <id> | Builds it from the plan. 40 credits for a game; 20 for a 2D simulation, 30 for 3D. |
revise <id> | Revises it. --feedback <text> is required. Priced like build. |
status <id> | Prints the running step (active) and how the last one ended (last). |
brief, build, and revise take -w, --wait, --timeout <seconds> (default
900), and --idempotency-key. The CLI always asks the API for the asynchronous
202 answer, not the event stream.
tutorflow game create --title "Fraction match"
tutorflow game brief 00000000-0000-4000-8000-000000000701 --wait
tutorflow game build 00000000-0000-4000-8000-000000000701 --wait --timeout 600With --wait, the command prints the { active, last } status once the step ends.
A failed step exits 1 with ERUNFAILED. See Games
and Simulations.
Evaluate Learner Answers
tutorflow evaluate
Grades one answer and waits for the result (1 credit).
tutorflow evaluate --type open-ended \
--question "Why is the sky blue?" \
--student-answer "Air scatters blue light more." \
--learner-id student-7 --concept-tags light,atmosphere| Flag | Request field |
|---|---|
-t, --type <type> | evaluationType: exact, rubric_short_answer, or open_ended. Aliases: rubric, open-ended. |
-q, --question <text> | questionText |
-a, --student-answer <text> | learnerAnswer |
-e, --expected-answer <text> | referenceAnswer. Required for exact. |
--rubric-json <json> | rubric. Required for rubric_short_answer. |
--max-score <n> | maxScore |
-l, --language <lang> | language of the feedback. Default en. |
--learner-id <id> | learnerExternalId: your id for the learner |
--concept-tags <list> | conceptTags, comma-separated |
--subject <subject> | subject |
--idempotency-key <key> | Idempotency-Key header |
On a terminal the CLI asks for a missing type, question, answer, or expected answer.
tutorflow evaluation
| Command | What it does |
|---|---|
tutorflow evaluation list | Lists the classroom's evaluations, newest first. -l, --limit <n>, --cursor, --learner-id <id>, --status <status>, --type <type>. |
tutorflow evaluation get <evaluationId> | Prints one evaluation. |
tutorflow evaluation concepts | Lists the concepts evaluations have tagged in the classroom. |
tutorflow evaluation mastery <learnerId> | Prints a learner's mastery per concept. learnerId is the --learner-id you graded with. |
Learners
Learner commands need a live key; a test key gets 403 content_sandbox_unsupported.
| Command | What it does |
|---|---|
tutorflow learner list | Lists learners. -l, --limit <n>, --cursor, --status <status>, -q, --query <text> (name or email). |
tutorflow learner get <learnerId> | Prints a learner. |
tutorflow learner progress <learnerId> | Prints the learner's course progress. |
tutorflow learner invite | Adds a learner by email. --email <email> (required), --name <name>, --locale <locale> (default en), and repeatable --course <courseId> and --test <testId>. |
tutorflow learner remove <learnerId> | Removes the learner from the classroom. Takes -y, --yes. |
tutorflow learner invite --email learner@example.com --course 00000000-0000-4000-8000-000000000201An organization member joins at once; anyone else gets an invitation. See Learners.
Webhooks
Webhook commands call /v1/content/webhooks and need a key with the
webhooks:manage scope.
| Command | What it does |
|---|---|
tutorflow webhook list | Lists endpoints. |
tutorflow webhook create | Creates an endpoint. --url <url> (required), one or more --event <event>, --mode live|test. The signing secret is shown once. |
tutorflow webhook get <webhookId> | Prints an endpoint. |
tutorflow webhook delete <webhookId> | Deletes an endpoint. Takes -y, --yes. |
tutorflow webhook test <webhookId> | Sends a webhook.ping event now. |
tutorflow webhook deliveries <webhookId> | Lists recent deliveries, newest first. |
tutorflow webhook rotate-secret <webhookId> | Replaces the signing secret and shows the new one once. |
tutorflow webhook create --url https://example.com/hooks/tutorflow \
--event course.generation.completed --event video.render.completedTest endpoints receive the events of test keys. See Webhooks.
Classrooms and Credits
| Command | What it does |
|---|---|
tutorflow classroom list | Lists the classrooms the key can reach. Text mode shows ID, name, slug, and whether it is the sandbox. |
tutorflow credits balance | Prints the AI Credit balance the key spends from. |
tutorflow credits history | Lists charges, refunds, and adjustments, newest first. -l, --limit <n> (default 20, max 100), --cursor, --from <iso>, --to <iso>, --type <type>. |
A test key works in the sandbox classroom and spends nothing. See Test Mode.