---
title: Edit a documentary or interview from the transcript, with b-roll and lower thirds
description: Your interviews transcribed, the quotes picked by what they mean, a paper edit you can change, and a cut with b-roll, lower thirds, music and chapters.
---
You get a documentary or interview film cut from hours of interviews, also called a talking-head edit or a doc edit. Your agent transcribes every interview with speakers, reads them to find the quotes that say what your story needs, writes a paper edit for you to change, then cuts the film with b-roll, lower thirds, music under the voices, and chapter markers.

Use invideo for this when you want the paper edit and the cut to stay connected: the quotes live in a brief you can edit, every quote lands on the timeline with its in and out points, and you can swap a quote without starting again.

## Quickest path

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

```text
Here are the interviews in ./interviews and b-roll in ./broll. The film
is about why the town's last mill closed. Transcribe the interviews with
speakers, price it first. Find the quotes that tell the story in
chapters, write them as a paper edit, and wait for my changes. Then cut
it with b-roll, lower thirds with names, and music under the voices.
```

In a chat app, you drag the files into the project. In a terminal, you name the folders and the agent uploads them, large files included.

## What you need

The agent finds quotes by reading what people mean, so tell it what the film is about.

- **The interviews.** Camera files with sound, or picture and separate sound.
- **The names and titles.** Who each speaker is, for the lower thirds.
- **The story.** The question the film answers, and the chapters if you know them.
- **B-roll.** Shots of the places, people and things the interviews talk about.
- **Music.** Your track, or a mood for stock or generated music.

## Steps

The agent works on a branch. It stops after the paper edit for your changes.

<Steps>
<Step title="Upload the interviews">
The agent sets up in three calls.

1. It makes the timeline with `new_timeline`, and a branch with `timeline_history` and `action: "create_branch"`.
2. For each large local file, it calls `start_upload` and PUTs the bytes to the `upload_url`.
3. It calls `add_media` with the `upload_id` and the branch URL.

Expected result: a sequence URL and a media bin id for every interview and b-roll file.
</Step>
<Step title="Transcribe every interview">
The agent prices `audio.transcript` with `dry_run` on each interview's sequence URL from `add_media` 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. Expected result: every word with its time and speaker, for every interview.
</Step>
<Step title="Write the paper edit from the quotes">
The agent reads the transcripts against your story and finds the lines that answer each question, even when the speaker uses other words. It makes a brief with `new_brief` and writes each quote into it with `edit`, in story order, with the speaker, the words, and the in and out times. Expected result: a brief URL. You reorder, cut or add quotes in the brief, and tell the agent when it is ready.
</Step>
<Step title="Lay the quotes, then the b-roll above them">
The agent reads the brief with `read` and places each quote on `V1` with `place_media`, using its in and out times and `linked_audio` true. Then it places b-roll on `V2` with `insert_media` over the lines it illustrates, and lowers the b-roll's own sound with `set_audio_gain`. It sends a chapter in one `edit_timeline` call. Expected result: the interviews cut in paper-edit order with b-roll over the voices, and a new `state_token`.
</Step>
<Step title="Add lower thirds, music and chapters">
The agent adds each speaker's name and title with `add_text` the first time they appear, and fades it in and out with `set_keyframes` on opacity. It places your music, or the bed from the music section below, on `A2` and adds `ducker` to that track with `add_audio_effect`. A new timeline ducks under `A1`, where the interview sound sits, so no sidechain call is needed. It adds a marker per chapter with `add_marker`. Expected result: lower thirds, music that dips under every voice, and chapter markers.
</Step>
<Step title="Check, then export">
The agent runs `capture` at each lower third and each chapter start, and `check_timeline`. It checks that no lower third covers a face. Then it runs `export`. Expected result: an export card with status `completed`, and a chapter list with timecodes for YouTube.
</Step>
</Steps>

### Make a music bed when you have no track

The agent follows the generation pattern.

