# Explainer videos # Explainer videos An explainer is a 30–120 second video that says what a product does, for whom, and why it matters: the kind of thing that sits on a landing page, opens a sales call, or launches a feature. Second Studio makes them from three inputs you control: 1. **A brand kit** — name, what the company does, tone, colors, font, logo, product screenshots. 2. **A script** — written by the studio from your brief, or by you. It's plain JSON: a list of scenes. 3. **A render** — the scenes dressed in the brand, with motion, optional captions, narration and music. Rendering is deterministic. The same script and brand always produce the same video, so you can edit one line of a scene and re-render without anything else changing. The model writes words, never layout. ## 0. Start from your boards — `POST /v1/brands/analyze` `{ "imageAssetIds": ["…"], "notes": "editorial, light canvas" }` (1–6 brand boards, screenshots or deck pages) → a job whose `result.suggested` is a ready kit: colors, the closest font, a `style` block and tone, with a short rationale. Pass it to `POST /v1/brands`. 1 credit. ## 1. Save a brand kit — `POST /v1/brands` Upload the logo and any product images first ([assets](api.html#assets)), then: ```json { "name": "Acme Analytics", "description": "Product analytics for B2B SaaS teams: connect your app, ask questions in plain language, get answers without SQL.", "tone": "clear, confident, a little dry", "tagline": "See what your customers do next.", "colors": { "primary": "#F5F3FF", "secondary": "#B8B2D6", "accent": "#8B5CF6", "background": "#0F0B1F", "text": "#ECE9F7" }, "font": "Inter", "logoAssetId": "…", "images": [ { "assetId": "…", "description": "Dashboard showing a retention cohort chart" }, { "assetId": "…", "description": "The natural-language question box with an answer" } ], "musicAssetId": "…" } ``` | field | notes | |---|---| | `description` | The script writer's main source. Say what it does, for whom, and what's different. | | `colors` | Five hex values: `primary` (headlines), `secondary` (supporting text), `accent` (bars, numbers, buttons), `background`, `text`. Any you omit get a dark default. | | `font` | One of `Inter`, `Montserrat`, `Poppins`, `DM Sans`, `Space Grotesk`, `Playfair Display`, `Manrope`, `Sora`, `Karla`. Headlines always use it; set `style.bodyFont` for a different body face. | | `images` | Up to 12. The description tells the writer what each shows so it can place them in `image` scenes. Only these images can appear in a video. | | `musicAssetId` | A bed track, looped and ducked under narration. Optional; can also be given per render. | | `videos` | Up to 12 clips with descriptions: product recordings, b-roll, founder clips. The script can place them as `video` scenes. | | `style` | How the brand looks beyond colors and font — see below. | | `logoDarkAssetId` | A logo for light canvases. | | `backgroundAssetId` | A full-bleed photo or video behind every scene (dimmed so type stays readable). | | `skillIds` | Your own image skills, applied to every image made for this brand. | `GET /v1/brands`, `GET /v1/brands/{id}`, `POST /v1/brands/{id}` (update any field, including adding and removing library assets), `DELETE /v1/brands/{id}`. Free. ### Style Every field is optional; the renderer has defaults (dark canvas, soft accent glow, bold headings, check-mark lists, pill button). | `style.` | values | |---|---| | `canvas` | `dark` (brand background), `light` (off-white canvas, ink type), `custom` (your colors exactly, no glow) | | `gradient` | `true`/`false` — the soft accent glow behind scenes | | `headingWeight` | `light`, `regular`, `semibold`, `bold` | | `captionStyle` | `box` (translucent pill) or `plain` (text with a shadow) | | `listMarker` | `check`, `number`, `dash`, `dot` | | `buttonStyle` | `pill`, `underline`, `text` | | `radius` | 0–4: corner radius in % of the short side (0 = square) | | `logoSize` | 3–12: corner logo size | | `lockup` | `true` puts a large centered wordmark on the title and CTA cards | | `backgroundDim`, `backgroundTint` | 0–1: darken the background; tint it toward the brand colors (duotone feel) | | `bodyFont` | A second family (same list as `font`) for body text and captions, e.g. Montserrat headings over Karla body | A flat, editorial brand: `{ "canvas": "light", "gradient": false, "headingWeight": "light", "listMarker": "dash", "buttonStyle": "underline", "captionStyle": "plain", "radius": 0.2, "lockup": true }`. A photographic one: `backgroundAssetId` + `{ "backgroundDim": 0.5, "backgroundTint": 0.6, "lockup": true }`. ## 2. Get a script — `POST /v1/scripts` (2 credits) ```json { "brandId": "…", "brief": "60-second explainer for our homepage. Audience: heads of product at 50–500 person SaaS companies. Pain: they wait days for an analyst to answer simple questions. Key points: set up in an afternoon, plain-language questions, no SQL. Real numbers you can use: customers report 42% faster roadmap decisions. CTA: start a free trial at acme.example.", "duration": 60, "aspect": "16:9" } ``` The job's `result.script` is the scene list: ```json { "title": "Acme Analytics — homepage explainer", "scenes": [ { "id": "s1", "type": "title", "durationSec": 4, "headline": "Stop guessing what your users want.", "subline": "Acme turns raw product events into answers.", "narration": "You have the data. Getting an answer out of it still takes a week." }, { "id": "s2", "type": "steps", "durationSec": 8, "headline": "How it works", "steps": ["Connect your product", "Ask a question in plain language", "Share the answer"], "narration": "…" }, { "id": "s3", "type": "image", "durationSec": 6, "imageAssetId": "…", "headline": "Ask it like you'd ask a colleague", "fit": "contain", "narration": "…" }, { "id": "s4", "type": "stat", "durationSec": 4, "value": "42%", "label": "faster roadmap decisions", "narration": "…" }, { "id": "s5", "type": "cta", "durationSec": 5, "headline": "Try Acme free", "action": "acme.example", "narration": "…" } ] } ``` Scene types: `title`, `bullets`, `steps`, `stat`, `quote`, `image`, `video` (one of the brand's clips: `videoAssetId`, `start`, `fit`, `sound`), `compare` (left vs right), `cta`. Any scene may carry `backgroundAssetId` for a full-bleed photo or video behind it. Every scene has `id`, `durationSec`, `narration` (what a voice says) and an optional short `caption`. Edit anything — wording, order, durations, drop a scene — and send it to the render step. The studio only uses real numbers and claims from your brief; if you give it none, it won't invent any. Options: `duration` 15–180 s (default 60), `aspect` `16:9` | `9:16` | `1:1`, `language`. ## 3. Render — `POST /v1/explainers` (12 credits) Either a brief (the studio writes the script and renders in one go) or a script: ```json { "brandId": "…", "script": { "title": "…", "scenes": [ … ] }, "aspect": "16:9", "captions": true } ``` | option | | |---|---| | `brief` / `script` | One of the two. A script from step 2, edited as you like, or your own in the same shape. | | `aspect` | `16:9` (1920×1080), `9:16` (1080×1920), `1:1` (1080×1080). Layouts adapt. | | `captions` | Show each scene's caption or narration as an on-screen line. Good when there's no voice. | | `voiceover` | Narrate each scene with a generated voice — the platform's, or your own ElevenLabs voice (pass its `voiceId` as `voice`) when your key is connected. Scenes stretch to fit the read. | | `voiceoverAssetId` | Your own recorded or cloned narration track, played across the whole video. Give this *or* `voiceover`. | | `voiceoverJobId` | A finished dialogue or voice job: its track becomes the voiceover and its line timings set the scene cuts, in order — scene 1 runs for line 1, and so on. | | `estimate` | `true` returns the price and total seconds without rendering. | | `musicAssetId` | Bed track for this render; overrides the brand's. | | `duration` | With a brief: the target length. With a script: the scenes are rescaled to it; leave it out to keep the scenes' own timing. | | `language` | Used when you give a brief. | The result has the MP4 (`outputs.video`), the final `script` that was rendered, and `duration`. A render is silent unless you pass `musicAssetId`, `voiceover: true` or `voiceoverAssetId`; `captions: true` puts the narration on screen. Renders take a few minutes; poll the job or use the MCP tool, which waits. You can also pass an inline `brand` object instead of `brandId` for a one-off (same fields as the kit). ## Through MCP `create_brand` → `write_script` → `create_explainer`, plus `list_brands`, `get_brand`, `delete_brand`. The local MCP server accepts file paths for the logo, images and music and uploads them for you. ## What it's good for - Landing-page and App Store explainers, in every aspect ratio from one script. - Feature launches: new brief, same brand kit, done in minutes. - Localised versions: re-run the script step with `language`, keep the brand. - Sales enablement: a `compare` scene for "before / after" or "them / us", a `stat` for proof. Product screenshots in a video come only from the images you put in the brand kit; the studio never generates or fakes an interface.