---
title: "Extend a video"
description: "Continue one video from its last frame and get one longer clip."
url: https://docs.roasos.com/workflows/extend-a-video
---

# Extend a video

Extend a video continues one video that your workspace owns. roasOS takes the last frame of the video, makes new footage from that frame, and joins the two parts. You get ONE longer clip: the source, then the new footage.

## 1. Choose the source

Send exactly one source.

| Field                  | Use it for                                                   |
| ---------------------- | ------------------------------------------------------------ |
| `video_url`            | A video on `https://cdn.roasos.com` that your workspace owns |
| `source_generation_id` | A finished video in your library                             |

The source plus the new footage must fit in 178 seconds. To extend a longer video, cut it first with `POST /v1/assembly/trim-video`.

## 2. Write a prompt

Send a `prompt` that says what happens next. The new footage starts at the last frame of the source.

```
She puts the cup down, smiles at the camera and walks out of frame.
```

## 3. Choose the model and the length

The default model is `seedance-2.5`. You can send any image-to-video model as `model`. Refer to [Models](/models).

| Field              | Rule                                                                                                                                          |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `duration_seconds` | The ADDED length. It must be one of the lengths of the model. The default is 5 seconds. `auto` is not accepted.                               |
| `resolution`       | Optional. It must be one of the resolutions of the model. When you send none, roasOS uses the model resolution that is closest to the source. |
| `generate_audio`   | Optional. Send it only to a model that has a sound switch.                                                                                    |

There is no `aspect_ratio`. The shape of the new footage follows the source.

## 4. Quote

Send `quote_only: true`. A quote spends nothing.

```bash
curl -X POST https://api.roasos.com/v1/workflows/extend \
  -H "Authorization: Bearer roasos_sk_..." \
  -H "Idempotency-Key: extend-cafe-001" \
  -H "Content-Type: application/json" \
  -d '{
    "video_url": "https://cdn.roasos.com/uploads/.../videos/....mp4",
    "prompt": "She puts the cup down and walks out of frame.",
    "duration_seconds": 5,
    "quote_only": true
  }'
```

The quote has two parts: the new footage and one merge credit.

```json
{
  "data": {
    "kind": "quote",
    "quote_id": "f70b2d51-...",
    "credits": 16,
    "credits_breakdown": { "continuation": 15, "merge": 1 },
    "pricing_version": "customer-pricing@2026-10-30.v14"
  }
}
```

5 seconds of new footage on `seedance-2.5` at 720p costs 15 credits. The merge costs 1 credit. The total is 16 credits.

## 5. Confirm

Send the same body with the `quote_id`. Use the same idempotency key. The answer is `201` with the job envelope of the new footage (the continuation).

## 6. Read the run

```bash
curl https://api.roasos.com/v1/workflows/extend/1e9c4a70-... \
  -H "Authorization: Bearer roasos_sk_..."
```

Use the job id from step 5. When the continuation completes, roasOS starts the merge. The run tells you where the work is.

| `stage`        | Meaning                                                                         |
| -------------- | ------------------------------------------------------------------------------- |
| `continuation` | The new footage is in progress.                                                 |
| `merging`      | The new footage is done. The merge is in progress.                              |
| `completed`    | `merged.result.url` is the one longer clip.                                     |
| `failed`       | The new footage failed and was refunded.                                        |
| `merge_failed` | The merge did not run. The new footage stays in your library and stays charged. |

A `webhook_url` in the confirm request is delivered for the joined clip, not for the continuation.

Both parts are ordinary jobs. They appear in `GET /v1/jobs` and in your library. Refer to [Jobs](/concepts/jobs).
