---
title: "Saved edits"
description: "A stored cut with versions. Change it with commands and render it with one QA result."
url: https://docs.roasos.com/concepts/saved-edits
---

# Saved edits

A saved edit is a stored cut. It holds clips, voice, music, captions and overlays. Each change makes a new version. You can read an old version at any time.

Saved edits are free. Commands and renders cost no credits.

## The four steps

1. **Create.** `POST /v1/edits` with `clips`, a list of files in order. Each file is `{ "generation_id": "…" }` or `{ "url": "…" }`. A URL must be a file that your workspace owns on `cdn.roasos.com`.
2. **Inspect.** `GET /v1/edits/{id}` returns each item with its number.
3. **Change.** `POST /v1/edits/{id}/commands` with `commands`.
4. **Render.** `POST /v1/edits/{id}/render`.

## Commands

A batch applies all commands or no commands. If one command is not valid, the edit does not change. The response is `422 edit_command_invalid`, and the message tells you what to send.

```json
{
  "expected_version": 3,
  "commands": [
    { "type": "remove_clip", "clip": 1 },
    { "type": "move_clip", "clip": 1, "to": 2 },
    { "type": "add_overlay", "text": "20% off today", "style": "promo", "from_end_seconds": 3 }
  ]
}
```

Clip numbers are positions. They update after each command. In this example, the second command moves the clip that was clip 2 before the first command.

Send `expected_version` when other writers can change the edit. If the edit is not at that version, the response is `409 edit_version_conflict` and the edit does not change.

| Command                                                                                                         | Use                                                                                               |
| --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `insert_clip`, `remove_clip`, `move_clip`, `duplicate_clip`, `replace_clip`                                     | Change the clips.                                                                                 |
| `split_clip`, `trim_clip`, `set_speed`                                                                          | Change the time of a clip.                                                                        |
| `set_fit`, `set_framing`, `set_effect`, `set_transition`, `set_output`                                          | Change the picture.                                                                               |
| `set_image`                                                                                                     | Set how long an image stays, and its slow move.                                                   |
| `set_volume`, `set_voice`, `set_music`, `update_audio`, `remove_audio`                                          | Change the sound.                                                                                 |
| `fit_clips_to_voice`                                                                                            | Change the clip lengths so that the picture ends just after the voice. The audio does not change. |
| `captions_from_script`, `set_captions`, `edit_caption`, `remove_caption`, `clear_captions`, `set_caption_style` | Change the captions.                                                                              |
| `add_overlay`, `edit_overlay`, `remove_overlay`                                                                 | Change the overlays.                                                                              |

The `changeEdit` schema in the API reference gives the fields of each command.

## Captions from the script

`captions_from_script` uses the words of your approved script, so brand names have the correct spelling. Send `words`, a list of `{ "text", "start", "end" }` from a transcript, to get exact times. If you do not send `words`, roasOS estimates the times from the length of the voice, and the response includes a note.

If less than half of the script matches `words`, the command fails. Make sure that the script is the one that the voice speaks.

## Overlays

An overlay has a `style`: `plate`, `promo`, `reply`, `title`, `label` or `cta`. A `reply` overlay can have a small top line in `sub`.

Use `from_end_seconds` to count back from the end of the clips. The overlay stays at the end when the clips change.

## Render and QA

A version has one render job. If you render the same version again, you get the same job. Call the render operation again to read the status. If a job failed, the same call runs it again.

The final mix is set to about -14 LUFS. A completed job has `url` and `qa`.

| QA field        | What it measures                                                                                   |
| --------------- | -------------------------------------------------------------------------------------------------- |
| `duration`      | The length of the file against the length of the edit.                                             |
| `size`          | The width, the height and the file size.                                                           |
| `loudness`      | Integrated loudness against -14 LUFS, plus or minus 1.                                             |
| `true_peak`     | True peak. The limit is -1 dBTP.                                                                   |
| `black_ranges`  | Times when the picture is black. A dark colour with saturation, such as a deep blue, is not black. |
| `frozen_ranges` | Times when a video does not move. Still images are not included.                                   |
| `caption_speed` | The fastest caption. The limit is 22 characters per second.                                        |

`qa.failures` holds each failure as one sentence. A job can complete and have failures. Read them before you use the video.

## Limits

| Limit                              | Value        |
| ---------------------------------- | ------------ |
| Length of an edit                  | 180 seconds  |
| Commands in one batch              | 50           |
| Clips when you create an edit      | 30           |
| Clips in an edit                   | 80           |
| New render jobs for each workspace | 30 each hour |

A render job that already exists does not count against the hourly limit.
