JSON format
Everything a video document can contain. This page is generated from the same schema the engine validates with, so it is always exact.
The document at a glance
A video is one JSON object. Only title and scenes are required; the look comes from the domain, the voice from sensible defaults. This example uses every part of the envelope:
{
"version": 1,
"title": "Coffee, Explained",
"subtitle": "How a bean becomes your morning cup.",
"topic": "How coffee is made",
"domain": "food",
"emoji": "โ",
"kicker": "Kitchen science ยท Episode 1",
"chips": [
"Beginner",
"2 minutes"
],
"brand": {
"name": "Daily Bites",
"tagline": "Learn something tasty"
},
"style": {
"palette": "ember",
"fonts": "editorial",
"background": "food",
"mascot": "buddy",
"enter": "slide-up",
"transition": "fade",
"shape": "soft",
"captions": "plain"
},
"narration": {
"voice": "F1",
"speed": 0.95,
"lang": "en",
"pauses": {
"section": 1.8
},
"pronunciations": {
"espresso": "ess-PRESS-oh"
}
},
"followUps": [
{
"kicker": "Try this",
"title": "Brew a cup with a method you have never used",
"tone": "amber"
}
],
"scenes": [
{
"kind": "intro",
"say": [
"Welcome to Daily Bites.",
"Today we follow a coffee bean from the farm to your cup."
]
},
{
"kind": "cards",
"heading": "From bean to cup",
"layout": "flow",
"lead": "Every cup of coffee goes through four steps.",
"items": [
{
"icon": "๐ฑ",
"title": "Grow",
"text": "Coffee cherries ripen on the tree.",
"say": "First, coffee cherries ripen on the tree."
},
{
"icon": "๐ฅ",
"title": "Roast",
"text": "Heat turns green beans brown.",
"tone": "orange",
"say": "Then roasting turns the green beans brown and brings out the flavour."
},
{
"icon": "โ๏ธ",
"title": "Grind",
"text": "Smaller pieces extract faster.",
"say": "Grinding breaks the beans into small pieces so water can reach the flavour."
},
{
"icon": "โ",
"title": "Brew",
"text": "Hot water carries the flavour.",
"tone": "amber",
"say": "Finally, hot water carries that flavour into your cup."
}
],
"outro": "Change any step, and the taste changes too."
},
{
"kind": "statement",
"eyebrow": "Remember",
"text": "The **grind size** matters more than most people think.",
"icon": "๐ก",
"say": "The grind size matters more than most people think."
}
]
}
titleโฆfollowUpsdescribe the video as a whole: the title card, the top bar and the recap.stylechooses colours, fonts, backgrounds, host, animations and captions. Leave a field out and the domain decides.narrationchooses the voice and the pauses.soundadds sound design made for the video: whooshes, hits, risers and an optional music bed.scenesis the story: a list of scenes played in order (scene reference).
Video fields
| Field | Type | What it does |
|---|---|---|
| version | 1 | Spec format version. Always 1. |
| titlerequired | string | Shown in the top bar and on the title card. Limits: 1โ80 characters |
| subtitle | string | One-sentence summary, shown on the title card. Limits: 1โ220 characters |
| topic | string | What the video is about. Used to pick a look when Limits: 1โ200 characters |
| domain | enum | Topic area. Picks a matching default look; anything in
|
| aspect | enum | The shape the video is made for:
|
| emoji | string | Shown beside the host on the title card. Limits: 1โ8 characters |
| kicker | string | Small line above the title in the top bar, e.g. Limits: 1โ48 characters |
| chips | string[] | Pills above the title on the title card. Limits: 0โ4 items, each 1โ24 characters |
| brand | object | |
| โ name | string | Shown in the top bar (and on the end card). Limits: 1โ32 characters |
| โ tagline | string | Limits: 1โ60 characters |
| โ logo | string | Address of your logo (PNG, SVG or JPEG with an http(s) address, a data:image URL or a path starting with /). Shown in a corner of every scene. |
| โ logoPosition | enum | Which corner the logo sits in. Default
|
| โ logoPlate | enum | A rounded plate behind the logo, for a logo that would not stand out on the video's background:
|
| host | object | A picture of the presenter, shown instead of the drawn mascot (in the top bar and on the title card). |
| โ srcrequired | string | Address of the picture of the host: a cut-out with a transparent background works best. |
| โ alt | string | Who or what the host is. Limits: 1โ150 characters |
| โ prompt | string | What the AI was asked to paint. Kept so the picture can be made again; it is not shown. Limits: 1โ600 characters |
| music | object | |
| โ srcrequired | string | Address of the music: an http(s) link to an MP3, WAV, M4A or OGG file, or an uploaded one ( Limits: up to 2000 characters |
| โ name | string | The name of the file, shown in the editor. Limits: 1โ120 characters |
| โ volume | number | Loudness of the music, 0 to 1, where the narration is 1. Default 0.18. Limits: 0โ1 |
| โ duck | boolean | Lower the music further while the narrator speaks. Default |
| audio | object[] | Recordings and music placed on the timeline, each playing part of an uploaded file from a given second of the video. Exports mix them in ( Limits: up to 24 items |
| โ kindrequired | enum |
|
| โ srcrequired | string | Address of the uploaded audio ( |
| โ name | string | The name of the file, shown in the editor. Limits: 1โ120 characters |
| โ durationrequired | number | Length of the whole file in seconds. Limits: 0.2โ3600 |
| โ startrequired | number | Where the clip begins, in seconds from the start of the video. Limits: 0โ3600 |
| โ offset | number | Seconds cut from the beginning of the file. Default 0. Limits: 0โ3600 |
| โ lengthrequired | number | Seconds of the file that play, from Limits: 0.2โ3600 |
| followUps | object[] | Cards beside the recap: a hands-on task, what to watch next. Limits: 0โ3 items |
| โ kickerrequired | string | Limits: 1โ24 characters |
| โ titlerequired | string | Limits: 1โ48 characters |
| โ tone | enum | Accent colour.
|
| scenesrequired | object[] | Limits: 1โ40 items |
style: the look
Every field is optional and {} is a complete style. Precedence, highest first: what you write in style, then the profile of the domain, then the default. Every palette, font, background and animation is shown on Looks & styles.
| Field | Type | What it does |
|---|---|---|
| style | object | |
| โ theme | enum | A complete ready-made look (palette, fonts, background, motion, captions, effects) in one word. Every other
|
| โ palette | enum | Colour scheme: a list of backdrops the scenes cycle through. See the palette catalog.
|
| โ brandColor | string | Builds a palette around this colour. Wins over Limits: hex colour such as #7c3aed |
| โ mode | enum |
|
| โ textColor | string | Text colour. Defaults to white (dark) or deep ink (light). Replaced if it would be unreadable. Limits: hex colour such as #7c3aed |
| โ accent | [string, string] | The two highlight colours: title gradient, spoken caption word, brand name. Limits: exactly 2 items, each hex colour such as #7c3aed |
| โ cycleBackdrops | boolean |
|
| โ tones | enum | Accent set for chips, bars and chart parts.
|
| โ fonts | enum | Heading and body font pairing.
|
| โ displayFont | enum | Overrides the heading font of the pairing.
|
| โ bodyFont | enum | Overrides the body font of the pairing.
|
| โ background | enum | A ready-made stack of animated background layers.
|
| โ backgroundLayers | enum[] | Your own stack of layers, bottom to top. Wins over Limits: up to 6 items
|
| โ glyphs | string[] | Symbols or emoji for the Limits: 1โ12 items, each 1โ4 characters |
| โ mascot | enum | The host character.
|
| โ enter | enum | How items appear.
|
| โ transition | enum | How scenes replace each other.
|
| โ shape | enum | Corner roundness of cards and chips.
|
| โ captions | enum | Caption look.
|
| โ captionPosition | enum | Where captions sit.
|
| โ progress | enum | A progress indicator along the top edge. Default: none. A scene can hide or show it for itself with its own
|
| โ header | enum[] | Which parts of the top bar show on every scene except the title card: Limits: up to 4 items
|
| โ camera | enum |
|
| โ grade | enum | A colour grade over the whole picture, like the last step of a professional edit:
|
| โ safeZone | enum | For a tall video (9:16) made for a social platform: keeps the titles, captions and logo clear of the parts of the screen the app covers. Default: none.
|
| โ effects | enum[] | Finishing touches over the whole picture (vignette, letterbox, film, glow ...). Combine up to four. Limits: up to 4 items
|
narration: the voice
engine is standard (the default): the voices, speed and languages of the Supertonic text-to-speech server. Press play to hear each voice (the samples are in English; every voice speaks all the languages). Or it is premium: Google Gemini 3.8 Flash TTS, directed with premium and the delivery of every scene. Pauses are in seconds.
- Male voice 1
- Male voice 2
- Male voice 3
- Male voice 4
- Male voice 5
- Female voice 1
- Female voice 2
- Female voice 3
- Female voice 4
- Female voice 5
The 30 premium voices, each with the quality Google gives it:
- Zephyr ยท Bright
- Puck ยท Upbeat
- Charon ยท Informative
- Kore ยท Firm
- Fenrir ยท Excitable
- Leda ยท Youthful
- Orus ยท Firm
- Aoede ยท Breezy
- Callirrhoe ยท Easy-going
- Autonoe ยท Bright
- Enceladus ยท Breathy
- Iapetus ยท Clear
- Umbriel ยท Easy-going
- Algieba ยท Smooth
- Despina ยท Smooth
- Erinome ยท Clear
- Algenib ยท Gravelly
- Rasalgethi ยท Informative
- Laomedeia ยท Upbeat
- Achernar ยท Soft
- Alnilam ยท Firm
- Schedar ยท Even
- Gacrux ยท Mature
- Pulcherrima ยท Forward
- Achird ยท Friendly
- Zubenelgenubi ยท Casual
- Vindemiatrix ยท Gentle
- Sadachbia ยท Lively
- Sadaltager ยท Knowledgeable
- Sulafat ยท Warm
| Field | Type | What it does |
|---|---|---|
| narration | object | |
| โ engine | enum |
|
| โ premium | object | The premium voice: which of the 30 voices, how it delivers the video, accent and pace. Only used when |
| โ voice | enum | One of 30 studio voices (see
|
| โ style | string | How the whole video is delivered: emotion, energy, inflection. Short and concrete, e.g. "warm, confident, with a smile in the voice". Scenes can add to it with their own Limits: 1โ160 characters |
| โ accent | string | A regional accent or dialect as a soft hint, e.g. "British" or "Scottish". The voice keeps its own character; the model follows the hint most of the time. Limits: 1โ40 characters |
| โ pace | enum | How quickly the voice speaks. Default
|
| โ voice | enum | Standard voice id.
|
| โ speed | number | Standard voice: 1 = normal speech. Default 0.95. Limits: 0.5โ2 |
| โ quality | enum | Standard voice: more synthesis steps sound better and take longer. Default
|
| โ lang | enum | Language of the narration. Default
|
| โ silent | boolean |
|
| โ voiceover | object | Your own recording instead of the generated voice. The captions and the scenes follow it. Ignored when |
| โ srcrequired | string | Address of the uploaded audio ( |
| โ durationrequired | number | Length of the audio in seconds. The scenes are spread over it in proportion to what they say. Limits: 0.5โ3600 |
| โ name | string | The name of the file, shown in the editor. Limits: 1โ120 characters |
| โ pauses | object | |
| โ sentence | number | Seconds of silence after each sentence. Limits: 0โ10 |
| โ section | number | Seconds of silence between scenes. Limits: 0โ10 |
| โ leadIn | number | Seconds of silence before the first word. Limits: 0โ10 |
| โ tail | number | Seconds of silence after the last word. Limits: 0โ10 |
| โ pronunciations | map<string, string> | Respellings for words the voice mispronounces, e.g. |
| โ foreign | map<string, string[]> | Names, words and phrases that belong to another language than the narration, spoken by that language's voice in the middle of the sentence, e.g. |
sound: the sound design
Sound effects and a music bed made for the video, from nothing: no files are needed. Whooshes ride the cuts, a riser and an impact land as the product appears, and the bed's tempo is fitted to the cuts so they fall on the beat. The narrator is always on top, and the whole mix is mastered to about โ15 LUFS. Left out, the video has none.
| Field | Type | What it does |
|---|---|---|
| sound | object | Sound design made for the video itself: whooshes on the cuts, a riser and an impact into the reveal, small pops for text, and an optional music bed whose tempo is fitted to the cuts. Exports mix it in ( |
| โ effects | enum | How lively the sound effects are:
|
| โ bed | enum | A music bed made to the cuts of the video, so they land on the beat:
|
| โ bedVolume | number | How loud the bed is under the narrator, 0 to 1. Default 0.4. Limits: 0โ1 |
| โ effectsVolume | number | How loud the sound effects are, 0 to 1, where the narrator is 1. Default 0.6. Limits: 0โ1 |
How narration drives the picture
Every scene has narration (say), and the narration decides when things appear. The sentences are spoken in order, and each one reveals more of the scene: an item appears just before the sentence that talks about it. So you never time anything by hand; you only write what the narrator says.
Take this cards scene:
{
"kind": "cards",
"heading": "Three states of water",
"lead": "Water exists in three states.",
"items": [
{
"title": "Ice",
"text": "Solid below zero.",
"say": "Below zero it freezes into ice."
},
{
"title": "Liquid",
"text": "What we drink.",
"say": "In between it is a liquid."
}
],
"outro": "Heat decides which one you get."
}
| Narrator says | What is on screen |
|---|---|
lead | The heading only |
items[0].say | โฆand the Ice card |
items[1].say | โฆand the Liquid card |
outro | Both cards stay while the last sentence is spoken |
Each scene kind has its own mapping, described under its name in the scene reference. A say with several sentences is split at the full stops; each sentence is a separate clip, so keep them short.
say; the captions would show it. Digits and symbols are read out in English; in other languages, write numbers in words. The one exception is the premium voice, which performs a few tags (such as <breath> or <sigh>) written in the sentence: the captions leave them out.Pictures on a scene
Every scene may carry an image: a picture behind it or beside its content. The editor makes them with the AI (Pictures tab), but any address works, so you can use your own.
| mode | What it does |
|---|---|
backdrop | Fills the frame behind the scene, softened and darkened so the text stays easy to read. The default. |
cutout | A picture with a transparent background that floats beside the content, on the side you choose (right by default). |
card | A framed photo, slightly tilted, beside the content, on the same side. It works with any picture. |
motion makes the picture move while its scene is on screen. A backdrop takes zoom-in, zoom-out, pan or still; a cut-out or card takes float (the default), sway, spin, turn, pulse, bounce or still. A scene without motion uses the default of its mode.
{
"kind": "statement",
"text": "Sunlight is made of **every colour** at once.",
"say": "Sunlight is made of every colour at once.",
"image": {
"src": "/api/assets/3c9d0e5a71b2f486",
"alt": "A prism splitting white light",
"mode": "backdrop"
}
}
src is the address of a picture of yours (/api/assets/<id>) or an http(s) link. prompt keeps what the AI was asked to paint, so the picture can be made again; it is never shown. Pictures are drawn in exports too. A media scene shows a picture of its own, full size, instead. A gallery scene shows several pictures that move, as a mosaic, a stack, a carousel or a flipbook. The presenter can be a picture too: host (src and alt, a cut-out works best) replaces the drawn mascot.
Rich text on screen
Text shown on screen (headings, card titles, statements, table cellsโฆ) supports three marks and nothing else, on purpose:
| Write | You get |
|---|---|
**compound interest** | compound interest |
`git commit` | git commit |
==less code== | less code |
Limits
Limits keep text inside its box, even on a vertical video. Going over a limit is an error that says which field and by how much.
| Limit | Value |
|---|---|
| Scenes in one video | 40 |
Characters of the video title | 80 |
| Characters of a scene heading | 60 |
| Characters of a card, step or row title | 48 |
| Characters of a card or step description | 150 |
| Characters of one table cell | 48 |
Characters of one narration line (say) | 500 |
Characters of a big number such as +27% | 14 |
| Items (cards, steps, rowsโฆ) in one scene | 8 |
Lines of a code scene | 12 |
| Characters of one code line | 64 |
| Chips on the title card | 4 |
Bullets in the recap of an outro | 6 |
Validation: errors and warnings
A document is checked in three steps. Structure: right fields, right types, within the limits. Meaning: things that are valid JSON but make no sense (a quiz whose answer is not one of its options, a funnel that grows). Quality: advice that never blocks you (no title card, a very long sentence, five identical scenes in a row).
Errors stop a video from being saved; warnings do not. Every issue has a path to the field and often a hint. This is what POST /api/validate answers for a document with two mistakes:
{
"valid": false,
"errors": [
{
"level": "error",
"path": "scenes[0].items[0].icon",
"message": "Required field is missing."
},
{
"level": "error",
"path": "scenes[0].items[0].say",
"message": "Required field is missing."
},
{
"level": "error",
"path": "scenes[1].kind",
"message": "Unknown scene kind \"fireworks\".",
"hint": "Did you mean \"forecast\" or \"reviews\" or \"timer\"? Allowed: intro, section, statement, cards, table, example, stat, chart, ranking, versus, feature, timeline, cycle, funnel, ... (92 in total, see the docs)."
}
],
"warnings": [],
"stats": null
}
JSON Schema
The complete JSON Schema (draft 2020-12) is available at GET /api/schema. Point your editor at it for completion and inline errors, or validate documents in your own pipeline before sending them. In VS Code, map it in .vscode/settings.json:
{
"json.schemas": [
{
"fileMatch": [
"*.video.json"
],
"url": "http://localhost:3300/api/schema"
}
]
}
Using documents in your own code
- Keep the document in version control as plain JSON; a video can always be made again from it.
- Unknown fields are rejected: a typo such as
palleteis an error, not silently ignored. - Send documents as
{ "spec": { โฆ } }to the API (see HTTP API).