veedio-cli
Videos from any terminal
A thin client over the public API for shells, cron jobs, CI and terminal agents. Zero dependencies, Node 20 or newer. Everything it does, the API does — it exists so that a shell script does not have to hold a JSON payload together with quotes.
- install from a checkout
- Node 20+
- zero dependencies
The npm package is not published yet, so install it from a clone of the repository. There are no dependencies to resolve, so this is a copy and a symlink. npm install -g veedio-cli will be the install once the package is on the registry; it is not there today.
Install
git clone https://github.com/milletgilmore/veedio.git
npm install -g ./veedio/packages/cli # puts `veedio` on your PATH
export VEEDIO_API_KEY=vd_live_... # Settings -> API keys
veedio create --prompt "why indie launches fail" --wait --jsonCommands
| Command | What it does |
|---|---|
| veedio create | Start a generation. |
| veedio status <id> | Where a video has got to, and its scenes. |
| veedio list | Your videos, newest first. |
| veedio publish <id> | Publish a finished video to connected accounts. |
| veedio estimate | What a generation costs, before spending it. |
| veedio me | Whose key this is, their plan and their balance. |
create
Exactly one source, and it is the source that picks the workflow.
Sources
veedio create --prompt "a 30 second explainer on compound interest" # prompt-to-video
veedio create --script "Here is the script, word for word." # script-to-video
veedio create --idea "morning routines" # idea-to-video
veedio create --url https://example.com/blog/post # article-to-video- --title <text>stringdefault Untitled video
- Title for the video.
- --voice <id>enumdefault rachel
- Which voice narrates it.
- rachelwarm
- adamdeep
- bellabright
- joshcasual
- ellisoft
- --captions <id>enumdefault bold-center
- Caption style, burned in.
- bold-centerbig centered
- highlightword by word
- subtlesmall
- noneoff
- --music <id>enumdefault uplifting
- The bed under the voice.
- upliftingbright
- loficalm
- cinematictense
- trappunchy
- nonesilence
- --style <id>enumdefault cinematic
- How every frame looks.
- cinematicfilm still
- 3drender
- animekey visual
- documentaryphotoreal
- retro80s film
- --aspect <id>enumdefault 9:16
- Output shape.
- 9:16vertical
- 1:1square
- 16:9landscape
- --waitflag
- Poll until the video is ready or failed, up to 20 minutes.
- --jsonflag
- JSON on stdout, progress on stderr.
Generation is asynchronous and takes a few minutes. Without --wait the command prints the video id and returns; with it, it blocks and prints the finished MP4's URL.
publish
bash
veedio publish 8f1c0f2e-... --platforms tiktok,youtube --caption "new one"The video has to be ready and the platform has to be connected in Settings first. Publishing costs no credits. A video already live on a platform is refused, so the command is safe to retry after a dropped connection; --force posts again deliberately.
estimate
bash
veedio estimate # the default quote, which is what the deposit assumes
veedio estimate --scenes 8 # for a script you know the shape ofA generation costs 3 credits plus a charge per scene that follows what fills it: 2 for a still or stock footage, 13 for a scene the video model sets in motion. A 5-scene short is 13 credits with stills and 68 animated.
Scripting it
--json writes JSON and only JSON to stdout; everything else goes to stderr. So this composes.
bash
url=$(veedio create --prompt "$BRIEF" --wait --json | jq -r .videoUrl)- Agent notes.
--jsonis a contract: nothing but the JSON document reaches stdout, errors arrive on stderr as{ error: { code, message } }, and--waitpolls for up to 20 minutes before giving up. - Exit codes are meaningful, so a shell agent can branch without parsing prose: 0 worked, 1 the request or the generation failed, 2 the command line was wrong.
| 0 | It worked. |
|---|---|
| 1 | The request failed, or the generation did. |
| 2 | The command line was wrong. |
A one-a-day channel, as a cron line:
crontab
0 9 * * * veedio create --idea "$(shuf -n1 ~/topics.txt)" --wait --json \
| jq -r .id | xargs -I{} veedio publish {} --platforms tiktokEnvironment
- VEEDIO_API_KEYstringRequired
- Create one in Settings → API keys. Shown once.
- VEEDIO_API_URLstringdefault https://www.veedio.co
- Point it at a local dev server to test against one.
What it cannot do
The CLI is a client, so it inherits every limit of the API.
- No file uploads over the wire — the CLI posts text and URLs, so captioning footage you already have and repurposing a podcast recording are out. A PDF works as a source if you host it:
--url https://example.com/report.pdfis read as a document. - No voice cloning and no face swap. Narration comes from the five stock voices.
- Fewer flags than the API has fields. The opening photo (
photoUrl), the narration language, the presenter avatar and the video length have no flag yet, so a video created from the terminal comes out at the default 60 seconds in English.POST /api/v1/videostakes all four today. - Short-form, not long-form: 30, 60, 90 or 180 seconds, free accounts up to 60 and paid plans to 180. The product narrates in 29 languages; the CLI cannot pick one yet.
- `--url` is fetched and read, not passed on as text: articles, YouTube, X, Reddit, TikTok, Instagram, LinkedIn and PDFs each have their own reader.