> ## Documentation Index
> Fetch the complete documentation index at: https://docs.roughy.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Cut

> A cut is the kept-segment plan for an audio or video asset — the spans Roughy keeps, computed from your asset and an optional reference script.

## What is a cut

A cut is the decision of **which spans of the source to keep**. It's a
list of `{start, end}` segments on the source timeline, stored as its
own entity and bound to an [asset](/concepts/asset) (1:N — an asset can
have many cuts). You drive the editor from it: export the cut to your
NLE, or feed it to a [render](/concepts/render) to get a flattened video
or audio output.

Roughy computes the cut from your asset — plus an optional reference
`script` (the intended final message) you pass on the request —
dropping filler, restarts, and off-topic spans while preserving pacing.

## Triggering a cut

```bash theme={null}
curl https://api.roughy.ai/v1/cuts \
  -H "Authorization: Bearer $ROUGHY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "asset_id": "<video-or-audio-id>", "script": "optional reference text" }'
```

`asset_id` may be a video or an audio asset. The `script` is an optional
field on this request: pass the intended final message and the cut aligns
to it, or omit it (`null`) for a scriptless cut.

The response is the cut row, with the request's `script` frozen onto it:

```json theme={null}
{ "id": "<cut_id>", "asset_id": "<asset_id>", "state": "pending", "script": null }
```

Poll `GET /v1/cuts/{cut_id}` until `state` is `completed`, then export
the cut via `/v1/cuts/{cut_id}/export`. Or skip polling and subscribe to
[webhooks](/concepts/webhooks) (`cut.completed` / `cut.failed`).

### Pre-conditions

A cut can only be produced once the asset is **cuttable** — fully
prepared and paid for. Check the `cuttable` boolean on the asset
([`GET /v1/assets/{id}`](/concepts/asset)); while it is `false`,
`POST /v1/cuts` returns **409** with a typed code:

| `code`                   | Meaning                                                                                          |
| ------------------------ | ------------------------------------------------------------------------------------------------ |
| `asset_processing`       | The asset is still being prepared. Transient — back off for the `Retry-After` seconds and retry. |
| `asset_payment_required` | The asset is prepared but unpaid (`pending_payment`). Top up, then retry.                        |
| `asset_failed`           | The asset failed preparation and can't be cut. Re-upload.                                        |

## Idempotency

`POST /v1/cuts` is **idempotent** on `(asset, script)`:

* The first request for a given `(asset, script)` creates a new cut and
  returns it (**201**, with a `Location` header).
* A repeat request with the **same** `(asset, script)` returns the
  existing cut (**200**) — no second cut, no second charge. The same
  request body always gives you the same cut.
* A request with a **different** `script` (on the same asset) is a new
  cut (**201**). Cuts are 1:N per asset, so distinct scripts coexist.

A scriptless request (`script` omitted / `null`) dedups the same way —
two full-auto cuts on one asset return the same cut.

The `script` you pass is snapshotted onto the cut, so a cut is a
permanent record of one cutting attempt:

* **Another take?** Post with a different `script` — you get a new
  `cut_id`; earlier cuts stay until you remove them.
* **Clean up** with `DELETE /v1/cuts/{cut_id}` — this also removes that
  cut's subtitle and any renders derived from it, and cancels any
  in-flight renders of it.

A `completed` cut is immutable. A `failed` cut is not reused — a fresh
request starts a new attempt; delete the failed one when you no longer
need it.

## Subtitles

When a cut completes, Roughy generates a **subtitle** for it — word-level
caption lines remapped onto the cut's output timeline, bound 1:1 to the
cut. Export it straight off the cut — it's addressed via its parent
`cut_id`:

```bash theme={null}
curl "https://api.roughy.ai/v1/cuts/{cut_id}/subtitle/export?format=vtt" \
  -H "Authorization: Bearer $ROUGHY_API_KEY"
```

| Format | Notes                                           |
| ------ | ----------------------------------------------- |
| `srt`  | SubRip, line-level timing.                      |
| `vtt`  | WebVTT with inline per-word karaoke timestamps. |

## Exporting a cut

Stream the cut as an edit-decision file for your NLE — synchronous,
free, no render required:

```bash theme={null}
curl "https://api.roughy.ai/v1/cuts/{cut_id}/export?format=xmeml" \
  -H "Authorization: Bearer $ROUGHY_API_KEY"
```

| Format   | Target                                     |
| -------- | ------------------------------------------ |
| `xmeml`  | Premiere Pro / DaVinci Resolve (FCP7 XML). |
| `fcpxml` | Final Cut Pro X.                           |
| `edl`    | CMX-3600 EDL — broadly accepted.           |
| `otio`   | OpenTimelineIO JSON.                       |

## Related concepts

* [Render](/concepts/render) — flatten a cut into a video or audio output.
* [Asset](/concepts/asset) — what a cut is bound to.
* [Credit ledger](/concepts/credit-ledger) — cuts are free; you pay once per source asset.
