# How to edit and finish existing video with an API

> Edit footage you already have from a text prompt, swap the product, expand the frame, then upscale to 4K, convert to HDR and dub it through an API.

Author: Runway · Published: 2026-10-22 · Updated: 2026-10-22 · Source: https://dev.runway.com/learn/edit-and-finish-video-api

## Summary

Editing a video you already have through an API is a video-to-video request: you send the clip with an instruction, and the model removes, replaces or restyles what you ask for while the framing, motion, timing and sound stay. Finishing is a separate set of calls that upscale the edit to 4K, retime it, convert it to HDR last and clean or dub the dialogue. Runway Dev runs every step on one key, with Runway's Aleph 2.0 for edits and Ruby for HDR, as code, a [Workflow](https://dev.runway.com/workflows) or the [Product Swap Recipe](https://dev.runway.com/recipes).

## What does editing an existing video with an API involve?

A video edit changes part of a clip and keeps the rest. Regenerating the shot from a new prompt does the opposite, because a new take brings new framing, new motion and a new version of everything you had already approved.

The job splits into two kinds of call:

- **Editing** changes what is in the picture. It runs on `POST /v1/video_to_video`, where a model takes your clip and a text instruction.
- **Finishing** changes how the picture ships: resolution, frame rate, dynamic range and sound. Each is its own endpoint, with its own input limits.

Runway's guide to [AI in post production](https://runway.com/resources/ai-post-production) covers where AI fits in an editor's schedule. The sections below cover the endpoints, in the order a shot goes through them.

## What can you change in a video with an API?

Most of what is in the frame, from one object to the whole look, and the motion of one clip can drive another. These are the common edits, each with a prompt or an input that does it:

| Edit                                        | Example prompt or input                                         | On Runway Dev                                                                                |
| ------------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| Remove an object or on-screen text          | "Remove the red scooter from the lane"                          | Aleph 2.0                                                                                    |
| Replace the background or the location      | "Change the background to ancient city ruins"                   | Aleph 2.0                                                                                    |
| Change wardrobe or accessories              | "Change the outfit to a bright yellow fur coat"                 | Aleph 2.0                                                                                    |
| Swap a product or an object                 | "Swap the bag for a black leather clutch with a gold buckle"    | Aleph 2.0, or the Product Swap Recipe across a catalog                                       |
| Swap a character                            | A first frame with the new character in it, or reference images | Aleph 2.0 with a keyframe; Kling 4.0, Gemini Omni Flash 1.1 and Seedance 2.5 with references |
| Change the weather, the season or the light | "Heavy overcast and raining", "Chiaroscuro lighting"            | Aleph 2.0                                                                                    |
| Restyle the footage                         | "Make it a 1920s silent film"                                   | Aleph 2.0, Kling 4.0                                                                         |
| Add effects or new elements                 | "Fire begins to spread up the trees"                            | Aleph 2.0                                                                                    |
| Change the aspect ratio                     | `targetAspectRatio: '9:16'`                                     | Aleph 2.0                                                                                    |
| Transfer motion or a performance            | An actor's performance video and a character image              | Act-Two; Seedance 2.5 with a reference video                                                 |
| Extend a shot                               | "Continue the shot as the train pulls away"                     | Gemini Omni Flash 1.1 and Seedance 2.5 with `mode: "extend"`                                 |
| Change the voice                            | The clip and a preset voice                                     | Speech to speech                                                                             |

The prompts that work best pair a verb (remove, change, replace, relight, restyle) with the result you want, and many edits combine in one request.

## How do you edit a video from a text prompt, without a mask?

