---
title: Cut ums, pauses and retakes, as reversible timeline edits
description: Remove filler words, ums, long pauses and bad takes from your talking video, as cuts on a branch you can undo, with the original kept.
---
You cut the filler words and ums from your talking video: every "um", "uh", long pause and false start, and the takes you redid. Each cut is a real edit on a branch of your timeline, so you can see every one, put any of them back, and your original recording is never changed.

Use invideo for this when you want to check the cuts before you keep them: your agent finds the ums and retakes in a transcript, makes the cuts on a branch, and the original stays in the media bin and on main.

## Quickest path

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

```text
Clean up my talking video on a new branch. Cut every um and uh, every
pause longer than 0.7 seconds, and every retake: when I say a line
twice, keep the last one. List the cuts with timecodes before you make
them. Price the transcript first.
```

In a chat app, you drag the recording into the timeline's media bin in invideo, then ask in the chat. In a terminal, you name the file and the agent uploads it.

## What you need

A recording where you talk is enough. Tell the agent how tight you want it.

- **The recording.** A talking head, a tutorial, a voice-over, a podcast.
- **What counts as filler.** Um and uh only, or also "like", "you know", "so".
- **How long a pause can be.** Short for a fast Short, longer for a calm tutorial.
- **Retakes.** Say if you redid lines. The agent keeps the last take unless you say another.

## Steps

Your agent cuts on a branch and tells you what it cut, with timecodes.

<Steps>
<Step title="Make a branch and a checkpoint">
The agent reads the timeline with `get_timeline` for its `timeline_id`, its `state_token` and the recording's asset id in the media bin. It calls `timeline_history` with `action: "create_branch"` and a `name`, then `action: "checkpoint"` with the new `branch_slug` and a `title`. Each call takes the latest `expected_state_token`. Expected result: a branch URL and a checkpoint. Main stays as it was.
</Step>
<Step title="Transcribe the recording">
The agent prices `media` with `op: "audio.transcript"` and `dry_run: true`, on the recording's sequence URL as `url`, the one `add_media` returned, 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 start and end, the ums and uhs included.
</Step>
<Step title="Find the pauses">
The agent calls `media` with `op: "audio.content"` on the same file. It returns the spans of speech, music, effects and silence. The agent keeps the silences longer than the pause you set. Expected result: a list of silent spans with times.
</Step>
<Step title="Find the retakes">
The agent reads the transcript for lines you said twice, or a sentence you stopped and started again. It keeps the last take and marks the earlier ones to cut. Expected result: a list of retakes, each with the take it keeps.
</Step>
<Step title="Show you the cut list">
The agent lists every cut with its time, its kind (filler, pause or retake) and the words around it. You approve the list, or take items off it. Expected result: an approved list of cuts.
</Step>
<Step title="Make the cuts">
The agent turns each span from seconds in the file into frames on the timeline, with a few frames of room so no word is clipped. It cuts each span with `edit_time_range` in `close_gap` mode, from the last cut to the first, so the times of the cuts still to make do not move. To keep the music in place, it locks the music track first with `set_track_locked`. For a cut on one clip only, it uses `split_clip` and `delete_clip` instead. Expected result: a tighter timeline on the branch.
</Step>
<Step title="Check and review">
The agent runs `capture` around a few cuts and `check_timeline`, and gives you the branch URL to watch. Expected result: no clipped words and no jumps you did not want.
</Step>
</Steps>

The same job from a terminal. The CLI calls a timeline an edit.

```bash
invideo agent register <project-url> --name <name>
export INVIDEO_AS=<name>
invideo edit show <edit-url> --json
invideo branch new <edit-url> --name clean-up --token <state_token>
invideo edit show <branch-url> --json
invideo branch checkpoint <branch-url> --title "before cuts" \
  --token <state_token>
invideo media audio.transcript <sequence-url> --dry-run
invideo media audio.transcript <sequence-url> \
  --max-credits <price>
invideo media audio.content <branch-url> --asset m1
invideo edit show <branch-url> --json
invideo edit change <branch-url> --timeline T1 --token <state_token> \
  --operations @cuts.json
invideo edit capture <branch-url> --at 10,42,95 --out ./frames
invideo edit check <branch-url>
```

Where each value comes from:

- `<name>` is the name you choose in `invideo agent register`. `INVIDEO_AS` passes it to every later command. `<project-url>` is your project's URL, from `invideo project list`.
- `<edit-url>` is the timeline's URL from `invideo edit new`. `invideo edit show` on it gives the main `<state_token>`, the timeline id `T1` and the recording's bin id `m1`.
- `<branch-url>` is the `.branch_url` that `invideo branch new` returns. Every later command uses it.
- After the branch, `<state_token>` is the branch's own token from `invideo edit show <branch-url>`. The main token is stale on the branch, so the agent reads the branch again before each change.
- `<sequence-url>` is the `url` that `invideo asset upload` returned for the recording. A transcript refuses `--asset`.
- `<price>` is the dry run's `.estimated_credits`.
- `@cuts.json` reads a file that holds a bare JSON list of ops, the `operations` list of the call below.

The full `timeline_history` call for the branch, before any cut. `<edit-url>` is the timeline's URL from `new_timeline` or `list_projects`, and `<state_token>` comes from `get_timeline`.

