You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+13-12Lines changed: 13 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Shotstack CLI
2
2
3
-
Command-line interface for the [Shotstack](https://shotstack.io) video rendering API. Built for humans and AI coding agents.
3
+
Command-line interface for the [Shotstack](https://shotstack.io) video rendering API. Built for humans and AI agents.
4
4
5
5
```sh
6
6
shotstack render template.json
@@ -16,7 +16,7 @@ npm i -g @shotstack/cli
16
16
# one-shot via npx
17
17
npx @shotstack/cli render template.json
18
18
19
-
# one-shot via bun (~100x faster than npx for cached invocations)
19
+
# one-shot via bun
20
20
bunx @shotstack/cli render template.json
21
21
```
22
22
@@ -27,7 +27,7 @@ All three install paths use the same `@shotstack/cli` package on npm.
27
27
Set your API key as an environment variable:
28
28
29
29
```sh
30
-
export SHOTSTACK_API_KEY=sk_...
30
+
export SHOTSTACK_API_KEY=...
31
31
```
32
32
33
33
Get a key at <https://shotstack.io>.
@@ -69,23 +69,24 @@ shotstack status 01ja7-x8m2k-... --watch
69
69
shotstack status 01ja7-x8m2k-... --output json
70
70
```
71
71
72
-
### `shotstack preview <file>`
72
+
### `shotstack studio <file>`
73
73
74
-
Opens a `shotstack.studio` URL that loads the Edit JSON directly into the browser-based editor. No API call, no key, no charge — pure client-side encoding via the URL hash. Use it to hand a generated edit off to a human for review or quick tweaks before rendering.
74
+
Opens a `shotstack.studio` URL that loads the Edit JSON in the browser-based editor. By default, posts the JSON to the share API and emits a short URL like `https://shotstack.studio/s/abc12345` — clean, shareable, expires in 30 days. Falls back to inline base64url encoding if the share API is unreachable.
75
+
76
+
No render API key required; no render credits charged. Use to hand a generated edit off to a human for review or quick tweaks before rendering.
75
77
76
78
```sh
77
-
shotstack preview my-template.json
78
-
# → opens browser silently
79
+
shotstack studio my-template.json
80
+
# → opens browser silently with https://shotstack.studio/s/<slug>
79
81
80
-
shotstack preview my-template.json --copy # also copies URL to clipboard
81
-
shotstack preview my-template.json --no-open # print URL, don't open browser
82
-
shotstack preview my-template.json --output json # emit {"url":"..."} on stdout
82
+
shotstack studio my-template.json --copy # also copies URL to clipboard
83
+
shotstack studio my-template.json --no-open # print URL, don't open browser
shotstack studio my-template.json --output json # emit {"url":"...","shortened":true} on stdout
83
86
```
84
87
85
88
When a browser can be launched, the command is silent — the URL only opens in the browser. On a headless server (no `$DISPLAY`, no `xdg-open`), the URL is printed to stdout instead so you can copy it elsewhere.
86
89
87
-
Templates whose encoded URL exceeds ~6KB print a stderr warning. Browser URL limits vary; if you regularly exceed it, host the JSON publicly and link to it via `https://shotstack.studio/#src=<https-url>`.
88
-
89
90
### `shotstack feedback`
90
91
91
92
Opens a pre-filled GitHub issue with a sanitised dossier of your last 5 CLI invocations (render IDs, errors, exit codes). API keys and signed URLs are stripped at write time. You review and submit in your browser; nothing is transmitted automatically. Inspect the log at `~/.shotstack/log.jsonl`.
Copy file name to clipboardExpand all lines: SKILL.md
+10-7Lines changed: 10 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,16 +47,19 @@ shotstack status 01ja7-x8m2k-39rzv-cmvxve --watch
47
47
48
48
## Hand-off to a human before rendering
49
49
50
-
When a human is in the loop and may want to tweak the result, prefer **`shotstack preview <file>`** over `shotstack render`. By default it opens the browser to `https://shotstack.studio/#json=<base64url>`and prints the URL — the timeline loads directly into the browser-based editor. No API call, no key, no charge. The human can play, edit, and decide whether to render — saving credits when the AI's first attempt isn't quite right.
50
+
When a human is in the loop and may want to tweak the result, prefer **`shotstack studio <file>`** over `shotstack render`. By default it posts the JSON to the share API and opens `https://shotstack.studio/s/<slug>`in the browser — a short, shareable URL. No API key, no render credits charged. The human can play, edit, and decide whether to render.
51
51
52
52
```sh
53
-
shotstack preview template.json # opens browser + prints URL
54
-
shotstack preview template.json --no-open # headless: just print the URL
55
-
shotstack preview template.json --output json # piping: {"url":"..."}, no browser
53
+
shotstack studio template.json # opens browser + prints short URL
54
+
shotstack studio template.json --no-open # headless: just print the URL
shotstack studio template.json --output json # piping: {"url":"...","shortened":true}, no browser
56
57
```
57
58
58
59
On headless systems (no `xdg-open`, no `$DISPLAY`) the browser launch silently no-ops; the URL is still printed. Safe to run anywhere.
59
60
61
+
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.
62
+
60
63
Use `render` only when you're confident the JSON is final, or there's no human to review.
61
64
62
65
## Four CLI rules
@@ -67,7 +70,7 @@ Use `render` only when you're confident the JSON is final, or there's no human t
67
70
68
71
3.**Fetch the current schema and docs before generating Edit JSON.** The Shotstack API evolves; LLM training data is often stale. Pull <https://shotstack.io/docs/api/api.edit.json> and <https://shotstack.io/docs/guide/llms-full.txt> for the current schema and guides before composing an Edit from scratch.
69
72
70
-
4.**Hand off to a human via `preview` when uncertain.** Don't burn render credits iterating. Generate JSON → `shotstack preview` → human reviews/tweaks → render only when right.
73
+
4.**Hand off to a human via `studio` when uncertain.** Don't burn render credits iterating. Generate JSON → `shotstack studio` → human reviews/tweaks → render only when right.
71
74
72
75
## Authoring Edit JSON
73
76
@@ -100,8 +103,8 @@ Authoritative sources, in order of preference:
100
103
101
104
This skill ships sub-references for the gnarly bits:
102
105
103
-
-[`references/timeline.md`](references/timeline.md) — track layering, transitions, soundtrack vs audio
104
-
-[`references/rich-caption.md`](references/rich-caption.md) — sizing per resolution, default style, the 5 named presets, alias pattern
106
+
-[`references/timeline.md`](references/timeline.md) — track layering, transitions, background music via audio assets
107
+
-[`references/caption.md`](references/caption.md) — sizing per resolution, default style, the 5 named presets, alias pattern (asset type: `rich-caption`)
105
108
-[`references/svg.md`](references/svg.md) — required attrs, supported elements
106
109
-[`references/fonts.md`](references/fonts.md) — built-in fonts, Google Fonts URL pattern, custom-font workflow
107
110
-[`references/asset-library.md`](references/asset-library.md) — placeholder videos, images, music
Royalty-free tracks from the Unminus library, hosted on Shotstack's CDN. Suitable for `timeline.soundtrack`or as audio assets.
33
+
Royalty-free tracks from the Unminus library, hosted on Shotstack's CDN. Use as `audio` assets on a dedicated track. (`timeline.soundtrack`is deprecated — use `audio` with `length: "end"` instead.)
Copy file name to clipboardExpand all lines: references/caption.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,9 @@
1
-
# Rich-caption guide
1
+
# Caption guide
2
2
3
3
Word-level animated captions. The most failure-prone asset type — read this fully before composing one.
4
4
5
+
The asset type to use is **`rich-caption`** (Shotstack's name for word-level captions). The deprecated `caption` type still parses but produces inferior output — always use `rich-caption`.
6
+
5
7
## Contents
6
8
7
9
- The five named presets (use these verbatim when possible)
@@ -182,7 +184,7 @@ Rich-caption transcribes audio to produce word-level timing. Three ways to sourc
182
184
|`src` value | Behaviour |
183
185
|---|---|
184
186
|`alias://<name>`| Auto-transcribe a referenced audio/video/text-to-speech clip. Set `alias: "<name>"` on the source clip. **Preferred for sync.**|
185
-
| Subtitle file URL | Use existing `.srt`, `.vtt`, `.ttml`, or `.dfxp` file. No auto-transcription. |
187
+
| Subtitle file URL | Use existing `.srt`or `.vtt` file. No auto-transcription. |
186
188
| Audio/video file URL | Auto-transcribe a standalone media file. Use when there's no source clip on the timeline. |
187
189
188
190
The `alias://` form keeps the captions in sync with the source clip even when you change its `start` or `length`.
Copy file name to clipboardExpand all lines: references/fonts.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Fonts guide
2
2
3
-
The Shotstack render engine ships a small built-in font set; everything else must be loaded as a custom font via `timeline.fonts[]`. Per the [Shotstack docs](https://shotstack.io/docs/guide/architecting-an-application/rich-text/#custom-fonts), **prefer custom Google Fonts** for predictable rendering and full typographic range.
3
+
The Shotstack render engine ships a small built-in font set; everything else must be loaded as a custom font via `timeline.fonts[]`. Per the [Shotstack docs](https://shotstack.io/docs/guide/architecting-an-application/rich-text.md), **prefer custom Google Fonts** for predictable rendering and full typographic range.
Copy file name to clipboardExpand all lines: references/svg.md
+75-24Lines changed: 75 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -57,46 +57,97 @@ Standard fill, stroke, and transform attributes work: `fill`, `fill-opacity`, `s
57
57
58
58
Animated SVGs are not rendered — only the static initial frame is used.
59
59
60
-
## Worked example: lower-third bar
60
+
## Worked example: speech bubble for a testimonial
61
+
62
+
Speech bubbles are an example "rich-text can't do this" case — a rounded body with a tail pointing at the speaker requires a `<path>`. Pair the SVG bubble with a `rich-text` clip for the quote inside it.
Track order: text on top, semi-transparent black bar in the middle, video on the bottom.
140
+
Track order: rich-text quote on top, SVG bubble in the middle, talking-head video at the bottom. The `<path>``d` attribute draws a rounded rectangle (40px corner radius via `Q` curves) with a triangular tail at the bottom pointing toward the speaker. `stroke` gives the bubble an outline; `fill="#ffffff"` makes the body opaque.
141
+
142
+
Position the bubble with `offset` so the tail points at the subject's head. Adjust the path's tail coordinates (`L 160 220 L 170 180`) to point left/right/up depending on where the speaker is in frame.
143
+
144
+
Other patterns SVG is right for:
145
+
146
+
-**Tutorial highlight rings** — `<circle>` with `fill="none"` and a thick `stroke`, positioned over a UI element.
147
+
-**Brand badges** — small geometric lockups using `<rect>`/`<polygon>` plus `transform`.
148
+
-**Decorative dividers** — wavy lines or geometric frames between scenes.
149
+
150
+
If you only need a coloured rectangle behind text, **don't reach for SVG** — `rich-text` already supports `background.color`/`opacity`/`borderRadius`. Reserve SVG for shapes rich-text can't produce.
Copy file name to clipboardExpand all lines: references/timeline.md
+20-13Lines changed: 20 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Timeline conventions
2
2
3
-
Detailed guide to track layering, the soundtrack vs audio distinction, and `timeline.fonts[]`. Read this when building any non-trivial Edit JSON.
3
+
Detailed guide to track layering, background music (via `audio` assets — `timeline.soundtrack` is deprecated), and `timeline.fonts[]`. Read this when building any non-trivial Edit JSON.
4
4
5
5
## Contents
6
6
@@ -17,7 +17,7 @@ The single most counter-intuitive Shotstack convention.
17
17
18
18
`timeline.tracks` is an array. **The first element is the TOP layer (foreground); the last is the BOTTOM (background).** The order of the JSON array IS the visual stacking order, top-to-bottom.
19
19
20
-
Per the [official docs](https://shotstack.io/docs/guide/architecting-an-application/guidelines/):
20
+
Per the [official docs](https://shotstack.io/docs/guide/getting-started/core-concepts.md):
21
21
22
22
> Tracks are layered on top of each other in the same order they are added to the array with the top most track layered over the top of those below it.
23
23
@@ -72,25 +72,32 @@ If you put the video first and the captions last, the video covers the captions
72
72
| Title card on video | Title clip in early track, video in later track |
73
73
| Picture-in-picture | PiP video in early track, main video in later track |
74
74
75
-
## Soundtrack vs audio asset
75
+
## Background music: use `audio`, not `timeline.soundtrack`
76
76
77
-
Prefer `Audio` assets — they support custom timing, keyframes, and effects, and can do everything `timeline.soundtrack` can. Use `timeline.soundtrack` only when you want a single background track spanning the whole edit.
77
+
`timeline.soundtrack` is **deprecated**. Always use an `audio` asset on its own track with `length: "end"`. The audio asset path supports keyframes, custom timing, multi-clip mixing, and the full effect set; soundtrack does not.
`soundtrack.effect` accepts `fadeIn`, `fadeOut`, or `fadeInFadeOut`.
92
-
93
-
An `audio` clip with `length: "end"` is functionally identical to `timeline.soundtrack`.
100
+
`asset.effect` on audio accepts `fadeIn`, `fadeOut`, or `fadeInFadeOut` (same enum the deprecated soundtrack used).
94
101
95
102
## `timeline.fonts[]` for custom fonts
96
103
@@ -127,7 +134,7 @@ See `references/fonts.md` for the full pattern.
127
134
128
135
## Common track-layout patterns
129
136
130
-
**Slideshow:** images in one track, soundtrack for music. One image per clip; use `start: "auto"` to chain them.
137
+
**Slideshow:** images in one track, an `audio` asset on a separate track with `length: "end"`for the background music. One image per clip; use `start: "auto"` to chain them.
131
138
132
139
**Voiceover with captions:** captions in track[0], audio in track[1] (with `alias` for the captions to reference), video/image in track[2].
Copy file name to clipboardExpand all lines: references/troubleshooting.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -61,7 +61,7 @@ You used a font name that isn't in the built-in list and didn't load it via `tim
61
61
62
62
A `rich-caption` clip without `width`, `height`, and `fit: "none"` defaults to filling the entire output.
63
63
64
-
**Fix:** use one of the five named presets in `references/rich-caption.md` (Nico, Kai, Kapow, Lovely Little Lychee, Rizz) which include the right dimensions, or set `width`/`height`/`fit: "none"` explicitly on your clip.
64
+
**Fix:** use one of the five named presets in `references/caption.md` (Nico, Kai, Kapow, Lovely Little Lychee, Rizz) which include the right dimensions, or set `width`/`height`/`fit: "none"` explicitly on your clip.
0 commit comments