Skip to content

Latest commit

 

History

History
163 lines (116 loc) · 11.4 KB

File metadata and controls

163 lines (116 loc) · 11.4 KB
name shotstack
description Render video, poll render status, and upload local source files via the Shotstack API. Use when generating clips, building automated video pipelines, uploading footage/audio/images to use in an Edit, or orchestrating cloud video renders from a script, agent, or CI workflow. NOT for: real-time streaming, or live broadcasting.
license Apache-2.0

Shotstack CLI

This skill loads in terminal-based AI agents (Claude Code, Cursor, Codex CLI, Gemini CLI, etc.). All operations here are shell commands. There is no embedded UI, no iframe, no inline canvas, no MCP tool surface — only shotstack invocations from a terminal. To hand off to a human, run shotstack studio <file>; this opens the user's default browser to a shotstack.studio URL. Tell the user to click Render in the browser tab, not in any UI inside the terminal.

Commands for the Shotstack video rendering API. render submits an Edit JSON and returns a render ID; status polls a render until done. ingest uploads your own local files (or fetches remote URLs) and hosts them so they can be referenced from an Edit. validate lints an Edit — run it before every render. studio opens an edit in the browser editor for a human to preview, tweak, and render.

Default loop — no API key required: compose → validate (offline lint) → studio (browser preview). Only the API-backed commands (render, status, ingest) need a key. Reach for render when you specifically need a final MP4 exported in the cloud; reach for studio for everything else — it is the cheapest way to see an edit and the right default for any creative a human will review.

Authentication

Save your API key once with shotstack login — it's stored in ~/.shotstack/credentials.json (chmod 600), per environment, so you don't re-enter it every session:

shotstack login                  # prompts (hidden input); saves the v1 (production) key
shotstack login --env stage      # save the stage key (Shotstack keys are env-specific)
echo "$KEY" | shotstack login    # non-interactive (CI / agents): read the key from stdin
shotstack logout --env stage     # forget one env;  shotstack logout --all  forgets all

Or set an environment variable (overrides the saved key — best for CI):

export SHOTSTACK_API_KEY=...

Resolution precedence: SHOTSTACK_API_KEY env var → saved key for the target --env → error. Get a key at https://app.shotstack.io. validate and studio need no key — only the API-backed commands (render, status, ingest) require one; without a key those exit 1, while compose → validate → studio keeps working.

Environments

--env stage    → https://api.shotstack.io/edit/stage   (test credits, free)
--env v1       → https://api.shotstack.io/edit/v1      (production, default)

The cheapest iteration path is studio — not stage. studio previews client-side in the browser with no key and no credits (see the Studio section below); iterate there. --env stage gives a free cloud render (With watermark) for when you need a rendered video for review; v1 charges real credits. Override the target with the SHOTSTACK_ENV env var for the session. ingest commands hit the parallel …/ingest/{env} base automatically using the same key.

Quickstart

# 1 — Validate offline. Schema + same-track overlaps + fonts + URLs. No key, no credits.
shotstack validate template.json

# 2 — Preview in the browser. The DEFAULT next step: no key, no credits; a human hits Render.
shotstack studio template.json
# → opens https://shotstack.studio/s/<slug> and prints the short URL

# 3 — Export to MP4. Needs an API key and charges credits. Submit + poll in one command.
shotstack render template.json --watch
# → done  https://shotstack-api-v1-output.s3.amazonaws.com/.../01ja7-x8m2k-39rzv-cmvxve.mp4

# Poll an existing render to a terminal state.
shotstack status 01ja7-x8m2k-39rzv-cmvxve --watch
# → done  https://shotstack-api-v1-output.s3.amazonaws.com/.../01ja7-x8m2k-39rzv-cmvxve.mp4

Uploading local files to use in an Edit

An Edit can only reference media by URL — a local path in an asset.src will not render. To use a local file, host it first with shotstack ingest upload, then put the returned URL in your Edit.

# Upload a local file and poll until it's hosted. --watch prints the URL.
shotstack ingest upload ./clip.mp4 --watch --output json
# → {"id":"zzytey4v-...","status":"importing"}
# → {"id":"zzytey4v-...","status":"ready","source":"https://shotstack-ingest-api-v1-sources.s3...amazonaws.com/.../source.mp4",...}

