TubeTube CLI: make AI videos from your terminal
Updated · CLI v1.0.0 · API v1
On this page
InstallationAuthenticationQuickstartGlobal flagsCommandscreatelistgetwatchdownloadassetsdeletestyles, engines, optionswhoami, creditsShell completionRecipesREST APIError codesEnvironmentFAQInstallation
Nothing to install: npx fetches the latest version each time it runs. Install it globally if you use it daily.
npx tubetube --help
# or, to keep it around
npm install -g tubetube
tubetube versionNode.js 18.17 or newer is the only requirement, on macOS, Linux or Windows. The package has zero dependencies, so nothing else lands in your node_modules.
Authentication
Create a key on your Account page, then log in once.
tubetube login # asks for the key and verifies it
tubetube login --key tt_live_… # non-interactive
tubetube whoami # account, plan, credits
tubetube logout # forget the stored keyThe key is stored in ~/.tubetube/config.json with owner-only permissions. It is shown in full only once, at creation: the server keeps a SHA-256 hash of it, never the key itself. Revoking a key on the Account page takes effect immediately.
TUBETUBE_API_KEY as a secret instead of running login. It takes precedence over the stored key and nothing is written to the disk of the runner.A key can create, read, download and delete videos on your account. It can never use operator-only settings such as automatic publishing to Google Drive, even on an admin account.
Quickstart
npx tubetube login
npx tubetube styles # pick a look
npx tubetube create --title "Counting song" \
--style "Pixar-style 3D" \
--lyrics-file song.txt \
--scene-duration 5 \
--dry-run # what would it cost?
npx tubetube create --title "Counting song" \
--style "Pixar-style 3D" \
--lyrics-file song.txt \
--scene-duration 5 \
--wait --download # launch, follow, save the mp4Global flags
| Flag | Meaning |
|---|---|
-o, --output <fmt> | text (default) or json. Accepted by every command. |
--json | Shorthand for -o json. |
-h, --help | Help for the command. tubetube help <command> works too. |
Every command exits with a non-zero status on failure, including watch when the generation itself fails, so a script stops on its own. Unknown options are rejected rather than ignored: a typo cannot silently change your settings and waste credits.
Commands
create
Builds the parameters, asks the server for a price, then launches. Credits are reserved at launch and whatever is not produced is refunded when the job ends.
# Price it, launch nothing
tubetube create --title "My song" --style "Pixar-style 3D" \
--lyrics-file song.txt --dry-run
# Launch and follow until the file is on disk
tubetube create --title "My song" --style "Pixar-style 3D" \
--lyrics-file song.txt --wait --download
# Same recipe as a previous video, new words
tubetube create --from a1b2c3d4 --lyrics-file new-song.txt --wait
# Text from stdin
cat script.txt | tubetube create --type narration --style "Watercolor storybook"The text comes from --lyrics, --lyrics-file, stdin, or the video referenced by --from. The visual style is required: pass --style with a preset name or --style-text with your own prompt.
| Option | Meaning |
|---|---|
--title <text> | Title of the video. Defaults to the first non-empty line of the text. |
--type <kind> | song (default), narration or dialogue. |
--format <ratio> | 16:9 (default) or 9:16 for shorts. |
--lyrics <text> | Lyrics or script, inline. |
--lyrics-file <file> | Read the text from a file. You can also pipe it on stdin. |
--style <name> | Visual style by name, fuzzy-matched. See tubetube styles. |
--style-text <prompt> | Free-form visual style instead of a preset. |
--engine <id> | Video engine. See tubetube engines. |
--scene-duration <s> | Seconds per scene. 5 keeps the visuals on the beat; 10 makes them lag behind fast lyrics. Allowed values depend on the engine. |
--duration <s> | Target length of the finished video, in seconds. |
--audio-source <src> | suno, elevenlabs, elevenlabs_tts, upload or upload_cover. |
--music-style <text> | Musical direction for the generated song. |
--voice <id> | ElevenLabs voice id for narration. |
--image-model <id> | Image model. See tubetube options. |
--upscale <mode> | none, 2k or 4k. |
--motion <style> | Motion style, e.g. natural, stop_motion, anime. |
--language <code> | Spoken language for dialogue videos. |
--scene-instructions <t> | Manual scene cutting instructions. |
--no-sync | Disable word-by-word visual syncing. |
--bg-sound | Add a background ambience track. |
--from <video-id> | Reuse every setting of an existing video. |
--params-file <file> | Full params JSON, for advanced use. |
--tags <a,b,c> | Comma-separated tags. |
--description <text> | Video description. |
--dry-run | Print the credit cost and stop. |
--wait | Follow progress until the video is ready. |
--download | With --wait, download the result when it finishes. |
--output-dir <dir> | With --download, where to save. |
list
Your videos, newest first. Ids are shortened to their first 8 characters.
tubetube list
tubetube list --status processing
tubetube list --limit 50 -o json
tubetube list --cursor 2026-08-30T20:36:23Z # next page| Option | Meaning |
|---|---|
--status <s> | queued, processing, completed, failed or canceled. |
--limit <n> | Rows per page, up to 100. Default 20. |
--cursor <iso> | Pagination cursor printed at the end of the previous page. |
get
Everything about one video: type, style, engine, credits, every pipeline step with its state, and a summary of the files produced.
tubetube get a1b2c3d4
tubetube get a1b2c3d4 -o json | jq .stepswatch
Polls until the video reaches a final state, drawing a progress bar with the step currently running. In -o json mode it prints one JSON object per poll, which is what you want in a log.
tubetube watch a1b2c3d4
tubetube watch a1b2c3d4 --interval 15 # seconds between polls, minimum 2download
Downloads the finished files. The main video is renamed after the video title, so several downloads can live in the same folder.
tubetube download a1b2c3d4 # the finished video
tubetube download a1b2c3d4 --all --output-dir ./out # every scene, image and audio file
tubetube download a1b2c3d4 --asset archive # the zip of all assets
tubetube download a1b2c3d4 --url-only # print signed URLs instead| Option | Meaning |
|---|---|
--asset <what> | video (default), archive or all. |
--all | Same as --asset all. |
--output-dir <dir> | Where to save. Created if needed. Default: current folder. |
--url-only | Print signed URLs, valid one hour, instead of downloading. |
Downloads made without a subscription carry a small tubetube.io mark. Subscribing later makes every video you have already made downloadable clean.
assets
Lists every file of a video with its kind, scene number, size and duration.
tubetube assets a1b2c3d4
tubetube assets a1b2c3d4 -o json | jq '[.assets[] | select(.kind=="scene_video")] | length'delete
Permanent: the files are removed from storage and the record is dropped. Refused while a job is still running.
tubetube delete a1b2c3d4 # asks for confirmation
tubetube delete a1b2c3d4 --yes # no prompt, for scriptsstyles, engines, options
The accepted values, straight from the server, so you never have to guess an identifier like veo31fast720.
tubetube styles # featured and custom styles
tubetube styles --all # the full catalogue
tubetube engines # engines and the scene durations each one allows
tubetube options -o json # everything, machine-readablewhoami, credits
tubetube whoami # email, plan, balance, watermark status, key source
tubetube credits # just the number, handy in a shell promptShell completion
# zsh — add to ~/.zshrc
source <(tubetube completion zsh)
# bash — add to ~/.bashrc
source <(tubetube completion bash)
# fish
tubetube completion fish > ~/.config/fish/completions/tubetube.fishRecipes
One video a day, from a cron job
#!/usr/bin/env bash
set -euo pipefail
export TUBETUBE_API_KEY="$(cat ~/.secrets/tubetube)"
id=$(tubetube create --title "Daily story $(date +%F)" \
--type narration --style "Watercolor storybook" \
--lyrics-file "$HOME/stories/$(date +%F).txt" \
-o json | jq -r .video.id)
tubetube watch "$id" # exits non-zero if it fails
tubetube download "$id" --output-dir ~/outBatch: same recipe, many texts
for f in lyrics/*.txt; do
tubetube create --from a1b2c3d4 --lyrics-file "$f" \
--title "$(basename "$f" .txt)" -o json | jq -r .video.id
done > ids.txt
xargs -a ids.txt -I{} tubetube watch {}Check the cost before spending
tubetube create --title x --style "Pixar-style 3D" \
--lyrics-file song.txt --dry-run -o json | jq '{credits, scenes, balance: .quote.balance}'REST API
The CLI is a thin client: every command is one HTTP call. Authenticate with Authorization: Bearer tt_live_…. Responses are JSON; errors always look like { "error": { "code": "…", "message": "…" } }.
| Endpoint | Purpose |
|---|---|
GET /api/v1/me | Account, plan, credit balance, whether downloads are watermark-free. |
GET /api/v1/videos | List videos. Query: status, limit (max 100), cursor. |
POST /api/v1/videos | Create and launch. Body: title, description, tags, params. |
GET /api/v1/videos/{id} | Status, progress, steps, credits, files. |
DELETE /api/v1/videos/{id} | Delete permanently. 409 while a job is running. |
GET /api/v1/videos/{id}/download | Signed URLs. Query: asset=video|archive|all. |
POST /api/v1/quote | Price a video without launching it. |
GET /api/v1/options | Styles, engines with their scene durations, image models. |
# List videos
curl -s https://www.tubetube.io/api/v1/videos \
-H "Authorization: Bearer $TUBETUBE_API_KEY"
# Price a video without launching it
curl -s https://www.tubetube.io/api/v1/quote \
-H "Authorization: Bearer $TUBETUBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"params":{"contentType":"song","format":"9:16",
"lyrics":"Twinkle twinkle little star, how I wonder what you are",
"imageStyle":"3D CGI in the style of Pixar, rounded expressive characters",
"audioSource":"suno"}}'
# Create and launch
curl -s -X POST https://www.tubetube.io/api/v1/videos \
-H "Authorization: Bearer $TUBETUBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"My song","params":{ … }}'GET /api/v1/options returns the full prompt of every style, which is what you put in params.imageStyle. params accepts the same fields as the web wizard; anything you omit takes its default server-side.
Error codes
| Code | Meaning |
|---|---|
missing_api_key | No Authorization header. 401. |
invalid_api_key | Unknown, malformed or revoked key. 401. |
invalid_json | The body is not valid JSON. 400. |
invalid_body | Parameters rejected by validation; details lists the fields. 400. |
invalid_reference_images | A reference image path does not belong to your account. 400. |
insufficient_credits | Not enough credits; needed and balance are included. 402. |
insufficient_scope | The key does not carry the required right. 403. |
not_found | No video with this id on your account. 404. |
asset_not_ready | The requested file does not exist yet. 404. |
job_running | The video is still generating and cannot be deleted. 409. |
pricing_unavailable | The pricing table could not be read; retry. 503. |
The CLI turns these into one-line messages and a non-zero exit status. With -o json it prints the error object instead, so a script can branch on .error.code.
Environment
| Variable | Effect |
|---|---|
TUBETUBE_API_KEY | Use this key instead of the stored one. Nothing is written to disk. |
TUBETUBE_API_URL | Point the CLI at another instance. Defaults to https://www.tubetube.io. |
NO_COLOR | Disable colours. Colours are also off when the output is piped. |
Frequently asked questions
Do I need to install anything?
No. npx tubetube <command> runs the latest version straight away, and it has no dependencies. Node.js 18.17 or newer is the only requirement. npm install -g tubetube keeps it around if you prefer.
How do I authenticate?
Create an API key on your Account page, then run tubetube login and paste it. The key is stored in ~/.tubetube/config.json, readable by you only. In CI, set the TUBETUBE_API_KEY environment variable instead and nothing is written to disk.
Does the CLI cost extra?
No. It spends the same credits as the web app, at the same rate. tubetube create --dry-run prints the exact cost before you launch anything, and whatever a job does not produce is refunded to your balance.
Can I use it in a CI pipeline?
Yes. Every command accepts -o json and exits non-zero on failure, including when a generation fails. Set TUBETUBE_API_KEY as a secret, then chain tubetube create -o json, tubetube watch and tubetube download.
Are downloads watermarked?
On a free account, yes: downloads carry a small tubetube.io mark, exactly as in the web app. Any paid plan exports clean files, and subscribing later makes every video you have already made downloadable clean again.
Can an API key do everything my account can?
Almost. A key can create, read, download and delete videos. It can never use the operator-only settings such as automatic publishing to Google Drive, even on an admin account, so a leaked key cannot publish anything in your name.
What happens if I lose a key?
Revoke it on the Account page; it stops working immediately. Keys are stored as a SHA-256 hash, so nobody, including us, can read an existing key. Create a new one and run tubetube login again.
Try it in one line
Sign up, create a key, and your first video is a single command away. New accounts get 1,000 credits, valid 7 days, no card required.
npx tubetube login && npx tubetube stylesCreate a free account