1. It runs `find_models` with the music job in words, picks one, and reads its inputs with `get_model`. A good pick is `elevenlabs_music_v2_5_instrumental`. Your agent can search for others with `find_models`.
2. It calls `generate` with `dry_run: true`, a `prompt` and a `duration` within the range `get_model` gives, 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`. It gets a thread URL and, when the result lands, a sequence URL. It reads that URL with `read` and never calls `generate` again to check.

The same job from a terminal:

```bash
invideo edit new <project-url> --name "The Mill, cut 1" --fps 25
invideo asset upload <edit-url> ./interviews/* ./broll/*
invideo edit show <edit-url>
invideo branch new <edit-url> --name paper-edit-v1 --token <state_token>
invideo edit show <branch-url>
invideo media audio.transcript <interview-sequence-url> --dry-run
invideo media audio.transcript <interview-sequence-url> --max-credits <price>
invideo gen models <project-url> --query "quiet instrumental music bed"
invideo gen model <project-url> --model elevenlabs_music_v2_5_instrumental
invideo gen run <page-url> --model elevenlabs_music_v2_5_instrumental \
  --dry-run -i prompt="quiet piano, slow, hopeful" -i duration=180
invideo gen run <page-url> --model elevenlabs_music_v2_5_instrumental \
  --max-credits <price> --idempotency-key mill-music \
  -i prompt="quiet piano, slow, hopeful" -i duration=180
invideo context new-brief <project-url> --name "The Mill paper edit" \
  --description "Quotes in story order, by chapter"
invideo context write <brief-url> --markdown @paper-edit.md \
  --revision <revision>
invideo edit change <branch-url> --timeline T1 --token <state_token> \
  --operations @chapter-1.json
invideo edit capture <branch-url> --at 5,62,140,233 --out ./frames
invideo edit check <branch-url>
invideo edit export <branch-url> --format video --quality 1080
```

Where the values come from: `<project-url>` from `invideo project new`, and `<edit-url>` 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. `<interview-sequence-url>` is the `url` that `invideo asset upload` returns for each interview. `<price>` is the price each dry run returns, its `estimated_credits`. `<page-url>` comes from `invideo notebook show <project-url>`. `<brief-url>` is the URL `context new-brief` returns, and `<revision>` comes from reading the brief with `invideo context show`. The file in `--operations @chapter-1.json` is a bare list of ops, like the `operations` list below.

The key MCP call lays one quote, adds its lower third, and marks the chapter. This fence is the full MCP `edit_timeline` call. `at_f`, `start_f` and `end_f` are frames at the timeline's frame rate, and `m1` is the interview's bin id from `get_timeline`.

```json
{
  "url": "<branch-url>",
  "timeline_id": "T1",
  "expected_state_token": "<state_token>",
  "operations": [
    { "op": "place_media", "asset": "m1", "track": "V1", "at_f": 0,
      "source_start_seconds": 812.4, "source_end_seconds": 829.9,
      "mode": "append", "linked_audio": true },
    { "op": "add_text", "track": "V3", "start_f": 25, "end_f": 150,
      "text": "Ruth Okafor\nMill worker, 1979 to 2019" },
    { "op": "add_marker", "at_f": 0, "name": "Chapter 1: The town" }
  ]
}
```

The fade goes in the next call, on the text clip's id: `set_keyframes` with `property` opacity and points from 0 to 1 over a short fade-in.

## 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:** a transcript per interview with `audio.transcript`, and any stock or generated music.
- **Free:** uploads, reading the transcripts, the paper edit, the cut, b-roll, lower thirds, the ducker, markers, `capture` and the export.

Transcripts of a day of interviews take a few minutes each. The paper edit takes the agent a few minutes, and your review takes the longest. See [Credits and what they cost](/account/credits) for prices.

## If something goes wrong

Most problems come from quotes cut mid-word or speakers with the wrong label.

| Symptom | Fix |
| --- | --- |
| A quote starts or ends mid-word | Move the edge a few frames out with `trim_clip`, then listen again. |
| Two speakers share one label | Tell the agent who speaks first in that interview. It relabels them in the paper edit. |
| A quote is in the brief but not on the timeline | The agent reads the brief again with `read` and places the missing line. |
| `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. |
| `audio.transcript` is refused as `not_found` | It got a bin id like `m1`. Pass the interview's sequence URL instead. |
| The music does not dip under the voices | A new timeline ducks under `A1`. If the voices sit on another track, point the ducker at it with `set_sidechain_source`. |
| A lower third covers a face | Move it with `set_position`, then `capture` again. |
| The transcript returns status running | Call `audio.transcript` again after `retry_after_s`. Only the first call costs credits. |
| An upload by URL fails on a large file | Use `start_upload`, then `add_media` with the `upload_id`. |
| Avoid: searching for keywords only | Instead: read the transcript for what people mean. The best quote often uses other words. |
| Avoid: cutting before you approve the paper edit | Instead: change the brief first. The cut follows it. |

## Prompts to try

Each prompt is a real variation of the job.

```text
Find every place where someone talks about the strike, even if they do
not say "strike". List them with speaker and timecode, best first.
```

```text
Swap quote 7 in the paper edit for the one where Ruth talks about her
father, then recut chapter 2 and show me the cut points.
```

```text
Make a short teaser from the paper edit: the strongest lines, b-roll
under each, and the title card at the end.
```

## When to use something else

invideo does not clear archive footage or music rights for you. Clear archive clips with their owners, and use stock or generated music for anything you cannot clear.

For a broadcast delivery with a closed-caption file to a network spec, or a surround mix, finish in Premiere Pro or DaVinci Resolve: export the project with `format` `premiere` or `davinci`.

## Related

- [Turn dailies into string-outs and selects](/how-to/film/dailies-to-string-outs)
- [Clean up the dialogue and keep the original](/how-to/film/dialogue-cleanup)
- [Cut a trailer or teaser from your film](/how-to/film/trailer-or-teaser)
- [Make titles readable over busy footage](/guides/how-do-i-make-titles-readable-over-busy-footage)
- [What is audio ducking and when would I use ducker?](/guides/what-is-audio-ducking-and-when-would-i-use-ducker)
- [Export to Premiere Pro, DaVinci Resolve or Final Cut Pro](/how-to/export-to-premiere-resolve-final-cut)