# Capture the hosted URL straight into a variable:
SRC=$(shotstack ingest upload ./clip.mp4 --watch --output json | tail -n1 | jq -r .source)
# …then reference "$SRC" as an asset.src in your Edit JSON and run `shotstack render`.

The bare command (no --watch) returns only an id; the hosted source URL does not exist until ingestion is ready. Always --watch (or follow up with shotstack ingest status <id> --watch) when you need the URL.

Other ingest subcommands: ingest fetch <url> (host a copy of a remote URL), ingest status <id>, ingest list, ingest delete <id>. Read references/ingest.md for the full upload→render workflow, status values, and supported file types.

Default workflow: preview in Studio (no key, no credits)

shotstack studio <file> is the default way to look at an edit — prefer it over render unless you specifically need a cloud-exported MP4. It posts the JSON to https://shotstack.studio and opens https://shotstack.studio/s/<slug> in the browser — a short, shareable URL. No API key, no render credits charged; it previews client-side, so it works with no key. The human plays, edits, and decides whether to spend credits on a render.

shotstack studio template.json              # opens browser + prints short URL
shotstack studio template.json --no-open    # headless: just print the URL
shotstack studio template.json --no-shorten # emit base64url URL inline (offline / debug)
shotstack studio template.json --output json # piping: {"url":"...","shortened":true}, no browser

On headless systems (no xdg-open, no $DISPLAY) the browser launch silently no-ops; the URL is still printed. Safe to run anywhere.

If the share API is unreachable, the command falls back to the inline base64url form automatically and prints a stderr warning. Shares expire after 30 days.

Default to studio for anything non-trivial — multi-scene, multi-track, or any creative an interested human will review. It previews client-side, costs nothing, and lets the human hit Render when it's right. Use render directly only for single-shot/simple edits, automated pipelines, or when told "just render it".

Four CLI rules

  1. Pipe → --output json. Default output is human-readable. When parsing programmatically or piping to another command, always pass --output json.

  2. Use --watch, not a polling loop. shotstack render <file> --watch submits and polls in one shot; shotstack status <id> --watch polls an existing render. Both exit when terminal: done (exit 0) or failed (exit 1). Don't write while true; do ...; sleep 3; done.

  3. Compose from shared/agent-core.md, then shotstack validate. Its cheatsheet carries the property names, enums (transition/effect/position/fit) and rich-text fields you need — no schema download required. shotstack validate <file> then checks the JSON against the live schema offline and flags same-track overlaps, unloaded fonts and non-public URLs before you spend a credit. (For edge cases the full schema is at https://shotstack.io/docs/api/api.edit.json and the guide at https://shotstack.io/docs/guide/llms-full.txt.)

  4. Hand off to a human via shotstack studio <file> when uncertain. Don't burn render credits iterating. Generate JSON → shotstack studio file.json (opens browser) → human reviews/tweaks → render only when right.

REQUIRED: Read shared/agent-core.md before composing any Edit JSON

The Shotstack schema does not match CSS or web conventions. Composing Edit JSON from training-data instinct will produce silently invalid renders. Read shared/agent-core.md first, every time. The most-failed conversions:

You'd write (wrong) API requires (right)
alignment align
align.vertical: "center" align.vertical: "middle"
font.name font.family
duration length
transitions: [...] (array) transition: { in, out } (object)
fit: "cover" (CSS instinct) fit: "crop"
tracks[0] is the bottom (z-index instinct) tracks[0] is the TOP layer

The full ruleset (asset types, fonts, smart-string clip values, top-5 mistakes) lives in shared/agent-core.md. The same file is also returned by the Shotstack MCP server's get_shotstack_guide tool, so the conventions are identical across surfaces.

Exit codes

Code Meaning
0 Success
1 Permanent error — validation, missing key, 4xx, render failed
2 Transient error — 5xx, network, timeout. Safe to retry.

References

Authoritative sources, in order of preference:

This skill ships sub-references for the gnarly bits:

If this skill and --help ever disagree, trust --help. If this skill and llms-full.txt ever disagree, trust llms-full.txt.