Send the clip and one sentence describing the change. Aleph 2.0 (`aleph2`) takes a `videoUri` and a `promptText` of up to 1,000 characters on [`POST /v1/video_to_video`](https://docs.dev.runwayml.com/api/#tag/Start-generating/paths/~1v1~1video_to_video/post), works out what the sentence refers to and changes only that, with no mask, tracking or rotoscoping on your side. The edit comes back at the clip's own resolution, up to 1080p, at its own frame rate and with its own audio track.

![Source clip](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-remove-source-20fad441.mp4 'One request with no mask removes the scooter and rebuilds the chair and the wall behind it, while the lane, the light and the sound stay. Drag the divider to compare the source with the edit.') ![Aleph 2.0 edit](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-remove-edit-54acba5e.mp4)

```text
Remove the red scooter from the lane. Keep the cobblestones, the café, the tables, the window boxes, the awning and the morning light exactly as they are.
```

Removing an object this way is what post-production calls inpainting, done from a sentence instead of a hand-drawn mask. The request is the same for a change of light, weather, season, wardrobe or style:

```javascript
import RunwayML from '@runwayml/sdk';

const client = new RunwayML();

const task = await client.videoToVideo
  .create({
    model: 'aleph2',
    videoUri: 'https://example.com/shot.mp4',
    promptText:
      'Remove the red scooter from the lane. Keep everything else exactly as it is.',
  })
  .waitForTaskOutput();

console.log(task.output[0]);
```

Two habits make prompt edits predictable. Name the thing the way you would point at it on screen ("the red scooter by the green door") and say what has to stay.

## How do you control what a video edit changes?

Beyond the prompt, an Aleph 2.0 request takes three controls, and a mask or a crop adds two more from your own code.

**Keyframes show the result.** `keyframes` takes up to five images, each placed by `seconds` or by `at`, a fraction of the clip's length. An edited still of the first frame is a precise brief: change one frame in an image model, then let Aleph 2.0 carry the change through the clip. Make the still at the clip's own aspect ratio and ask for the same framing, because Aleph 2.0 follows the keyframe, and an image model asked for a different shape recomposes the scene to fill it.

![The source clip's first frame, edited into a snowy winter day: snow on the dock, the hills and the pines, frost on the reeds, the lake still open water](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/images/edit-and-finish-video-api/keyframe-winter-d894d355.jpg 'Keyframe at 0 seconds')

![Source clip](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-keyframe-source-f3cee147.mp4 'The first frame, edited into winter with Nano Banana Pro at the same 16:9 framing and sent as a keyframe at 0 seconds: Aleph 2.0 carries the snow through the whole clip while the water keeps moving.') ![Aleph 2.0 edit](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-keyframe-edit-9909c89f.mp4)

```text
Turn the scene into a snowy winter day, as in the keyframe: fresh snow on the dock, the hills and the pines, frost on the reeds, a pale overcast sky. The lake stays open water with the same ripples. Keep the camera and the composition the same.
```

**A range limits the edit in time.** Give every keyframe a `range` with `start_seconds` and `end_seconds`, and the edit applies only inside that window. The rest of the clip is returned as it was, with the original audio across the whole output. Ranged edits return MP4 only, take sources up to 4,096 pixels on a side and can't be combined with `targetAspectRatio`.

**The seed repeats a result.** The same `seed` with the same request gives a similar edit again, which keeps a batch consistent while you change one input at a time.

**A mask limits the edit to part of a frame.** The video endpoints take no mask, but a keyframe can be made with one: Ideogram 4.5 on `POST /v1/text_to_image` takes a `maskUri`, a black-and-white image the size of the frame where black is edited and white is kept. Edit the first frame inside the mask, then send it to Aleph 2.0 as the keyframe, as in the character swap below.

**A crop keeps the rest of the shot exactly as it was.** Crop the region, edit the crop, then lay it back over the source: everything outside the crop comes from the source, not from the model. A smaller frame also leaves the model less to change.

Burned-in subtitles are the usual case. The prompt "Remove the subtitles from the bottom of the frame. Change nothing else." clears them from the full frame, and the crop is for a delivery spec that allows no change anywhere else. A strip works as input: the 1920 by 360 lower third of a 1080p shot goes to Aleph 2.0 as it is.

```bash
# Cut out the bottom third, where the subtitles are
ffmpeg -i shot.mp4 -vf "crop=iw:ih/3:0:ih*2/3" -c:a copy lower-third.mp4

# Edit lower-third.mp4 with Aleph 2.0, then lay the edit back over the source
ffmpeg -i shot.mp4 -i lower-third-edited.mp4 -filter_complex "[0:v][1:v]overlay=0:H*2/3[v]" \
  -map "[v]" -map 0:a -c:a copy shot-clean.mp4
```

## How do you swap a character in a video with an API?

Make the first frame with the new character in it, then let Aleph 2.0 carry the swap through the clip. A mask keeps the frame's edit to the character: the masked area of the first frame is replaced with the character from a reference image, and everything else in the still stays as shot, so the keyframe matches the clip exactly.

![The black-and-white mask over the walker in the first frame: black where the edit goes, white everywhere else](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/images/edit-and-finish-video-api/swapchar-mask-f7a81a06.jpg 'Mask') ![A white humanoid robot seen from behind, mid-stride, on a light gray background](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/images/edit-and-finish-video-api/swapchar-robot-8de36652.jpg 'Character reference') ![The first frame with the walker replaced by the white robot, seen from behind on the boardwalk](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/images/edit-and-finish-video-api/swapchar-keyframe-86712d60.jpg 'Keyframe at 0 seconds')

![Source clip](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-swapchar-source-7b805364.mp4 'The robot takes over from the walker for the whole clip, with the same path, steps and speed, while the dune grass and the sea stay as shot. Ideogram 4.5 made the keyframe inside the mask, and Aleph 2.0 made the clip.') ![Aleph 2.0 edit](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-swapchar-edit-efba9f18.mp4)

```text
Replace the person in the red coat with the white robot from the keyframe, walking away along the boardwalk with the same steps and speed. Keep the boardwalk, the dune grass, the sea and the light exactly the same.
```

The two calls, with the mask, the first frame and the character image already uploaded:

```javascript
const still = await client.textToImage
  .create({
    model: 'ideogram_4_5',
    promptText:
      'In the masked area, replace the person in the red coat with the white robot from the second reference image, seen from behind, walking away along the boardwalk at the same size and position.',
    referenceImages: [{ uri: firstFrame }, { uri: robotImage }],
    maskUri: mask,
  })
  .waitForTaskOutput();

const edit = await client.videoToVideo
  .create({
    model: 'aleph2',
    videoUri: shot,
    promptText:
      'Replace the person in the red coat with the white robot from the keyframe, walking away along the boardwalk with the same steps and speed.',
    keyframes: [{ uri: still.output[0], seconds: 0 }],
  })
  .waitForTaskOutput();
```

Describe the pose as well as the character. An image model can turn the new character toward the camera when the person in the clip faces away, so show the pose in the reference image and say it in the prompt. Kling 4.0, Gemini Omni Flash 1.1 and Seedance 2.5 take reference images directly on their edits, so a character or a product can also go in as a reference with no keyframe.

## How do you transfer motion from one video to another with an API?

Act-Two on `POST /v1/character_performance` moves a character with a performance you record. Send the character as an image or a video, and a reference video of 3 to 30 seconds of someone performing, with their face in frame: Act-Two applies the facial expressions to the character, and the body movement too with `bodyControl`, at an `expressionIntensity` from 1 to 5.

For motion beyond a performance, such as the camera move of one shot or the choreography of another, Seedance 2.5 in its default `reference` mode generates a new clip guided by the video you send, so the motion carries over while the prompt and reference images change the subject or the style.

## How do you change a video's aspect ratio with an API?

Set `targetAspectRatio` on an Aleph 2.0 request. The model letterboxes the clip to the new ratio and generates the missing picture in the bars, so a 16:9 master becomes a 9:16 cut for vertical feeds without losing the edges of the shot. It takes `16:9`, `4:3`, `3:2`, `1:1`, `2:3`, `3:4`, `9:16` and `21:9`, and the prompt can describe what the new area shows.

![Source, letterboxed to 9:16](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-expand-source-6fc21504.mp4 'One request turns a 16:9 shot into a 9:16 cut. Aleph 2.0 letterboxes the clip, as on the left, then generates the gorge above and the pool below, with no seam where the original frame ends.') ![Aleph 2.0 at 9:16](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-expand-edit-af26b53e.mp4)

```text
Extend the same gorge into the new space above and below: more mossy rock face and hanging ferns above the falls, and below, the shallow pool the water falls into, with mossy stones at its edge. One continuous scene in the same light, with no visible edge where the original frame ends.
```

Cropping is still the right reframe when the subject already fits inside the narrower frame. Expanding is for the shots where it doesn't.

## Which models can edit a video through an API?

The choice turns on how long the clip is, what size it has to come back at and whether the edit needs reference images. These are the models that edit a clip on `POST /v1/video_to_video` today:

| Model                                                     | What it edits                                                            | Source clip                                     | What comes back                                                            |
| --------------------------------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------- | -------------------------------------------------------------------------- |
| Aleph 2.0 (`aleph2`)                                      | Prompt and keyframe edits, ranged edits, expanding the frame             | 2 to 30 seconds                                 | The source's resolution up to 1080p, its audio, MP4, ProRes, PNG or 10-bit |
| Kling 4.0 (`kling_4`)                                     | Prompt edits, with up to 10 reference images                             | 3 to 30 seconds, each side at least 700 pixels  | 720p or 1080p, as long as the source and in its framing                    |
| [Gemini Omni Flash 1.1](https://dev.runway.com/learn/gemini-omni-flash-1-1-api) | Prompt edits with `mode: "edit"`, with up to five reference images       | Up to 10 seconds                                | 720p in the source's orientation, as long as the source                    |
| [Seedance 2.5](https://dev.runway.com/learn/seedance-2-5-api)                   | Prompt edits with `mode: "edit"`, with image, video and audio references | Up to 30 seconds of video in all, at least 480p | A clip as long as the source, with sound generated by default              |

All of them run on the same endpoint with one Runway Dev key, and the body changes with `model`. Gemini Omni Flash 1.1 and Seedance 2.5 edits take `duration: "auto"` and return a clip as long as the one you send. [Kling O3](https://dev.runway.com/learn/kling-o3-api) also edits on this endpoint, with a 4K tier, on clips of up to 10 seconds. Seedance 2.0 and MiniMax H3 take a video there too, as a reference for a new clip rather than as footage to edit.

## Which output formats can a video edit come back in?

Aleph 2.0 returns an H.264 MP4 by default, and `outputFormat` switches the container for an editorial or VFX pipeline:

| `outputFormat`     | What comes back                                                                                                  |
| ------------------ | ---------------------------------------------------------------------------------------------------------------- |
| `mp4`              | H.264 `.mp4` (the default)                                                                                       |
| `prores`           | ProRes `.mov`, with `proresProfile` of `422 Proxy`, `422 LT`, `422`, `422 HQ`, `4444` (the default) or `4444 XQ` |
| `png_sequence`     | A `.zip` of PNG frames, plus a separate `.wav` when the clip has audio                                           |
| `sdr_rec709_10bit` | HEVC Main 10 in Rec.709, for a grade that needs more precision than 8-bit                                        |

All four are standard dynamic range, and the alpha channel in a `4444` file is present but fully opaque. The three formats beyond MP4 add a charge per second, listed on the [pricing page](https://dev.runway.com/pricing), and the [professional outputs guide](https://docs.dev.runwayml.com/guides/professional-outputs/) covers each one. An edit reaches HDR through Ruby, after the other steps.

## How do you upscale a video to 4K or change its frame rate with an API?

Both run on `POST /v1/video_upscale`, chosen by `model`.

**4K**: the Magnific Video Upscaler (`magnific_video_upscaler_creative`) takes a clip of up to 30 seconds and returns it at `720p`, `1k`, `2k` or `4k`. The default is `2k`, so for 4K, set `resolution: '4k'`. `creativity` sets how much detail it adds, from 0 (faithful to the source) to 100, and `sharpen`, `smartGrain`, `flavor` (`vivid` or `natural`) and `fpsBoost` tune the rest.

![720p source, scaled 3x](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-upscale-720p-d33d9ffc.mp4 'One detail of a 720p clip: scaled up three times on the left, upscaled to 4K by the Magnific Video Upscaler on the right. The default request adds detail as it upscales, so the soft whiskers behind the ear come back sharp.') ![4K upscale](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-upscale-4k-c64eab45.mp4)

**Frame rate**: Enhance Frame Rate (`enhance_frame_rate`) converts a clip of up to 300 seconds to `24`, `25`, `30`, `48`, `50`, `60` or `120` fps, or to the broadcast rates `23_98`, `29_97` and `59_94`.

Upscale first, then retime. The upscaler is billed per output frame, so raising the frame rate before it multiplies the cost of the upscale, while Enhance Frame Rate is billed per second of input at any resolution.

## How do you convert SDR video to HDR with an API?

Send the SDR clip to Ruby (`ruby`) on [`POST /v1/video_to_hdr`](https://docs.dev.runwayml.com/api/#tag/Start-generating/paths/~1v1~1video_to_hdr/post). Ruby is Runway's HDR grading model: it extends the clip's own luma and color into the HDR range instead of generating a new picture, and it takes sources of up to 30 seconds and up to 4K.

| `outputFormat`                                               | What comes back                                                                                   |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| `hdr10`                                                      | HEVC Main 10, BT.2020 with PQ, `.mp4` (the default)                                               |
| `hlg`                                                        | HEVC Main 10, BT.2020 with HLG, `.mp4`                                                            |
| `hdr_prores`                                                 | BT.2020 with PQ in ProRes `.mov`, with `proresProfile` of `422`, `422 HQ` (the default) or `4444` |
| `hdr_exr_sequence`                                           | A `.zip` of half-float OpenEXR frames in linear BT.2020 light, with a colorimetry sidecar         |
| `hdr_exr_acescg_sequence_1_3`, `hdr_exr_acescg_sequence_2_0` | The same EXR frames as scene-referred ACEScg, for ACES 1.3 or ACES 2.0 pipelines                  |

![SDR source](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-hdr-sdr-10ca4d40.mp4 'The same sunrise in SDR on the left and after Ruby on the right, delivered as HDR10. On an HDR display the sun, the lens flare and the dew on the ferns run brighter than SDR white while the bark keeps its detail. Safari and Chrome play the HDR side, and an SDR screen shows it tone-mapped.') ![Ruby HDR10](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-hdr-hdr10-939e0644.mp4)

Make HDR the last picture step. Every editing and upscaling step on this page works in SDR, so a step after Ruby can't carry the range it added. Which format to export depends on where the file goes next, and [what HDR video is, and when your product needs it](https://dev.runway.com/learn/what-is-hdr-video) covers that decision.

## How do you clean up dialogue or dub a video with an API?

Voice isolation and dubbing take audio, not video, so the step around them is yours: extract the track, process it, then put it back under the picture.

- **Voice isolation**: `eleven_voice_isolation` on `POST /v1/voice_isolation` strips background noise and ambience from a recording between 4.6 seconds and one hour long, and returns the voice alone.
- **Dubbing**: `eleven_voice_dubbing` on `POST /v1/voice_dubbing` translates the speech into one of 29 languages set by `targetLang`, in the original speaker's voice unless `disableVoiceCloning` is set. `dropBackgroundAudio` drops the background from the dub, and `numSpeakers` replaces automatic speaker detection.

An MP4 sent as `audioUri` fails with a 400 ("Expected valid audio contentType"). ffmpeg does both ends of the round trip:

```bash
# Take the audio track out of the clip
ffmpeg -i shot.mp4 -vn -c:a pcm_s16le dialogue.wav

# Put the dubbed track back under the picture, without re-encoding the video
ffmpeg -i shot.mp4 -i dub-es.mp3 -map 0:v -map 1:a -c:v copy -c:a aac -shortest shot-es.mp4
```

`-c:v copy` passes the picture through untouched, HDR10 included. To change who is speaking rather than the language, speech to speech (`eleven_multilingual_sts_v2` on `POST /v1/speech_to_speech`) takes the video itself, re-voices it with one of 49 preset voices and returns the video.

## How do you chain editing, upscaling, HDR and dubbing in one pipeline?

Each call returns a task, and the output of one task is the input of the next. The picture goes through the edit, the upscale, the retime and HDR, and the audio through extraction, isolation and dubbing. ffmpeg joins the two at the end. This script runs the whole chain with the Node SDK:

```javascript
import { execFileSync } from 'node:child_process';
import fs from 'node:fs';
import RunwayML from '@runwayml/sdk';

const client = new RunwayML(); // reads RUNWAYML_API_SECRET

const upload = async path =>
  (await client.uploads.createEphemeral({ file: fs.createReadStream(path) }))
    .uri;
const save = async (url, path) =>
  fs.writeFileSync(path, Buffer.from(await (await fetch(url)).arrayBuffer()));
// Video URLs are capped at 32 MB, so each output goes on as an upload (200 MB).
const pass = async (task, path) => {
  await save(task.output[0], path);
  return upload(path);
};
const ffmpeg = args =>
  execFileSync('ffmpeg', ['-y', '-v', 'error', ...args.split(' ')]);
// A 4K upscale can outlast the SDK's default 10-minute wait.
const wait = { timeout: 60 * 60 * 1000 };

// 1. Edit the picture. Aleph 2.0 returns the clip with its own audio.
const edit = await client.videoToVideo
  .create({
    model: 'aleph2',
    videoUri: await upload('shot.mp4'),
    promptText:
      'Remove the red scooter from the lane. Keep everything else exactly as it is.',
  })
  .waitForTaskOutput(wait);

// 2. Upscale to 4K at the clip's own frame rate.
const uhd = await client.videoUpscale
  .create({
    model: 'magnific_video_upscaler_creative',
    videoUri: await pass(edit, 'edit.mp4'),
    resolution: '4k',
  })
  .waitForTaskOutput(wait);

// 3. Retime to the delivery frame rate.
const retimed = await client.videoUpscale
  .create({
    model: 'enhance_frame_rate',
    videoUri: await pass(uhd, 'uhd.mp4'),
    targetFramerate: '59_94',
  })
  .waitForTaskOutput(wait);

// 4. Convert to HDR last.
const hdr = await client.videoToHdr
  .create({
    model: 'ruby',
    videoUri: await pass(retimed, 'retimed.mp4'),
    outputFormat: 'hdr10',
  })
  .waitForTaskOutput(wait);

// 5. Audio: extract the track, isolate the dialogue, dub it into Spanish.
ffmpeg('-i shot.mp4 -vn -c:a pcm_s16le dialogue.wav');
const clean = await client.voiceIsolation
  .create({
    model: 'eleven_voice_isolation',
    audioUri: await upload('dialogue.wav'),
  })
  .waitForTaskOutput(wait);
const dub = await client.voiceDubbing
  .create({
    model: 'eleven_voice_dubbing',
    audioUri: await pass(clean, 'clean.mp3'),
    targetLang: 'es',
  })
  .waitForTaskOutput(wait);

// 6. Put the dubbed track under the finished picture.
await save(hdr.output[0], 'picture.mp4');
await save(dub.output[0], 'dub-es.mp3');
ffmpeg(
  '-i picture.mp4 -i dub-es.mp3 -map 0:v -map 1:a -c:v copy -c:a aac -shortest final-es.mp4'
);
```

Three things keep a chain like this working:

- **Pass files, not links.** A video URL input is capped at 32 MB, and five seconds of 4K came back at 55 MB, so the script saves each output and sends it on as an ephemeral upload, which takes up to 200 MB. Output URLs are temporary, so the saved copies are also the ones you keep.
- **Wait long enough.** A 4K upscale can run past the SDK's default 10-minute wait, so the script passes its own `timeout` to `waitForTaskOutput`.
- **Split long cuts.** A clip longer than 30 seconds is split at its cuts into shots, each run through the chain, then joined again.

Images fit the same pattern. An edited still from an image model is the keyframe an Aleph 2.0 request takes, so one pipeline can start from text-to-image and end on dubbed HDR video.

## How long can a video be for an API edit?

Thirty seconds per call covers most shots and ads. Aleph 2.0, Kling 4.0, Seedance 2.5, the upscaler and Ruby each take up to 30 seconds, Gemini Omni Flash 1.1 edits up to 10, Enhance Frame Rate up to 300, and the Product Swap Recipe a reference video of 1.8 to 15 seconds. A clip with several cuts goes to Aleph 2.0 as it is.

A longer piece is split at its cuts into shots, each shot runs through the same calls, and the results are joined again, with ffmpeg in code or the Stitch Videos node in a Workflow.

## How do you batch edit hundreds of videos with an API?

Batch editing runs the same calls once per clip, so what changes is the code around them:

- **A failure repeats what came before it.** Without a checkpoint per step, a failed dub re-runs the edit and the upscale you already paid for, so store each step's output and retry from the step that failed.
- **The order sets the bill.** Upscaling at the source's frame rate and converting to HDR last keep each step at its smallest billed unit, across every clip in the batch.

## Can you publish the whole pipeline as one endpoint?

Yes. [Workflows](https://dev.runway.com/workflows) on Runway Dev turn the chain into one API endpoint. You build it in the [Runway app](https://app.runwayml.com/workflows) by connecting nodes, with no code, then [publish it as an endpoint](https://help.runwayml.com/hc/en-us/articles/50682960972947-Publishing-a-Workflow-as-an-Endpoint) and call it with your Runway Dev key.

The editor has a node for each step of this pipeline. For the edit: Aleph 2, Kling 4.0, Gemini Omni Flash (Video Edit) and Seedance 2.5 (Edit/Extend Video). For finishing: Upscale Video (Topaz), Update FPS and Convert to HDR. For the sound: Extract Audio, Voice Isolation, Voice Dubbing and Add Audio, so the remux happens inside the graph. Convert to HDR is a terminal node, so the editor keeps HDR as the last step for you.

- **The endpoint stays the same.** Swap a model or rewrite a prompt in the editor, and every call to the endpoint runs the new version.
- **The person who tunes the edit doesn't need your codebase.** An editor or a creative team changes the graph visually.
- **Billing is per step, from your Runway Dev credits.** If a step fails, the run stops there: you pay for the steps that succeeded and are refunded for the failed step and everything after it.

## How do you replace the product in a video ad with an API?

Use the [Product Swap Recipe](https://docs.dev.runwayml.com/recipes/product-swap/) replaces the product in an existing video with a new one and keeps the camera motion, lighting and composition, so one approved ad becomes a version for every product in a catalog.

![The plain white ceramic mug, cropped from the first frame of the reference video](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/images/edit-and-finish-video-api/swap-original-mug-a221d89c.jpg 'Original product') ![A speckled sage-green stoneware mug with a round handle on a light gray background](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/images/edit-and-finish-video-api/swap-new-mug-3e9acc91.jpg 'New product, front view')

![Reference video](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-swap-source-980e9802.mp4 'The Product Swap Recipe puts the green mug where the white one stood, with the same push-in, light and table. Drag the divider to compare the reference video with the swap.') ![Product Swap output](https://d3phaj0sisr2ct.cloudfront.net/devportal/learn/edit-and-finish-video-api-swap-edit-a50c7633.mp4)

A clean swap depends on choosing the model, writing the prompt and designing the steps around it, and all three are specialist work. Runway trains frontier models, so it knows how they behave, and its technical artists build these pipelines for a living. A Recipe is that expertise packaged as one endpoint:

```javascript
import RunwayML from '@runwayml/sdk';

const client = new RunwayML();

const task = await client.recipes
  .productSwap({
    version: '2026-06',
    referenceVideo: { uri: 'https://example.com/approved-ad.mp4' },
    originalProductImage: { uri: 'https://example.com/white-mug.png' },
    newProductImages: [
      { uri: 'https://example.com/green-mug-front.png', view: 'front' },
    ],
    duration: 8,
    resolution: '1080p',
  })
  .waitForTaskOutput();
```

The fields are the brief, not the pipeline. `referenceVideo` runs 1.8 to 15 seconds, `originalProductImage` shows the product to replace and `newProductImages` takes one to ten photos of the new one, each with an optional `view` of `front`, `side` or `back`. `duration` runs 4 to 15 seconds (10 by default) and `resolution` is `720p` (the default) or `1080p`. `audio` is on unless you turn it off. Swaps work best like for like, one mug for another rather than a mug for a hairbrush. Pin `2026-06` to keep the output stable, or send `unsafe-latest` to take each improvement as Runway ships it.

## What does it cost to edit and finish a video with an API?

Each step is billed in its own unit, so the total depends on the clip's length, size and frame rate, and on the order of the steps:

- **Aleph 2.0**: per second of the clip, with a minimum per request. ProRes, PNG and 10-bit outputs add a charge per second.
- **Kling 4.0, Gemini Omni Flash 1.1 and Seedance 2.5**: per second, with the length of the clip you send counted in the bill. A `duration` of `auto` reserves the most a clip can cost when the task starts and refunds the rest when it finishes. The [Gemini Omni Flash 1.1](https://dev.runway.com/learn/gemini-omni-flash-1-1-api) and [Seedance 2.5](https://dev.runway.com/learn/seedance-2-5-api) pages carry their live rates.
- **The upscaler**: per output frame, with a higher rate at 2K and 4K.
- **Enhance Frame Rate**: per second of input.
- **Ruby**: per second, with a higher rate above 4 megapixels (roughly 4K).
- **Voice isolation and dubbing**: per second of audio.
- **Product Swap**: a base price for the first four seconds, then a rate per extra second, at 720p or 1080p.

Every create request returns `estimatedCost.credits`, the most that task can charge, before it runs. Live rates for every model are on the [pricing page](https://dev.runway.com/pricing).

The larger cost is the take you throw away. An edit fixes the one thing that is wrong in a shot you approved and costs one request. Regenerating to fix it buys a new take of everything else, and usually several of them before one matches the rest of the cut.

## Which approach should you use to edit existing video?

- **The Product Swap Recipe** when the job is putting a new product into an approved video. It is the default for catalog versions of an ad, unless the shot runs past 15 seconds or the new product doesn't fit the old one's action.
- **A Workflow** when you know the steps and the models, and want one endpoint that a creative team can tune without a deploy.
- **The endpoints in code** when each clip needs its own logic: a prompt per shot, a ranged edit, a crop and composite, or your own quality check between steps.

## FAQ

**What's the best API for editing an existing video with AI?**

Look for prompt edits without a mask, a source length that fits your shots, output at the size you ship and the original audio kept. On Runway Dev, Aleph 2.0 edits clips of up to 30 seconds with keyframes, time ranges and frame expansion, and Kling 4.0, Gemini Omni Flash 1.1 and Seedance 2.5 edit on the same endpoint.

**Is there an API to upscale video to 4K?**

Yes. The Magnific Video Upscaler on Runway Dev, `magnific_video_upscaler_creative` on `POST /v1/video_upscale`, returns clips of up to 30 seconds at 4K when you set `resolution` to `4k`. It is billed per output frame, so upscale before raising the frame rate.

**How do I convert SDR video to HDR with an API?**

Send the clip to Ruby on Runway Dev's `POST /v1/video_to_hdr`. It takes SDR sources of up to 30 seconds and 4K, and returns HDR10 or HLG HEVC, BT.2020 ProRes, or OpenEXR frames in linear light or ACEScg. Run it after every other picture step.

**How do I chain image, video and audio generation APIs into one pipeline?**

Pass each task's output to the next request: an image model for a keyframe, Aleph 2.0 for the edit, the upscaler, Ruby, then voice isolation and dubbing on the extracted audio. Files over 32 MB go on as uploads. On Runway Dev, the same chain can also run as one Workflow endpoint.

**Can I remove an object from a video without drawing a mask?**

Yes. Describe the object in the prompt, for example "Remove the red scooter from the lane", and Aleph 2.0 on Runway Dev removes it and fills in what was behind it. Say what has to stay unchanged in the same sentence. To limit an edit to an exact area, make the keyframe with a mask in Ideogram 4.5.

**How do I swap a character in a video with an API?**

Put the new character in the first frame, then send that frame to Aleph 2.0 as a keyframe. On Runway Dev, Ideogram 4.5 edits the frame inside a mask, so the rest stays as shot. Kling 4.0, Gemini Omni Flash 1.1 and Seedance 2.5 also take the character as a reference image.

**Is there a motion transfer API?**

Yes. Act-Two on Runway Dev's `POST /v1/character_performance` drives a character image or video with a 3 to 30 second performance video, face and body included. Seedance 2.5 in `reference` mode carries the motion of a video into a new clip.

**How do I remove burned-in subtitles or on-screen text with an API?**

Ask for it in the prompt, such as "Remove the subtitles from the bottom of the frame. Change nothing else." on Aleph 2.0. When the rest of the frame must stay identical, crop the text region, edit the crop and composite it back over the source.

**How do I reframe a video to 9:16 or 1:1 with an API?**

Set `targetAspectRatio` on an Aleph 2.0 request. It letterboxes the clip and generates the missing picture, with eight ratios from `21:9` to `9:16`. Cropping works when the subject already fits the narrower frame.

**Does a video edit keep the original audio?**

Aleph 2.0 returns the edit with the source clip's own audio track. To change the dialogue, extract the audio and run it through voice isolation or dubbing.

**Can a video API return ProRes, EXR or ACES files?**

Yes. On Runway Dev, Aleph 2.0 returns ProRes in six profiles, PNG sequences or 10-bit Rec.709 HEVC, and Ruby returns BT.2020 ProRes, OpenEXR sequences and ACEScg frames for ACES 1.3 or 2.0.

**Is there an AI dubbing API that keeps the speaker's voice?**

Yes. `eleven_voice_dubbing` on Runway Dev dubs into 29 languages in the original speaker's voice by default, with `disableVoiceCloning` for a generic voice. It takes audio, so extract the track from the video first and remux the dub.

**How much does it cost to edit and finish a video with an API?**

Each step bills its own unit on Runway Dev: per second for Aleph 2.0, Ruby and audio, per output frame for the upscaler. Every request returns `estimatedCost.credits` before it runs, and the [pricing page](https://dev.runway.com/pricing) lists the live rates.

**Can I use edited videos commercially?**

You need the rights to the footage you edit. Runway Dev doesn't claim the outputs and doesn't restrict their commercial use. [Can I use AI image and video generation commercially in my product?](https://dev.runway.com/learn/commercial-use) covers the rest.

**Will my results change when models update?**

A request names a model ID, so it runs the model you chose until you change it. Recipes take a dated `version` such as `2026-06` to stay fixed, or `unsafe-latest` to follow improvements, and a published Workflow keeps its endpoint when you update the graph.