```json
{
  "url": "<edit-url>",
  "action": "create_branch",
  "name": "clean-up",
  "expected_state_token": "<state_token>"
}
```

The key MCP call, in full, locks the music and makes three cuts, last first. `<branch-url>` is the branch URL that `timeline_history` returns, and `<state_token>` is the branch's own token from `get_timeline` on it. `A2` is the music track id from `get_timeline`. At 30 fps, a pause from 95.2 to 96.8 seconds is frames 2856 to 2904.

```json
{
  "url": "<branch-url>",
  "timeline_id": "T1",
  "expected_state_token": "<state_token>",
  "operations": [
    { "op": "set_track_locked", "track": "A2",
      "locked": true },
    { "op": "edit_time_range", "timeline": "T1", "start_f": 2856,
      "end_f": 2904, "mode": "close_gap" },
    { "op": "edit_time_range", "timeline": "T1", "start_f": 1250,
      "end_f": 1262, "mode": "close_gap" },
    { "op": "edit_time_range", "timeline": "T1", "start_f": 300,
      "end_f": 480, "mode": "close_gap" }
  ]
}
```

The list lands all or none. If one cut is refused, nothing changes, and the agent reads the refusal and fixes that cut.

## Nothing is lost

Every cut is on the branch. Main keeps the uncut timeline, and the recording stays whole in the media bin. To undo all of it, the agent calls `timeline_history` with `action: "restore"`, the `branch_slug` and the `checkpoint_slug` that `action: "list"` names. To undo one cut, it sends two ops in one `edit_timeline` call, shown below as a bare list of ops. `edit_time_range` with `mode: "insert"` opens empty time at the cut, as long as the cut. `place_media` puts the missing part of the file back in that time, with `source_start_seconds` and `source_end_seconds` from the transcript. `m1` is the recording's asset id from `get_timeline`.

```json
[
  { "op": "edit_time_range", "timeline": "T1", "start_f": 1250,
    "end_f": 1262, "mode": "insert" },
  { "op": "place_media", "asset": "m1", "track": "V1", "at_f": 1250,
    "source_start_seconds": 52.1, "source_end_seconds": 52.5,
    "mode": "overwrite", "linked_audio": true }
]
```

You keep the branch by accepting it in the editor.

## 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.

- **Free:** the branch, the checkpoint, every cut, the checks and the export.
- **Tool ops:** `audio.content`. The dry run shows its price before anything starts.
- **Costs credits:** the transcript with `audio.transcript`, once per file. Only the first call spends credits.

The cuts take the agent a few minutes once the transcript is back. See [Credits and what they cost](/account/credits) for prices.

## If something goes wrong

Most problems come from cuts that are too tight, or cuts made in the wrong order.

| Symptom | Fix |
| --- | --- |
| `audio.transcript` refused with `code: "not_found"`, or CLI exit 2 "What the command names is not there" | The call named a media bin asset. Pass the recording's sequence URL, from `add_media` or `invideo asset upload`. |
| CLI exit 3 on the first command after `invideo branch new` | The main token is stale on the branch. Run `invideo edit show <branch-url>` and use its `state_token`. |
| `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. |
| 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. |
| A word sounds clipped | Leave more room around each cut. The agent widens the span by a few frames. |
| Cuts land in the wrong place | The cuts were made first to last, so later times moved. Restore the checkpoint and cut from last to first. |
| The music jumps at each cut | The music track was not locked. Lock it with `set_track_locked`, then cut. Trim the music's end to the new length with `trim_clip`. |
| It sounds too rushed | Raise the pause length you allow, and keep short breaths. |
| One cut is wrong | Undo that one cut as under "Nothing is lost", or restore the checkpoint. |
| The wrong take was kept | Tell the agent which take to keep. It restores the checkpoint and cuts again. |
| `set_track_locked` refused | Check the `track` is a track id from `get_timeline`. |
| Refusal `code: "revision_conflict"`, or CLI exit 3 | Someone changed the timeline since your read. Read it again with `get_timeline` or `invideo edit show`, and send the cuts with the new `state_token`. |
| Avoid: cutting on main | Instead: cut on a branch, with a checkpoint first. |
| Avoid: cutting before you approve | Instead: the agent lists the cuts first, with timecodes. |

## Prompts to try

Each prompt is a real variation of the job.

```text
Only cut the ums and uhs in my podcast, nothing else. Keep the pauses.
Show me how many you found and where.
```

```text
I recorded my course lesson with lots of retakes. Keep the last take of
each line, cut the false starts, and leave a short breath between
sentences.
```

```text
Make my vlog tight for a Short: cut every pause, every um, and the word
"basically". Then add word-by-word captions on the cut version.
```

## When to use something else

invideo cuts the sound and the picture together. To remove an um from the sound alone while the picture runs on, with a crossfade inside a word, use an audio editor such as Audacity or Adobe Audition, then bring the cleaned file back in.

## Related

- [Edit a long YouTube video](/how-to/creators/edit-a-long-youtube-video)
- [Add word-by-word captions](/how-to/creators/word-by-word-captions)
- [Edit a podcast episode and pull clips from it](/how-to/creators/podcast-edit-and-clips)
- [Build an assembly cut from a script by matching lines to takes](/how-to/creators/assembly-cut-from-a-script)
- [Check your video before you say it is done](/how-to/check-your-video)