---
title: Make a sizzle reel or proof-of-concept to raise money
description: A short reel that sells your film or series to investors, mixing your footage, stock and generated concept shots, each generated shot labeled as concept.
---
You get a sizzle reel for financing, also called a proof-of-concept, a pitch reel or a mood reel. It shows the world, the tone and the story of your project in a short reel. Your agent mixes your own footage, stock and generated concept shots, adds a voice-over, music and captions, and labels every generated shot as concept art.

Use invideo for this when you have more vision than footage: the agent makes the missing shots, finds stock, and cuts it all on one timeline, and the reel stays editable for each investor meeting.

## Quickest path

Set up your agent first with [invideo for AI agents](/agents). Then give it this prompt.

```text
Make a short sizzle reel for my series "Salt Road". My test footage
is in ./tests, the pitch deck is ./deck.pdf. Write the plan as a brief
first. Fill the gaps with stock and generated concept shots, and label
each generated shot "Concept". Add a voice-over from the logline, music
and captions. Price everything before you spend.
```

In a chat app, you drag the footage and the deck into the project. In a terminal, you name the files and the agent uploads them.

## What you need

Investors want to see the tone and know what is real. Give the agent both.

- **Your footage.** Test shoots, a scene, a teaser, location scouts.
- **The pitch.** The logline, the world, the characters, the comparable titles.
- **The voice-over script.** Or ask the agent to write one from the logline.
- **The look.** Mood images or a deck.
- **Music.** A track you have the rights to, or a mood for stock or generated music.
- **The length.** A sizzle is usually a few minutes.

## Steps

The agent writes a plan first, then cuts on a branch.

<Steps>
<Step title="Write the plan as a brief">
The agent makes a brief with `new_brief`, then writes the beats into it with `write`: the hook, the world, the characters, the stakes, the ask. Each beat says which shots are yours, which are stock, and which it will generate. Expected result: a brief URL. You change the plan before anything is spent.
</Step>
<Step title="Bring in your footage, the deck and stock">
The agent brings in three kinds of media.

1. It adds your files with `add_media`, or `start_upload` for large files.
2. It turns the deck into images with `media` `document.pages`, so slides can become cards. The dry run shows its price before anything starts.
3. It searches `search_library` in `stock_video`, shows you the previews, and places the ones you pick with `add_media` and `stock`. The dry run shows the stock's price.

Expected result: a sequence URL per file, an image per deck page, and the stock you picked.
</Step>
<Step title="Make the concept shots">
The agent follows the generation pattern for each shot that does not exist.

1. It runs `find_models` with the shot in words, picks one, and reads its inputs with `get_model`. A good pick is `seedance_2_5.r2v`. Your agent can search for others with `find_models`.
2. It calls `generate` with `dry_run: true` and the real inputs, and tells you the price.
3. For a price of 1 credit or more it waits for your yes. Then it calls `generate` with `max_credits` set to that price and an `idempotency_key`, and reads the sequence URL with `read` when the result lands. It names each shot for its beat with `rename`.

Expected result: a sequence URL per concept shot.
</Step>
<Step title="Make the voice-over">
The agent follows the same pattern for the voice. A good pick is `elevenlabs_text_to_speech.elevenlabs_tts_v4`. Your agent can search for others with `find_models`. It reads the inputs with `get_model`, finds a voice with `search_library` in `elevenlabs_text_to_speech_voices`, and gives you the previews. It calls `generate` with `dry_run: true` and tells you the price. For a price of 1 credit or more it waits for your yes. Then it calls `generate` with `max_credits` set to that price and an `idempotency_key`. Expected result: a voice-over sequence URL you can play.
</Step>
<Step title="Cut the reel">
The agent makes a timeline with `new_timeline` and a branch with `timeline_history`. It places the voice-over on `A1`, the shots in brief order on `V1` with `insert_media` and `place_media`, and the music on `A2` with `ducker` from `add_audio_effect`. A new timeline ducks under `A1`, so the ducker reacts to the voice-over. Expected result: a first cut, and a new `state_token`.
</Step>
<Step title="Label the concept shots and add captions">
On every generated shot, the agent adds a small "Concept" label with `add_text` for the length of the shot. It ends with a card that says which shots are concept art and names the models used. For captions, the agent prices `audio.transcript` with `dry_run` on the voice-over's sequence URL and tells you the price. For a price of 1 credit or more it waits for your yes. Then it starts the transcript with `max_credits` set to that price, and calls again after `retry_after_s` for the words. Then it sends `add_captions`. Expected result: a label on every generated shot, and captions.
</Step>
<Step title="Check, then export">
The agent runs `capture` on every generated shot to check its label, and at each card. It runs `check_timeline`, then `export`. Expected result: an export card with status `completed`. You share it from an export page with `share_export_page`, private or with a link.
</Step>
</Steps>

The same job from a terminal:

```bash
invideo context new-brief <project-url> --name "Salt Road sizzle" \
  --description "Short pitch reel for investors"
invideo asset upload <project-url> ./tests/* ./deck.pdf
invideo media document.pages <deck-url>
invideo library search <project-url> --library stock_video \
  --query "desert highway at dusk"
invideo gen models <project-url> --query "cinematic concept shot"
invideo gen model <project-url> --model seedance_2_5.r2v
invideo gen run <page-url> --model seedance_2_5.r2v --dry-run \
  -i prompt="A salt flat at dawn, a lone truck, wide, 35mm"
invideo gen run <page-url> --model seedance_2_5.r2v \
  --max-credits <price> --idempotency-key salt-flat-01 \
  -i prompt="A salt flat at dawn, a lone truck, wide, 35mm"
invideo status <thread-url> --wait
invideo notebook show <thread-url>
invideo library search <project-url> \
  --library elevenlabs_text_to_speech_voices --query "warm, low"
invideo edit new <project-url> --name "Salt Road sizzle" --fps 24
invideo branch new <edit-url> --name sizzle-v1 --token <state_token>
invideo edit show <branch-url>
invideo edit change <branch-url> --timeline T1 --token <state_token> \
  --operations @labels.json
invideo edit capture <branch-url> --at 8,31,57,96 --out ./frames
invideo edit export <branch-url> --format video --target-lufs -14
```

Where the values come from: `<project-url>` from `invideo project new`. `<deck-url>` is the `url` that `invideo asset upload` returns for the deck; uploads land in a dated folder, so never guess the path. `<page-url>` comes from `invideo notebook show <project-url>`. `<price>` is the price the dry run returns, its `estimated_credits`, and `<thread-url>` is the `url` the paid run returns. `<edit-url>` comes from `invideo edit new`. `<state_token>` comes from `invideo edit show` on the URL the next command runs on: `<edit-url>` for `branch new`, then `<branch-url>`, read fresh, because the main token is stale on the branch. `<branch-url>` is the `branch_url` that `branch new` returns. The file in `--operations @labels.json` is a bare list of ops, like the `operations` list below. The voice-over runs the same `gen model`, dry run and capped run on `elevenlabs_text_to_speech.elevenlabs_tts_v4`, with a `voice_id` from that search.

The key MCP call labels a generated shot and adds the end card. This fence is the full MCP `edit_timeline` call. `start_f` and `end_f` are frames at the timeline's frame rate.

```json
{
  "url": "<branch-url>",
  "timeline_id": "T1",
  "expected_state_token": "<state_token>",
  "operations": [
    { "op": "add_text", "track": "V3", "start_f": 744, "end_f": 864,
      "text": "Concept",
      "style": { "font_size": 28, "color": "#ffffffcc" } },
    { "op": "add_text", "track": "V3", "start_f": 2760, "end_f": 2880,
      "text": "Concept shots: Seedance 2.5.\nAll else is real footage." }
  ]
}
```

## Cost and time

Edits and exports are free. Generation and transcripts cost credits. Paid stock costs a small credit charge, or one of your workspace's iStock licenses. Your agent runs a dry run first and tells you the price before it spends anything.

- **Costs credits:** each generated shot, the voice-over, generated music, the captions' transcript, and each stock clip you place.
- **Free:** the brief, searching stock, the cut, the labels, `capture`, export pages and the export. `document.pages` shows its price in the dry run before anything starts.

A first cut takes the agent under an hour. The concept shots take a few minutes each. See [Credits and what they cost](/account/credits) for prices.

## If something goes wrong

Most problems come from a reel that blurs what is real and what is concept.

| Symptom | Fix |
| --- | --- |
| `get_model` or `generate` refuses the model as not found | Models retire. Run `find_models` with the job in words, use the best match, and tell the person which model you used. |
| A generated shot has no label | `capture` each generated shot and add the missing label with `add_text`. |
| The label covers a face | Move it to a corner with `set_position`, then `capture` again. |
| The voice sounds wrong | Pick another voice from `search_library` and generate again. Keep the old take. |
| The music drowns the voice | Add `ducker` to the music track `A2`. A new timeline ducks under `A1` by default. If the voice is on another track, point the ducker at it with `set_sidechain_source`. |
| `document.pages` returns "Nothing at that URL" | The path was guessed. Pass the URL that `invideo asset upload` returned for the deck. |
| Exit code 6, or `status` is `held` | A safety review, not a refusal. Wait, then run `invideo status <url> --wait` again. Do not resend. If it ends `failed`, change the input the review flagged. |
| CLI exit 5 | A limit on credits or quota. Check the balance. |
| Avoid: passing off a generated shot as footage | Instead: label it. Investors check, and a missing label costs trust. |
| Avoid: calling `generate` again to check on a shot | Instead: `read` the thread URL or call `status`. |

Investors and their lawyers expect generated material to be labeled. A clear "Concept" label and an end card that names the tools keep the reel honest and keep the meeting on your story.

## Prompts to try

Each prompt is a real variation of the job.

```text
Make a short version of the sizzle on its own branch for a cold
email: the hook, the world, the ask. Keep every concept label.
```

```text
Swap the stock desert shots for generated ones in the same style as my
test footage. Label them, and show me frames side by side.
```

```text
Make a version for a streamer with the comparable titles on cards after
the hook, and a version without them.
```

## When to use something else

invideo does not make the pitch deck itself. Write the deck in a slide tool like Keynote or Google Slides, then bring it in with `add_media` and `document.pages`.

For investor rooms that need a secure screening link with view tracking, host the export on a review platform like Frame.io or Vimeo.

## Related

- [Cut a trailer or teaser from your film](/how-to/film/trailer-or-teaser)
- [Make storyboards and previs before the shoot](/how-to/film/storyboards-and-previs)
- [Make an AI short film with a character that stays the same](/how-to/film/short-film-consistent-character)
- [Label AI content so the ad runs](/how-to/marketing/ai-disclosure-for-ads)
- [Licensing and commercial use](/account/commercial-use)