Core API: generation endpoints, task polling, inputs and outputs, errors, versioning, and billing
---
# API Documentation
> Access complete Runway Dev documentation. Find guides, references and resources to integrate AI video generation into your applications and products.
Runway Dev lets you bring our most powerful and popular generative models directly into your apps, products, platforms and websites. [Get started today](https://dev.runway.com/).
**New:** Seedance 2.5 now supports 1080p. Cinematic video up to 30 seconds with a large reference budget for images, videos, and audio.
[Get started with Seedance 2.5 →](/api#tag/Start-generating/paths/~1v1~1image_to_video/post)
## Models
[](/api#tag/Start-generating/paths/~1v1~1image_to_video/post)
[](/api#tag/Start-generating/paths/~1v1~1image_to_video/post)
[](/api/#tag/Start-generating/paths/~1v1~1video_to_video/post)
[](/api#tag/Start-generating/paths/~1v1~1text_to_image/post)
View available models and details [here](guides/models).
## Start Building
[Connect Dev MCP ](/guides/mcp)Connect Cursor, Claude Code, or Codex to your Runway Dev account
[Using the API ](/guides/using-the-api)Create your first generation on Runway Dev
[API Reference ](/api)Read about how to interact with the API
[Go-live checklist ](/guides/go-live)Prepare your integration for launch
[Runway Agent Skills ](https://github.com/runwayml/skills)Community tools, examples, and agent skills for Runway Dev
## Quickstart
Get started by following our [API guide](/guides/using-the-api) or jump right into the example of using the Gen-4.5 model below:
* Node
```ts
import RunwayML, { TaskFailedError } from '@runwayml/sdk';
const client = new RunwayML();
try {
// Create a new text-to-video task using the "gen4.5" model
const task = await client.imageToVideo
.create({
model: 'gen4.5',
promptText: 'A serene mountain landscape at sunrise with mist rolling through the valleys',
ratio: '1280:720',
duration: 5,
})
.waitForTaskOutput();
console.log('Task complete:', task);
console.log('Video URL:', task.output[0]);
} catch (error) {
if (error instanceof TaskFailedError) {
console.error('The video failed to generate.');
console.error(error.taskDetails);
} else {
console.error(error);
}
}
```
* Python
```python
from runwayml import RunwayML, TaskFailedError
client = RunwayML()
try:
task = client.image_to_video.create(
model='gen4.5',
prompt_text='A serene mountain landscape at sunrise with mist rolling through the valleys',
ratio='1280:720',
duration=5,
).wait_for_task_output()
print('Task complete:', task)
print('Video URL:', task.output[0])
except TaskFailedError as e:
print('The video failed to generate.')
print(e.task_details)
```
## Enterprise Scale
Runway Dev has been used by the world’s largest consumer technology companies to reliably generate millions of videos for their users.
To request higher usage than [the self-serve tiers](./usage/tiers#tiers), you can submit an exception request on the usage page of your developer portal.
### Enterprise Benefits
In addition to higher rate limits, enterprise customers receive:
* Faster support via Slack (or email) channels
* Earliest access to new features
* Direct access to provide product feedback and request features
* Implementation and usage tips
* Custom payment terms
---
# API Setup & Configuration
> Set up Runway Dev for your application. Follow our configuration guide for authentication, environments and initial integration setup.
Runway offers the most cutting-edge generative video models. You can start using our models in your application with only a few quick steps.
## Set up a project
First, sign up for an account in [the developer portal](https://dev.runway.com/). After signing up, you’ll be presented with an option to create a new project. A project corresponds to your integration, and contains resources like API keys and configuration.
### Create a key
Once you’ve created a project, click to the API Keys tab. You’ll create a new key, giving it a name. Call it something descriptive, like “Matt Testing” so you can revoke the key later if needed. Creating and disabling keys needs the Admin or Developer role — see [Projects and roles](/usage/organizations-and-roles).
The key will be presented to you only once: immediately copy it someplace safe, like a password manager. We’ll never return the key in plaintext again; if you lose the key, you’ll need to disable it and create a new one.
Removing a user from your project does not revoke their API key access. Because keys are project-scoped (not user-scoped), you must disable keys separately to fully cut off access.
### Add credits
Before you can start using the API, you’ll need to add credits to your project. Credits are used to pay for the compute resources used by your models. Visit the billing tab in the developer portal to add credits to your project. A minimum payment of $10 (at $0.01 per credit) is required to get started. Adding credits needs the Admin or Billing admin role.
## Start your integration
Now that you have a project and a key, you can start building on Runway Dev.
### Using your API key
When you make requests to the API, you’ll need to include your API key in the headers. Our SDKs will automatically add your key if it’s specified in the `RUNWAYML_API_SECRET` environment variable. You can export this in your shell for test purposes like so:
* macOS and Linux
```sh
export RUNWAYML_API_SECRET="key_123456789012345678901234567890"
```
* Windows
```powershell
setx RUNWAYML_API_SECRET "key_123456789012345678901234567890"
```
In a production environment, do not hard-code your key like this. Instead, securely load your key into environment variables using a secret manager or similar tool.
---
# Connect Runway Dev
> Connect Cursor, Claude Desktop, Claude Code, or Codex to your Runway Dev account over MCP. OAuth only. No API key is required in the client config.
Runway Dev lets a coding agent work against your [Developer Portal](https://dev.runway.com/) account from the editor: look up tasks, manage model routers, and read docs without copying an API key into `mcp.json`.
This is separate from the generation MCP at [mcp.runwayml.com](https://mcp.runwayml.com), which creates media in chat.
The server URL is the same in every client:
```text
https://dev.runwayml.com/mcp
```
Apps display the server as **Runway Dev**. CLI server identifiers cannot contain spaces, so the commands below use `runway-dev-mcp`.
Caution
Complete OAuth yourself in your normal browser. Do not ask an agent to automate the sign-in or approval steps.
## Cursor
One click adds the server. Cursor then opens a browser to sign in.
[Add Runway Dev to Cursor](https://cursor.com/install-mcp?name=Runway%20Dev\&config=eyJ1cmwiOiJodHRwczovL2Rldi5ydW53YXltbC5jb20vbWNwIiwiYXV0aCI6eyJDTElFTlRfSUQiOiJ0cGNfdHhTS3JHeENNRVVVYU56UjhQTGRjRSJ9fQ%3D%3D)
Or paste this into `~/.cursor/mcp.json` (or `.cursor/mcp.json` in a project) and restart Cursor:
```json
{
"mcpServers": {
"Runway Dev": {
"url": "https://dev.runwayml.com/mcp",
"auth": {
"CLIENT_ID": "tpc_txSKrGxCMEUUaNzR8PLdcE"
}
}
}
}
```
Then open **Settings → MCP**, find **Runway Dev**, and connect. Approve access in the browser when prompted.
## Claude Desktop
Claude Desktop uses the same custom connectors as Claude.ai. One click opens **Add custom connector** with the name and URL filled in.
[Add Runway Dev to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector\&connectorName=Runway%20Dev\&connectorUrl=https%3A%2F%2Fdev.runwayml.com%2Fmcp)
## Claude Code
Claude Code does not use Claude Desktop connectors. Add the server from a terminal:
```sh
claude mcp add --transport http --scope user runway-dev-mcp https://dev.runwayml.com/mcp
```
In a session, run `/mcp`, select **runway-dev-mcp**, and authenticate.
If Claude Code shows **Needs authentication**:
1. Run `/mcp`.
2. Select **runway-dev-mcp**.
3. Complete authentication in your normal browser.
4. Retry the MCP tool in the same Claude Code session.
5. Request a new session only if the authenticated tools remain unavailable.
Claude Code 2.1.186 or newer can also start authentication from a terminal:
```sh
claude mcp login runway-dev-mcp
```
Claude Code 2.1.191 or newer supports `--no-browser`. This option prints an authorization URL instead of opening a local browser:
```sh
claude mcp login runway-dev-mcp --no-browser
```
## Codex
Codex has a [known scope-discovery issue](https://github.com/openai/codex/issues/15643), so request the Runway scopes explicitly:
```sh
codex mcp add runway-dev-mcp --url https://dev.runwayml.com/mcp
codex mcp login runway-dev-mcp --scopes openid,profile,email,mcp:read,mcp:write
```
Or add the same URL in `~/.codex/config.toml`:
```toml
[mcp_servers.runway-dev-mcp]
url = "https://dev.runwayml.com/mcp"
```
Then run `codex mcp login runway-dev-mcp --scopes openid,profile,email,mcp:read,mcp:write` to complete browser login.
If Codex connects but reports a missing `mcp:read` scope, replace the cached authorization:
```sh
codex mcp logout runway-dev-mcp
codex mcp login runway-dev-mcp --scopes openid,profile,email,mcp:read,mcp:write
```
## After you connect
Ask the agent to call `whoami`. You should see your Developer Portal email. If that fails, authenticate with the client steps above and retry in the same session.
Do not put an API key in the MCP config. Keys stay in the Developer Portal, where you can rotate them.
---
# API Getting Started Guide
> Learn how to use Runway Dev for AI video generation. Follow our step-by-step guide to integrate Gen-4, image generation and more into your apps.
Before starting, you will need to create a [Runway Dev account](/guides/setup).
### Talking to the API
You can use the [Playground](https://dev.runway.com/playground) to test your code, or follow the examples below to get started.
* [Generating Video](#pill-tab-panel-0)
* [Generating Images](#pill-tab-panel-1)
In this example, we’ll use the `gen4.5` model to generate a video from an image using the text prompt “A timelapse on a sunny day with clouds flying by”. When building this into your app, you’ll want to replace the `promptImage` with a URL of an image and a `promptText` with your own text prompt.
* Node
First, you’ll want to install the Runway SDK. You can do this with npm:
```sh
npm install --save @runwayml/sdk
```
In your code, you can now import the SDK and start making requests:
```ts
import RunwayML, { TaskFailedError } from '@runwayml/sdk';
const client = new RunwayML();
// Create a new image-to-video task using the "gen4.5" model
try {
const task = await client.imageToVideo
.create({
model: 'gen4.5',
// Point this at your own image file
promptImage: 'https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_(cropped).jpg',
promptText: 'A timelapse on a sunny day with clouds flying by',
ratio: '1280:720',
duration: 5,
})
.waitForTaskOutput();
console.log('Task complete:', task);
} catch (error) {
if (error instanceof TaskFailedError) {
console.error('The video failed to generate.');
console.error(error.taskDetails);
} else {
console.error(error);
}
}
```
* Python
First, you’ll want to install the Runway SDK. You can do this with pip:
```sh
pip install runwayml
```
In your code, you can now import the SDK and start making requests:
```python
from runwayml import RunwayML, TaskFailedError
client = RunwayML()
# Create a new image-to-video task using the "gen4.5" model
try:
task = client.image_to_video.create(
model='gen4.5',
# Point this at your own image file
prompt_image='https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_(cropped).jpg',
prompt_text=' timelapse on a sunny day with clouds flying by',
ratio='1280:720',
duration=5,
).wait_for_task_output()
print('Task complete:', task)
except TaskFailedError as e:
print('The video failed to generate.')
print(e.task_details)
```
* Just testing
If you’re not ready to start writing code, you can test the API with cURL.
```sh
# Replace the example URL below with your own image URL
curl -X POST https://api.dev.runwayml.com/v1/image_to_video \
-d '{
"promptImage": "https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_(cropped).jpg",
"promptText": " timelapse on a sunny day with clouds flying by",
"model": "gen4.5",
"ratio": "1280:720",
"duration": 5
}' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $RUNWAYML_API_SECRET" \
-H "X-Runway-Version: 2024-11-06"
```
This command will start an image-to-video task using the “gen4.5” model. You’ll see a JSON response with the task ID printed in your terminal, which you can use to fetch the task status.
#### Uploading base64 encoded images as data URIs
You can also upload base64 encoded images (as a data URI) instead of pointing to an external URL. This can be useful if you’re working with a local image file and want to avoid an extra network round trip to upload the image.
To do this, simply pass the base64 encoded image string as a data URI in the `promptImage` field instead of a URL. For more information about file types and size limits, see the [Inputs](/assets/inputs) page.
* Node
```ts
import fs from 'node:fs';
import RunwayML, { TaskFailedError } from '@runwayml/sdk';
const client = new RunwayML();
// Read the image file into a Buffer. Replace `example.png` with your own image path.
const imageBuffer = fs.readFileSync('example.png');
// Convert to a data URI. We're using `image/png` here because the input is a PNG.
const dataUri = `data:image/png;base64,${imageBuffer.toString('base64')}`;
// Create a new image-to-video task using the "gen4.5" model
try {
const imageToVideo = await client.imageToVideo
.create({
model: 'gen4.5',
// Point this at your own image file
promptImage: dataUri,
promptText: 'A timelapse on a sunny day with clouds flying by',
ratio: '1280:720',
duration: 5,
})
.waitForTaskOutput();
console.log('Task complete:', task);
} catch (error) {
if (error instanceof TaskFailedError) {
console.error('The video failed to generate.');
console.error(error.taskDetails);
} else {
console.error(error);
}
}
```
* Python
```python
import base64
from runwayml import RunwayML
client = RunwayML()
image = './example.png'
# Encode image to a data URI
with open(image, "rb") as f:
# Read the file as a base64 encoded string
base64_image = base64.b64encode(f.read()).decode("utf-8")
# Format it as a data URI
# We're using `image/png` here because the input is a PNG.
data_uri = f"data:image/png;base64,{base64_image}"
# Create a new image-to-video task using the "gen4.5" model
try:
task = client.image_to_video.create(
model='gen4.5',
# Point this at your own image file
prompt_image=data_uri,
prompt_text='A timelapse on a sunny day with clouds flying by',
ratio='1280:720',
duration=5,
).wait_for_task_output()
print('Task complete:', task)
except runwayml.TaskFailedError as e:
print('The video failed to generate.')
print(e.task_details)
```
#### Text-to-video (without an input image)
Gen-4.5 also supports generating videos from text alone, without requiring an input image. Simply omit the `promptImage` parameter to use text-to-video mode.
* Node
```ts
import RunwayML, { TaskFailedError } from '@runwayml/sdk';
const client = new RunwayML();
// Create a new text-to-video task using the "gen4.5" model
try {
const task = await client.imageToVideo
.create({
model: 'gen4.5',
// No promptImage needed for text-to-video
promptText: 'A serene mountain landscape at sunrise with mist rolling through the valleys',
ratio: '1280:720',
duration: 5,
})
.waitForTaskOutput();
console.log('Task complete:', task);
} catch (error) {
if (error instanceof TaskFailedError) {
console.error('The video failed to generate.');
console.error(error.taskDetails);
} else {
console.error(error);
}
}
```
* Python
```python
from runwayml import RunwayML, TaskFailedError
client = RunwayML()
# Create a new text-to-video task using the "gen4.5" model
try:
task = client.image_to_video.create(
model='gen4.5',
# No prompt_image needed for text-to-video
prompt_text='A serene mountain landscape at sunrise with mist rolling through the valleys',
ratio='1280:720',
duration=5,
).wait_for_task_output()
print('Task complete:', task)
except TaskFailedError as e:
print('The video failed to generate.')
print(e.task_details)
```
In this example, we’ll use the `gen4_image` model to generate an image of the Eiffel Tower rendered in the style of the painting Starry Night. To do this, we’ll pass in reference images of the Eiffel Tower and Starry Night, and use the `promptText` to specify that we want the Eiffel Tower rendered in the style of Starry Night. Reference images can be referenced in the text prompt using at-mention syntax referencing the `tag` of the reference image.
* Node
```ts
import RunwayML, { TaskFailedError } from '@runwayml/sdk';
const client = new RunwayML();
// Create a new image generation task using the "gen4_image" model
try {
let task = await client.textToImage
.create({
model: 'gen4_image',
ratio: '1920:1080',
promptText: '@EiffelTower painted in the style of @StarryNight',
referenceImages: [
{
uri: 'https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_(cropped).jpg'
tag: 'EiffelTower',
},
{
uri: 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg/1513px-Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg',
tag: 'StarryNight',
},
],
})
.waitForTaskOutput();
console.log('Task complete:', task);
console.log('Image URL:', task.output[0]);
} catch (error) {
if (error instanceof TaskFailedError) {
console.error('The image failed to generate.');
console.error(error.taskDetails);
} else {
console.error(error);
}
}
```
* Python
```python
from runwayml import RunwayML, TaskFailedError
client = RunwayML()
try:
task = client.text_to_image.create(
model='gen4_image',
ratio='1920:1080',
prompt_text='@EiffelTower painted in the style of @StarryNight',
reference_images=[
{
'uri': 'https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_(cropped).jpg',
'tag': 'EiffelTower',
},
{
'uri': 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg/1513px-Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg',
'tag': 'StarryNight',
},
],
).wait_for_task_output()
print('Task complete:', task)
print('Image URL:', task.output[0])
except TaskFailedError as e:
print('The image failed to generate.')
print(e.task_details)
```
* Just testing
If you’re not ready to start writing code, you can test the API with cURL.
```sh
# Replace the example URL below with your own image URL
curl -X POST https://api.dev.runwayml.com/v1/text_to_image \
-d '{
"promptText": "@EiffelTower painted in the style of @StarryNight",
"model": "gen4_image",
"ratio": "1920:1080",
"referenceImages": [
{
"uri": "https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_(cropped).jpg",
"tag": "EiffelTower"
},
{
"uri": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg/1513px-Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg",
"tag": "StarryNight"
}
]
}' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $RUNWAYML_API_SECRET" \
-H "X-Runway-Version: 2024-11-06"
```
#### Uploading base64 encoded images as data URIs
You can also upload base64 encoded images (as a data URI) instead of pointing to an external URL. This can be useful if you’re working with a local image file and want to avoid an extra network round trip to upload the image.
To do this, simply pass the base64 encoded image string as a data URI in the `uri` of a `referenceImage` object instead of a URL. For more information about file types and size limits, see the [Inputs](/assets/inputs) page.
In this example, we’ll use the `gen4_image` model to generate an image of a bunny facing the camera. We provide a reference image of a rabbit that we use at-mention syntax to reference in the `promptText`. We also provide an untagged reference image that the model will use to style the output image with.
* Node
```ts
import fs from 'node:fs';
import path from 'node:path';
import RunwayML, { TaskFailedError } from '@runwayml/sdk';
// Use the `mime-types` package to get the content type of the image file
// Install with `npm install mime-types --save`
import * as mime from 'mime-types';
const client = new RunwayML();
function getImageAsDataUri(imagePath: string) {
// Read the image file
const imageBuffer = fs.readFileSync(imagePath);
// Convert to base64
const base64String = imageBuffer.toString('base64');
// Get the MIME type of the image file
const contentType = mime.lookup(imagePath);
return `data:${contentType};base64,${base64String}`;
}
// Create a new text-to-image task using the "gen4_image" model
try {
const textToImage = await client.textToImage
.create({
model: 'gen4_image',
promptText: '@bunny facing the camera',
ratio: '1920:1080',
referenceImages: [
{
uri: getImageAsDataUri('rabbit.png'),
tag: 'bunny',
},
{
uri: getImageAsDataUri('style.png'),
},
],
})
.waitForTaskOutput();
console.log('Task complete:', task);
} catch (error) {
if (error instanceof TaskFailedError) {
console.error('The image failed to generate.');
console.error(error.taskDetails);
} else {
console.error(error);
}
}
```
* Python
```python
import base64
import mimetypes
from runwayml import RunwayML, TaskFailedError
client = RunwayML()
def get_image_as_data_uri(image_path: str) -> str:
with open(image_path, "rb") as f:
base64_image = base64.b64encode(f.read()).decode("utf-8")
content_type = mimetypes.guess_file_type(image_path)[0]
return f"data:{content_type};base64,{base64_image}"
# Create a new text-to-image task using the "gen4_image" model
try:
task = client.text_to_image.create(
model='gen4_image',
ratio='1920:1080',
prompt_text='@bunny facing the camera',
reference_images=[
{
'uri': get_image_as_data_uri('rabbit.png'),
'tag': 'bunny',
},
{
'uri': get_image_as_data_uri('style.png'),
},
],
).wait_for_task_output()
print('Task complete:', task)
except TaskFailedError as e:
print('The image failed to generate.')
print(e.task_details)
```
### Additional Resources
* **[Runway Skills Repository](https://github.com/runwayml/skills)** - tools, code examples, and agent skills for Runway Dev
---
# Available AI Models
> Explore available AI models in Runway Dev. Learn about Gen-4, image generation and other models for video and image creation in your applications.
The API exposes the following models. See [pricing](/guides/pricing) for per-model costs. [Create an account](https://dev.runway.com/) to start building on Runway Dev.
Prefer not to have to decide the right model yourself? Use a [Model Router](/model-routers) to automatically route each request to the best available model based on your cost, latency, or quality preferences. No additional cost.
## Generate Video
| Model Name | Input | Output | Learn More |
| ------------------- | --------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `wan3` | Text or Image | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `seedance2_5` | Text, Image, or Video | Video | [Guide](https://help.runwayml.com/hc/en-us/articles/50488490233363-Creating-with-Seedance-2-0) [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `grok_imagine_1_5` | Text or Image | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `seedance2` | Text, Image, or Video | Video | [Guide](https://help.runwayml.com/hc/en-us/articles/50488490233363-Creating-with-Seedance-2-0) [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `seedance2_fast` | Text, Image, or Video | Video | [Guide](https://help.runwayml.com/hc/en-us/articles/50488490233363-Creating-with-Seedance-2-0) [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `seedance2_mini` | Text, Image, or Video | Video | [Guide](https://help.runwayml.com/hc/en-us/articles/50488490233363-Creating-with-Seedance-2-0) [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `h3_max` | Text or Image | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `hailuo3` | Text, Image, or Video | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `aleph2` | Video + Text/Image | Video | [Guide](https://help.runwayml.com/hc/en-us/articles/51683104370451-Creating-with-Edit-Studio) [Reference](/api#tag/Start-generating/paths/~1v1~1video_to_video/post) |
| `gen4.5` | Text or Image | Video | [Guide](https://runwayml.com/research/introducing-runway-gen-4.5) [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `gen4_turbo` | Image | Video | [Guide](https://help.runwayml.com/hc/en-us/articles/37327109429011-Creating-with-Gen-4) [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `act_two` | Image or Video | Video | [Reference](/api/#tag/Start-generating/paths/~1v1~1character_performance/post) |
| `veo3.1` | Text or Image | Video | [Reference](/api/#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `veo3.1_fast` | Text or Image | Video | [Reference](/api/#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `happyhorse_1_0` | Text or Image | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) |
| `gemini_omni_flash` | Text, Image, or Video | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_video/post) |
### Professional and HDR output formats
Runway’s flagship models — Gen-4.5 and Aleph 2.0 — can deliver video in professional formats beyond standard H.264 `.mp4`: ProRes and PNG image sequences for editorial workflows, 10-bit SDR masters for grading, and true HDR on Gen-4.5. Set `outputFormat` on the request to choose a delivery. These formats carry a per-second surcharge — see [pricing](/guides/pricing#professional-and-hdr-output-formats).
#### Editorial containers
Available on Gen-4.5 and Aleph 2.0:
| `outputFormat` | Delivery |
| --------------- | ----------------------------------------------------------------------- |
| `mp4` (default) | H.264 `.mp4` |
| `prores` | ProRes `.mov` |
| `png_sequence` | `.zip` of PNG frames (plus a separate `.wav` when the output has audio) |
For `prores`, optionally set `proresProfile` (`422 Proxy`, `422 LT`, `422`, `422 HQ`, `4444`, or `4444 XQ`; default `4444`).
#### 10-bit SDR
| `outputFormat` | Delivery | Models |
| ------------------ | ---------------------------- | ------------------ |
| `sdr_rec709_10bit` | HEVC Main 10, Rec.709 `.mp4` | Gen-4.5, Aleph 2.0 |
#### HDR and high bit-depth (Gen-4.5 only)
Gen-4.5 HDR outputs are true HDR renders — graded into BT.2020 with measured HDR10 metadata. Aleph 2.0 does not deliver native HDR. For HDR content with Aleph 2.0 you can chain an edit through [SDR to HDR](#sdr-to-hdr).
| `outputFormat` | Delivery |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `hdr10` | HEVC Main 10, BT.2020 + PQ `.mp4` |
| `hlg` | HEVC Main 10, BT.2020 + HLG `.mp4` |
| `hdr_pq_12bit_master` | 12-bit 4:4:4 BT.2020 + PQ `.mov` (lossless) |
| `hdr_prores` | BT.2020 + PQ ProRes `.mov` |
| `hdr_png_sequence` | `.zip` of 16-bit PNG frames + colorimetry sidecar (plus a separate `.wav` when the output has audio) |
| `hdr_exr_sequence` | `.zip` of half-float OpenEXR frames as linear BT.2020 light (1.0 = 100 nits) + colorimetry sidecar (plus a separate `.wav` when the output has audio) |
| `hdr_exr_acescg_sequence_1_3` | The EXR delivery as scene-referred ACEScg for ACES 1.3 pipelines — reads with the stock `ACES - ACEScg` input transform |
| `hdr_exr_acescg_sequence_2_0` | The same scene-referred ACEScg delivery for ACES 2.0 pipelines (inverted through the ACES 2.0 Output Transform) |
For `hdr_prores`, `proresProfile` accepts `422`, `422 HQ`, or `4444` (default `422 HQ`). On `/v1/video_to_hdr`, sources with an alpha channel are delivered as `4444` regardless of `proresProfile`.
The ACEScg EXRs are scene-referred: the delivered picture is inverted through the ACES 1.3 Output Transform (Rec.2100 PQ, 1000-nit), so reading the frames with the stock `ACES - ACEScg` input transform and viewing through your ACES pipeline reproduces the delivered picture — no Read-node changes needed. The `colorimetry.json` sidecar names the ACES version and the inverted transform.
## Real-time
| Model Name | Input | Output | Learn More |
| -------------- | ------------------- | ------------- | ----------------------------------------------------- |
| `gwm1_avatars` | Text (conversation) | Video + Audio | [Guide](/characters) [Reference](/api#tag/Characters) |
## Generate Images
| Model Name | Input | Output | Learn More |
| ------------------------ | ----------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gpt_image_2_5_flare` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `gpt_image_2_5_sunburst` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `muse_image` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `grok_imagine_image_2` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `seedream5_pro` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `seedream5_lite` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `gen4_image` | Text/Image (References) | Image | [Guide](https://help.runwayml.com/hc/en-us/articles/40042718905875-Gen-4-Image-References-Guide) [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `gen4_image_turbo` | Text+Image (References) | Image | [Guide](https://help.runwayml.com/hc/en-us/articles/40042718905875-Gen-4-Image-References-Guide) [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `gemini_image3_pro` | Text/Image (References) | Image | [Guide](https://help.runwayml.com/hc/en-us/articles/50317213804435-Creating-images-with-Nano-Banana) [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `gemini_image3.1_flash` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `gpt_image_2` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
| `gemini_2.5_flash` | Text/Image (References) | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) |
## Upscale Image
| Model Name | Input | Output | Learn More |
| -------------------------------- | ----- | ------ | --------------------------------------------------------------------- |
| `magnific_precision_upscaler_v2` | Image | Image | [Reference](/api#tag/Start-generating/paths/~1v1~1image_upscale/post) |
## Upscale Video
Set `model` to `magnific_video_upscaler_creative` on `POST /v1/video_upscale` to upscale a video. Input videos can be at most 30 seconds. The same endpoint also hosts [Enhance Frame Rate](#enhance-frame-rate).
| Model Name | Input | Output | Learn More |
| ---------------------------------- | ----- | ------ | --------------------------------------------------------------------- |
| `magnific_video_upscaler_creative` | Video | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1video_upscale/post) |
## Enhance frame rate
Set `model` to `enhance_frame_rate` on `POST /v1/video_upscale`. Converts a video to a target frame rate. Required `targetFramerate` is one of `24`, `25`, `30`, `48`, `50`, `60`, `120`, `23_98` (23.98 fps), `29_97` (29.97 fps), or `59_94` (59.94 fps). Inputs can be at most 300 seconds. See [pricing](/guides/pricing#enhance-frame-rate-pricing) for the 1 credit per 2 seconds rate.
| Model Name | Input | Output | Learn More |
| -------------------- | ----- | ------ | --------------------------------------------------------------------- |
| `enhance_frame_rate` | Video | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1video_upscale/post) |
## SDR to HDR
Always set `model` to `ruby` on `POST /v1/video_to_hdr`. Converts SDR video into true HDR, keeping the source pixels and audio. Delivers 10-bit HEVC in HDR10 (`outputFormat: "hdr10"`, the default) or HLG (`"hlg"`), a BT.2020 + PQ ProRes `.mov` editorial mezzanine (`"hdr_prores"`, with `proresProfile` of `422`, `422 HQ`, or `4444`; default `422 HQ`), or a `.zip` of half-float OpenEXR frames for compositing, as linear BT.2020 light (`"hdr_exr_sequence"`) or as scene-referred ACEScg for ACES pipelines (`"hdr_exr_acescg_sequence_1_3"`; reads with the stock `ACES - ACEScg` input transform; both zips include colorimetry and provenance sidecars, plus `audio.wav` when the source has audio). Ruby’s ACEScg sequences are referenced to the source: the frames are the source plate brought into ACES through the inverse ACES SDR (Rec.709) Output Transform, with the highlight detail Ruby recovers added on top. The ACES SDR view reproduces the source, and the ACES HDR views render the same scene with the recovered highlights. This is a scene, not the `hdr10` display grade, so an ACES HDR view is not expected to match `hdr10`. Sources with an alpha channel (ProRes 4444, WebM with alpha, RGBA codecs) keep it: the EXR deliveries write it as the `A` channel, and `hdr_prores` is delivered as `4444` regardless of `proresProfile`. The alpha is passed through unchanged and is not premultiplied. `hdr10` and `hlg` cannot carry alpha. Inputs must be SDR, at most 30 seconds, and under 4096 pixels per side; output dimensions may be cropped to a multiple of 16. See [pricing](/guides/pricing#sdr-to-hdr-pricing) for the 20 / 40 credit per-second rates by source resolution.
| Model Name | Input | Output | Learn More |
| ---------- | ----- | ------ | -------------------------------------------------------------------- |
| `ruby` | Video | Video | [Reference](/api#tag/Start-generating/paths/~1v1~1video_to_hdr/post) |
## Generate Audio
| Model Name | Input | Output | Learn More |
| ---------------------------- | ------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `seed_audio` | Text or Audio | Audio | [Text to Speech](/api#tag/Start-generating/paths/~1v1~1text_to_speech/post) [Sound Effect](/api#tag/Start-generating/paths/~1v1~1sound_effect/post) |
| `eleven_v3` | Text | Audio | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_speech/post) |
| `eleven_multilingual_v2` | Text | Audio | [Reference](/api#tag/Start-generating/paths/~1v1~1text_to_speech/post) |
| `eleven_text_to_sound_v2` | Text | Audio | [Reference](/api#tag/Start-generating/paths/~1v1~1sound_effect/post) |
| `eleven_voice_isolation` | Audio | Audio | [Reference](/api#tag/Start-generating/paths/~1v1~1voice_isolation/post) |
| `eleven_voice_dubbing` | Audio | Audio | [Reference](/api#tag/Start-generating/paths/~1v1~1voice_dubbing/post) |
| `eleven_multilingual_sts_v2` | Audio | Audio | [Reference](/api#tag/Start-generating/paths/~1v1~1speech_to_speech/post) |
---
# API Pricing & Costs
> Understand Runway Dev pricing and costs. View rates for Gen-4, image generation and other models to budget for your AI video integration project.
Each generation you run on Runway Dev costs credits. Credits can be purchased for $0.01 per credit in the developer portal for a project. Sales tax may apply depending on your location. [Create an account](https://dev.runway.com/) to start building on Runway Dev.
Generations routed through a [Model Router](/model-routers) are billed at the standard rate of whichever model the router selects. The response metadata reports the model used and the realized cost in credits.
## Video Generation Pricing
| Model | Pricing |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `wan3` (480p) | 5 credits per second |
| `wan3` (720p) | 10 credits per second |
| `wan3` (1080p) | 20 credits per second |
| `seedance2_5` (480p) | 20 credits per second of output, plus 10 credits per second of input and reference video (combined video capped at 30 seconds); reference images and audio are free (80 credit minimum per generation) |
| `seedance2_5` (720p) | 30 credits per second of output, plus 15 credits per second of input and reference video (combined video capped at 30 seconds); reference images and audio are free (80 credit minimum per generation) |
| `seedance2_5` (1080p) | 68 credits per second of output, plus 34 credits per second of input and reference video (combined video capped at 30 seconds); reference images and audio are free (80 credit minimum per generation) |
| `grok_imagine_1_5` (480p) | 10 credits per second, plus 1 credit per image or audio reference (including an image-to-video start frame) |
| `grok_imagine_1_5` (720p) | 16 credits per second, plus 1 credit per image or audio reference (including an image-to-video start frame) |
| `grok_imagine_1_5` (1080p) | 29 credits per second, plus 1 credit per image or audio reference (including an image-to-video start frame) |
| `seedance2` (480p/720p) | 36 credits per second |
| `seedance2` (1080p) | 40 credits per second |
| `seedance2` (4K) | 150 credits per second |
| `seedance2_fast` (480p/720p) | 29 credits per second |
| `seedance2_mini` (480p/720p) | 16 credits per second (64 credit minimum per generation) |
| `h3_max` (480p) | 5 credits per second |
| `h3_max` (768p) | 8 credits per second |
| `hailuo3` (768P) | 10 credits per second, plus 2 credits per reference image; reference video billed at the same per-second rate as output (capped at 15 seconds) |
| `hailuo3` (2K) | 15 credits per second, plus 2 credits per reference image; reference video billed at the same per-second rate as output (capped at 15 seconds) |
| `aleph2` | 28 credits per second (56 credit minimum per generation) |
| `gen4.5` | 12 credits per second |
| `gen4_turbo` | 5 credits per second |
| `act_two` | 5 credits per second |
| `veo3.1 (audio)` | 40 credits per second |
| `veo3.1 (no audio)` | 20 credits per second |
| `veo3.1_fast (audio)` | 15 credits per second |
| `veo3.1_fast (no audio)` | 10 credits per second |
| `happyhorse_1_0` (720p) | 15 credits per second |
| `happyhorse_1_0` (1080p) | 30 credits per second |
| `gemini_omni_flash` (text to video) | 10 credits per second |
| `gemini_omni_flash` (image to video) | 10 credits per second, plus 1 credit for the first-frame image |
| `gemini_omni_flash` (video to video) | 11 credits per second of input video (capped at 10 seconds), plus 1 credit per reference image |
### Professional and HDR output formats
These formats add a per-second surcharge on top of the model’s rate. Available on Gen-4.5 and Aleph 2.0 — see [models](/guides/models#professional-and-hdr-output-formats) for which `outputFormat` values each model supports.
| Formats | Surcharge |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `prores`, `png_sequence` | 5 credits per second |
| 10-bit and HDR profiles (`hdr10`, `hlg`, `sdr_rec709_10bit`, `hdr_pq_12bit_master`, `hdr_prores`, `hdr_png_sequence`, `hdr_exr_sequence`, `hdr_exr_acescg_sequence_1_3`, `hdr_exr_acescg_sequence_2_0`) | 20 credits per second; 40 credits per second when the output is larger than 4 megapixels (roughly 4K) |
## Image Generation Pricing
| Model | Pricing |
| ------------------------ | ------------------------------------------------------------------------------------------------ |
| `gen4_image` | 5 credits per 720p image, or 8 credits per 1080p image |
| `gen4_image_turbo` | 2 credits per image, any resolution |
| `muse_image` | 1 credit per image, any resolution |
| `grok_imagine_image_2` | 4–8 credits per image, by quality and resolution (see below) |
| `seedream5_pro` | 5 credits per 1K image, 9 credits per 2K image |
| `seedream5_lite` | 4 credits per image, any resolution |
| `gemini_image3_pro` | 20 credits per 1K or 2K image, 40 credits per 4K image |
| `gpt_image_2` | 1–41 credits per image, by quality and resolution (see below) |
| `gpt_image_2_5_flare` | 1–76 credits per image, by quality and resolution, plus 1 credit per reference image (see below) |
| `gpt_image_2_5_sunburst` | 1–76 credits per image, by quality and resolution, plus 1 credit per reference image (see below) |
| `gemini_2.5_flash` | 5 credits per image, any resolution |
`grok_imagine_image_2` is billed as `outputCount × perImage + referenceCount × 1`. Reference images cost 1 credit each and are charged once per request, not per output image — for example, four 1K `medium` images with two references is `4 × 6 + 2` = 26 credits. Default quality is `medium`; anything other than `low` (including an omitted `quality`) bills as `medium`. `auto_1k` and `auto_2k` bill at the 1K and 2K tiers. A plain 1K generation is 6 credits (the minimum charge). With `outputCount` capped at 4 and references at 3, the maximum for a single request is 35 credits.
| Quality | 1K (incl. `auto_1k`) | 2K (incl. `auto_2k`) |
| -------- | -------------------- | -------------------- |
| `low` | 4 | 6 |
| `medium` | 6 | 8 |
`gpt_image_2` is billed as credits per image × `outputCount`. The `auto` resolution is billed at the 4K tier. Default quality is `high`.
| Quality | 1K / 2K | 4K (incl. `auto`) |
| -------- | ------- | ----------------- |
| `low` | 1 | 2 |
| `medium` | 5 | 11 |
| `high` | 20 | 41 |
| `auto` | 20 | 41 |
`gpt_image_2_5_flare` and `gpt_image_2_5_sunburst` are billed on the same table, as (credits per image + 1 credit per reference image) × `outputCount` — reference images are charged once per generated image, not once per request. The `auto` resolution is billed at the 4K tier. Default quality is `high`.
| Quality | 1K / 2K | 4K (incl. `auto`) |
| -------- | ------- | ----------------- |
| `low` | 1 | 2 |
| `medium` | 5 | 11 |
| `high` | 16 | 19 |
| `xhigh` | 28 | 34 |
| `max` | 63 | 76 |
## Image Upscale Pricing
| Model | Pricing |
| -------------------------------- | --------------------------------------------------------------- |
| `magnific_precision_upscaler_v2` | 25 credits per image, or 150 credits when output exceeds 4096px |
## Video Upscale Pricing
`magnific_video_upscaler_creative` is billed per output frame, not per second of video. Credits = `ceil(USD / 0.01)`, where `USD = rate × fps × duration_seconds`. Minimum 1 credit per generation. When `fpsBoost` is enabled, output frame count may differ from input and affect cost. Frame-rate conversion on the same endpoint is billed separately — see [Enhance Frame Rate pricing](#enhance-frame-rate-pricing).
| Resolution | USD per frame | Example (10s @ 30fps) |
| ------------ | ------------- | --------------------- |
| `720p`, `1k` | $0.007 | 210 credits |
| `2k` | $0.009 | 270 credits |
| `4k` | $0.012 | 360 credits |
## Enhance Frame Rate Pricing
Enhance Frame Rate (`enhance_frame_rate`) converts a video to a target frame rate on `POST /v1/video_upscale`. Billed per second of input.
| Model | Pricing |
| -------------------- | ---------------------- |
| `enhance_frame_rate` | 1 credit per 2 seconds |
## SDR to HDR Pricing
Ruby (`ruby`) converts SDR video to true HDR on `POST /v1/video_to_hdr`. Billed per second of output at the source’s own resolution.
| Model | Pricing |
| ------ | ----------------------------------------------------------------------------------------------------- |
| `ruby` | 20 credits per second; 40 credits per second when the source is larger than 4 megapixels (roughly 4K) |
## Audio Generation Pricing
| Model | Pricing |
| --------------------------------------------- | --------------------------------------------------------- |
| `seed_audio` | 0.25 credits per second (5 credit minimum per generation) |
| `eleven_v3` | 1 credit per 50 characters (minimum 1 credit) |
| `eleven_multilingual_v2` | 1 credit per 50 characters |
| `eleven_text_to_sound_v2 (provided duration)` | 1 credit per second of audio |
| `eleven_text_to_sound_v2 (no duration)` | 2 credits |
| `eleven_voice_isolation` | 1 credit per 6s of audio |
| `eleven_voice_dubbing` | 1 credit per 2s of audio |
| `eleven_multilingual_sts_v2` | 1 credit per 3s of audio |
## Real-time Pricing
| Model | Pricing |
| -------------- | ----------------------------------------------- |
| `gwm1_avatars` | 2 credits upfront, then 2 credits per 6 seconds |
## Recipe Pricing
| Recipe | Pricing |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `product_ad` | 720p: 200 credits for a 4 second video, plus 36 credits per additional second. 1080p: 216 credits for a 4 second video, plus 40 credits per additional second. (4 second minimum, 15 second maximum per generation) |
| `product_swap` | 720p: 212 credits for a 4 second video, plus 36 credits per additional second. 1080p: 228 credits for a 4 second video, plus 40 credits per additional second. (4 second minimum, 15 second maximum per generation) |
| `product_ugc` | 720p: 192 credits for a 4 second video, plus 36 credits per additional second. 1080p: 208 credits for a 4 second video, plus 40 credits per additional second. (4 second minimum, 15 second maximum per generation) |
| `multi_shot_video` | 720p: 13 credits per second of video. 1080p: 17 credits per second of video. (5 second minimum, 15 second maximum per generation) |
| `ad_localization` | 21 credits per localized image |
| `marketing_stock_image` | 8 credits per call for prompt processing, plus 1–20 credits per generated image by `quality` (same 1K/2K tiers as [Image Generation Pricing](#image-generation-pricing)) × `outputCount`. Default (`outputCount: 4`, `quality: high`): **88 credits** total. |
| `product_campaign_image` | 36 credits per 1080p image (4 images generated per call) |
## Cost calculator
You can calculate the cost of your intended usage:
Images: 1 x 720p *(5 credits)* + 1 x 1080p *(8 credits)* = $0.13
Videos: WAN 3.0 (480p) (wan3\_480p) 1 video x Duration: 1 =$0.25
---
# Content Moderation System
> Learn about Runway's content moderation for API usage. Understand safety guidelines, moderation policies and best practices for responsible AI use.
Runway takes the safety of its platform seriously. This means we will moderate certain API requests.
If your account makes too many requests that get moderated, we will suspend your account. If needed, you should add moderation before calling the API, to avoid suspension.
## Approach to Trust & Safety
Refer to our [help center approach to trust & safety](https://help.runwayml.com/hc/en-us/articles/17944787368595-Runway-s-approach-to-trust-safety).
### Moderated content categories
Refer to our [help center FAQ guide on content moderation](https://help.runwayml.com/hc/en-us/articles/21745792516371-Why-is-my-input-getting-content-moderated-and-what-types-of-content-are-blocked).
### Moderated content types
Runway moderation will evaluate all elements of your request. This means your requests may be moderated for either an image or text prompt violation.
## Moderation implications
### Recommended moderation approach
We recommend reviewing [the categories we block](https://help.runwayml.com/hc/en-us/articles/21745792516371-Why-is-my-input-getting-content-moderated-and-what-types-of-content-are-blocked) to determine what type of, if any, moderation you need in place.
Each call to the API defaults to `auto` moderation levels. If you wish to be less strict about preventing generations that include recognizable public figures, add the `contentModeration` object to your image or video generation API requests. See the [API reference](/api/#tag/Start-generating/paths/~1v1~1image_to_video/post) for details.
### Cost of moderated generations
Moderated generations have the same credit cost as successful generations.
### Account suspension
If your account makes too many moderated requests we will suspend it. You can [appeal an account suspension here](https://help.runwayml.com/hc/en-us/articles/21667383978003-How-can-I-appeal-my-account-s-suspension). Be sure to email from an email account associated with your developer portal login.
## Moderation API responses
If a request was moderated, the task status response will return with `"status":"FAILED"`.
Additional details describing the moderation appear in the `"failure"` and `"failureCode"` fields.
---
# Software Development Kits
> Download Runway Dev SDKs for Python, Node.js and more. Use official libraries to integrate AI video generation into your development workflow.
## Available SDKs
We provide SDKs as convenient helpers for interacting with our API. These SDKs use best practices and offer type safety, which helps to avoid errors and make it easier to write code.
### Node.js
The Node.js SDK includes TypeScript bindings. It is compatible with Node 18 and up, and can be installed with `npm`, `yarn`, or `pnpm`.
### Python
The Python SDK includes type annotations compatible with MyPy. It is compatible with Python 3.8 and up.
## Generating content
You can create content using our API using the methods documented in the [API reference](/api). For instance, `POST /v1/text_to_image` accepts input and produces an image as output.
Each API endpoint for starting a generation is available as a member on the SDKs. Here is a subset of the API endpoints mapped to the SDK methods:
* Node
| Operation | API endpoint | Node.js SDK method |
| --------------------- | -------------------------------- | ------------------------------------ |
| Generate an image | `POST /v1/text_to_image` | `client.textToImage.create` |
| Generate a video | `POST /v1/image_to_video` | `client.imageToVideo.create` |
| Character performance | `POST /v1/character_performance` | `client.characterPerformance.create` |
* Python
| Operation | API endpoint | Python SDK method |
| --------------------- | -------------------------------- | ------------------------------------- |
| Generate an image | `POST /v1/text_to_image` | `client.text_to_image.create` |
| Generate a video | `POST /v1/image_to_video` | `client.image_to_video.create` |
| Character performance | `POST /v1/character_performance` | `client.character_performance.create` |
Calling these methods will create a task. A task is a record of the generation operation. The response from the method will look like this:
```plaintext
{
"id": "17f20503-6c24-4c16-946b-35dbbce2af2f"
}
```
The `id` field is the unique identifier for the task. You can use this ID to retrieve the task status and output from the [`GET /v1/tasks/{id}` endpoint](/api#tag/Task-management/paths/~1v1~1tasks~1%7Bid%7D/get), which is available as the `tasks.retrieve` method on the SDKs.
* Node
```ts
import RunwayML from '@runwayml/sdk';
const client = new RunwayML();
const task = await client.tasks.retrieve('17f20503-6c24-4c16-946b-35dbbce2af2f');
console.log(task);
```
* Python
```python
from runwayml import RunwayML
client = RunwayML()
task = client.tasks.retrieve('17f20503-6c24-4c16-946b-35dbbce2af2f')
print(task)
```
The response from the method will look like this:
```plaintext
{
"id": "17f20503-6c24-4c16-946b-35dbbce2af2f",
"status": "PENDING",
"createdAt": "2024-06-27T19:49:32.334Z"
}
```
The [API reference](/api#tag/Task-management/paths/~1v1~1tasks~1%7Bid%7D/get) documents the statuses that a task can be in, along with the fields that are available for each status.
Tasks are processed asychronously. The `tasks.retrieve` method returns the current status of the task, which you can poll until the task has completed. The task will eventually transition to a `SUCCEEDED`, `CANCELED`, or `FAILED` status.
When polling, we recommend using an interval of 5 seconds or more. You should also add jitter, and handle non-200 responses with exponential backoff. Avoid using fixed interval polling (such as with JavaScript’s `setInterval`), since latency from the API can cause the polling to be too frequent.
### Built-in task polling
As a convenience, all SDK methods that return a task include a helper method that polls for the task output. This reduces the amount of code you need to write to wait for a task to complete.
* Node
The `waitForTaskOutput` method is present on the unawaited response from the `create` methods on `textToImage`, `imageToVideo`, and other endpoints to start generations.
```ts
// ✅ Call `waitForTaskOutput` on the unawaited response from `create`
const imageTask = await client.textToImage
.create({
model: 'gen4_image',
promptText: 'A beautiful sunset over a calm ocean',
ratio: '1360:768',
})
.waitForTaskOutput();
console.log(imageTask.output[0]); // Print the URL of the generated image
```
```ts
// ✅ Getting the task ID for bookkeeping purposes
// Notice: no `await` here.
const imageTask = client.textToImage.create({
model: 'gen4_image',
promptText: 'A beautiful sunset over a calm ocean',
ratio: '1360:768',
});
// Await the output of `create` to get the task ID
const taskId = (await imageTask).id;
console.log(taskId); // The task ID can be stored in your database, for instance.
// Wait for the task to complete. It is safe to await `waitForTaskOutput`
// after the output of `create` was awaited above.
const completedTask = await imageTask.waitForTaskOutput();
console.log(completedTask.output[0]); // Print the URL of the generated image
```
```diff
// ❌ If you await the response from `create`, the result not have access to
// `waitForTaskOutput`.
const awaitedImageTask = await client.textToImage.create({
model: 'gen4_image',
promptText: 'A beautiful sunset over a calm ocean',
ratio: '1360:768',
});
-const taskOutput = await awaitedImageTask.waitForTaskOutput();
```
If the task fails (that is, its status becomes `FAILED`), a `TaskFailedError` will be thrown. You should handle this error appropriately.
```ts
import { TaskFailedError } from '@runwayml/sdk';
try {
const imageTask = await client.textToImage
.create({
model: 'gen4_image',
promptText: 'A beautiful sunset over a calm ocean',
ratio: '1360:768',
})
.waitForTaskOutput();
} catch (error) {
if (error instanceof TaskFailedError) {
// `taskDetails` contains the output of the tasks.retrieve call.
console.error('Task failed:', error.taskDetails);
} else {
throw error;
}
}
```
The `waitForTaskOutput` method accepts an optional `options` parameter. This parameter can be used to specify a timeout and an `AbortSignal`.
```ts
const imageTask = await client.textToImage
.create({
model: 'gen4_image',
promptText: 'A beautiful sunset over a calm ocean',
ratio: '1360:768',
})
.waitForTaskOutput({
// Wait up to 5 minutes for the task to complete
timeout: 5 * 60 * 1000,
// Abort the task if the request is cancelled
abortSignal: myAbortSignal,
});
```
By default, `waitForTaskOutput` will wait for ten minutes before timing out. Upon timeout, a `TaskTimedOutError` will be thrown. Pass `null` to `timeout` to wait indefinitely. Disabling the timeout is not recommended as it may cause your server to experience issues if your project reaches its concurrency limit or if Runway Dev experiences an outage.
It is recommended to use an `AbortSignal` to cancel polling if you are using `waitForTaskOutput` in the handler for an incoming request, such as on a web server. Here is an example of how to correctly integrate this into your application:
* Express.js
```ts
const runway = new RunwayML();
app.post('/generate-image', (req, res) => {
// Create an AbortController that triggers when the request is closed
// unexpectedly.
const abortController = new AbortController();
req.on('close', () => {
abortController.abort();
});
// 🚨 When performing a generation, be sure to add appropriate rate limiting
// and other safeguards to prevent abuse.
try {
const imageTask = await runway.textToImage
.create({
model: 'gen4_image',
promptText: req.body.prompt,
ratio: '1360:768',
})
.waitForTaskOutput({ abortSignal: abortController.signal });
res.send(imageTask.output[0]);
} catch (error) {
if (error instanceof TaskFailedError) {
res.status(500).send('Task failed');
} else {
throw error;
}
}
});
```
* Koa
```ts
const runway = new RunwayML();
app.post('/generate-image', async (ctx) => {
// Create an AbortController that triggers when the request is closed
// unexpectedly.
const abortController = new AbortController();
ctx.req.on('close', () => {
abortController.abort();
});
// 🚨 When performing a generation, be sure to add appropriate rate limiting
// and other safeguards to prevent abuse.
try {
const imageTask = await runway.textToImage
.create({
model: 'gen4_image',
promptText: ctx.request.body.prompt,
ratio: '1360:768',
})
.waitForTaskOutput({ abortSignal: abortController.signal });
ctx.body = imageTask.output[0];
} catch (error) {
if (error instanceof TaskFailedError) {
ctx.status = 500;
ctx.body = 'Task failed';
} else {
throw error;
}
}
});
```
* Socket.io
```ts
const runway = new RunwayML();
io.on('connection', (socket) => {
// Create an AbortController that triggers when the socket is closed
// unexpectedly.
const abortController = new AbortController();
socket.on('close', () => {
abortController.abort();
});
// 🚨 When performing a generation, be sure to add appropriate rate limiting
// and other safeguards to prevent abuse.
socket.on('generate-image', async (prompt) => {
try {
const imageTask = await runway.textToImage
.create({
model: 'gen4_image',
promptText: prompt,
ratio: '1360:768',
})
.waitForTaskOutput({ abortSignal: abortController.signal });
socket.emit('image', imageTask.output[0]);
} catch (error) {
if (error instanceof TaskFailedError) {
socket.emit('error', 'Task failed');
} else {
throw error;
}
}
});
});
```
Danger
Triggering the `abortSignal` passed to `waitForTaskOutput` or hitting the passed `timeout` will not cancel the task. Cancelling the task must be done by invoking the [cancellation endpoint](/api#tag/Task-management/paths/~1v1~1tasks~1%7Bid%7D/delete).
In addition to the methods that create new tasks, the `tasks.retrieve` method also returns a promise with a `waitForTaskOutput` method. This method is equivalent to the `waitForTaskOutput` method on the unawaited response from the `create` methods.
```ts
const task = await client.tasks
.retrieve('17f20503-6c24-4c16-946b-35dbbce2af2f')
.waitForTaskOutput();
console.log(task.output[0]);
```
This is useful if you’d like to create a task in one request and wait for its output in another request, or for handling the case where the client disconnected before the task completed.
Be aware that you must still add error handling for `TaskFailedError` and `TaskTimeoutError` when using this method.
* Python
```ts
const runway = new RunwayML();
app.post('/generate-image', (req, res) => {
// Create an AbortController that triggers when the request is closed
// unexpectedly.
const abortController = new AbortController();
req.on('close', () => {
abortController.abort();
});
// 🚨 When performing a generation, be sure to add appropriate rate limiting
// and other safeguards to prevent abuse.
try {
const imageTask = await runway.textToImage
.create({
model: 'gen4_image',
promptText: req.body.prompt,
ratio: '1360:768',
})
.waitForTaskOutput({ abortSignal: abortController.signal });
res.send(imageTask.output[0]);
} catch (error) {
if (error instanceof TaskFailedError) {
res.status(500).send('Task failed');
} else {
throw error;
}
}
});
```
* Express.js
```ts
const runway = new RunwayML();
app.post('/generate-image', async (ctx) => {
// Create an AbortController that triggers when the request is closed
// unexpectedly.
const abortController = new AbortController();
ctx.req.on('close', () => {
abortController.abort();
});
// 🚨 When performing a generation, be sure to add appropriate rate limiting
// and other safeguards to prevent abuse.
try {
const imageTask = await runway.textToImage
.create({
model: 'gen4_image',
promptText: ctx.request.body.prompt,
ratio: '1360:768',
})
.waitForTaskOutput({ abortSignal: abortController.signal });
ctx.body = imageTask.output[0];
} catch (error) {
if (error instanceof TaskFailedError) {
ctx.status = 500;
ctx.body = 'Task failed';
} else {
throw error;
}
}
});
```
* Koa
```ts
const runway = new RunwayML();
io.on('connection', (socket) => {
// Create an AbortController that triggers when the socket is closed
// unexpectedly.
const abortController = new AbortController();
socket.on('close', () => {
abortController.abort();
});
// 🚨 When performing a generation, be sure to add appropriate rate limiting
// and other safeguards to prevent abuse.
socket.on('generate-image', async (prompt) => {
try {
const imageTask = await runway.textToImage
.create({
model: 'gen4_image',
promptText: prompt,
ratio: '1360:768',
})
.waitForTaskOutput({ abortSignal: abortController.signal });
socket.emit('image', imageTask.output[0]);
} catch (error) {
if (error instanceof TaskFailedError) {
socket.emit('error', 'Task failed');
} else {
throw error;
}
}
});
});
```
* Socket.io
The `wait_for_task_output` method is present on the unawaited response from the `create` methods on `text_to_image`, `image_to_video`, and other methods to start generations.
```python
from runwayml import RunwayML
client = RunwayML()
image_task = client.text_to_image.create(
model='gen4_image',
prompt_text='A beautiful sunset over a calm ocean',
ratio='1360:768',
)
task_output = image_task.wait_for_task_output()
print(task_output.output[0])
```
If the task fails (that is, its status becomes `FAILED`), a `TaskFailedError` will be raised. You should handle this error appropriately.
```python
from runwayml import RunwayML, TaskFailedError
client = RunwayML()
# 🚨 When performing a generation, be sure to add appropriate rate limiting
# and other safeguards to prevent abuse.
try:
image_task = client.text_to_image.create(
model='gen4_image',
prompt_text='A beautiful sunset over a calm ocean',
ratio='1360:768',
)
task_output = image_task.wait_for_task_output()
except TaskFailedError as e:
print('Task failed:', e.task_details)
```
The `wait_for_task_output` method accepts an optional `timeout` parameter. This parameter specifies the maximum amount of time to wait for the task to complete in seconds. If not specified, the default timeout is ten minutes. Pass `None` to `timeout` to wait indefinitely. Disabling the timeout is not recommended as it may cause your server to experience issues if your project reaches its concurrency limit or if Runway Dev experiences an outage.
```python
from runwayml import RunwayML
client = RunwayML()
image_task = client.text_to_image.create(
model='gen4_image',
prompt_text='A beautiful sunset over a calm ocean',
ratio='1360:768',
).wait_for_task_output(
# Wait up to 5 minutes for the task to complete
timeout=5 * 60,
)
```
When the timeout is reached, a `TaskTimeoutError` will be raised.
Caution
If the timeout is reached, the task will not be cancelled. Cancelling the task must be done by invoking the [cancellation endpoint](/api#tag/Task-management/paths/~1v1~1tasks~1%7Bid%7D/delete).
In addition to the methods that create new tasks, the `tasks.retrieve` method also returns a promise with a `wait_for_task_output` method. This method is equivalent to the `wait_for_task_output` method on the unawaited response from the `create` methods.
```python
task_output = await client.tasks.retrieve(image_task.id).wait_for_task_output()
print(task_output.output[0])
```
This is useful if you’d like to create a task in one request and wait for its output in another request, or for handling the case where the client disconnected before the task completed.
Be aware that you must still add error handling for `TaskFailedError` and `TaskTimeoutError` when using this method.
## Code Skills & Agent Tool
The [Runway Skills repository](https://github.com/runwayml/skills) provides a collection of tools, examples, and agent skills for working with Runway Dev. This includes:
* **Claude Code Skills** - Pre-built skills for AI agents to interact with Runway Dev
* **Code and Prompt Examples** - Sample implementations and integration patterns
---
# API Versioning Policy
> Understand API versioning on Runway Dev. Learn about version compatibility, deprecation timelines and how to manage API updates in your apps.
The API uses an `X-Runway-Version` HTTP request header to specify which version of the API to use. This is in the form of a date, like `2024-11-06`. When you build an integration, setting a version header changes the default behavior of our API.
## When is a new version number created?
We’ll add new features and functionality to the latest existing API version so long as the functionality can be added in a backwards-compatible way. You’ll be able to enjoy these features automatically without having to make changes to your integration.
A new version will only be created when we make changes to the API that are not backwards-compatible. Here are a few examples of what might result in a new API version:
* **The type of an input parameter is changed.** For instance, if a parameter that was previously a string representing a URL becomes an object containing more information about the asset referenced by the URL.
* **The name of an input parameter is changed.** For example, we may restructure an API to better reflect new techniques or model constraints. An input that was previously a boolean to enable a feature may be changed to an object to allow extra configuration to be provided beyond.
* **Functionality is removed.** If we deprecate a feature, we’ll create a new API version that removes the functionality.
## Version support
We’ll offer support for old API versions for four months after a new version is created. After that date, API requests with an old API version may be rejected.
### Managing versions
We strongly suggest using one of the official [Runway Dev SDKs](/api-details/sdks). We’ll publish new major versions of each SDK when a new API version is released. Using [TypeScript](https://www.typescriptlang.org/) or a Python type checker like [MyPy](https://www.mypy-lang.org/), you’ll be able to easily identify any places where your integration needs to be updated.
## `/v1` URLs
While we include `/v1/` in our URLs, this is not used for versioning the API. We include this to reserve the ability to offer new functionality concurrently with our `/v1/` endpoints in the future.
---
# API Input Parameters
> Learn about input parameters for Runway Dev. Understand how to format images, videos, text prompts and other inputs for AI generation requests.
When starting tasks on Runway Dev, you’ll often need to provide assets like images. Some restrictions exist for what you can provide.
Assets can be provided via URLs or Data URIs.
## Size limits
The size limits of inputs differ based on whether they are provided as a URL or as a data URI in the JSON request body.
| Input type | URL size limit | Data URI size limit | Ephemeral uploads |
| ---------- | -------------- | ------------------- | ----------------- |
| Image | 16MB | 5MB | 200MB |
| Video | 32MB | 16MB | 200MB |
| Audio | 32MB | 16MB | 200MB |
## Inputs using URLs
In all cases, URLs must meet some basic minimum requirements:
1. All URLs must be HTTPS.
2. URLs must reference a domain name in the hostname position, not an IP address.
3. The server should respond with valid `Content-Type` and `Content-Length` headers.
4. Redirects are not followed. If the URL returns a 3XX response code, the request is considered failed.
5. The length of any single URL should not exceed `2048` characters.
Additionally, the server responding to the request must support HTTP `HEAD` requests.
### `Content-Type` values
When specifying a URL, the `Content-Type` response header must be returned, and it must match the media type of your asset. File extensions in URLs are not considered. The `Content-Type`s that are supported are [listed below](#type-specific-requirements) for the supported asset types.
Be aware that `application/octet-stream` and other generic values are explicitly not supported.
### User agent
Runway will use a `User-Agent` header that starts with `RunwayML API/` when making requests to your server. If you use a scraping-prevention tool or WAF, be sure to allowlist our user agent string prefix.
## Inputs using Data URIs (base64 encoded)
A [data URI](https://en.wikipedia.org/wiki/Data_URI_scheme) allows you to pass the base64 encoded assets as part of a request to our API, rather than passing a URL to the asset hosted on another server. This can reduce the complexity of your integration by eliminating an upload step, but it also has a lower limit on the size of the assets that can be provided.
Data URIs are accepted in any field where a URL is accepted unless otherwise specified.
* An appropriate [content type](https://en.wikipedia.org/wiki/Media_type) must be specified in the data URI. For instance, your data URI for a JPEG should start with something like `data:image/jpg;base64,`.
* Data URIs must use the base64 extension. The expected format is `data:content/type;base64,`.
* The size limit for your data URI (specified above) is the limit for the **encoded data URI**. Keep in mind that base64-encoding your asset increases its size by about 33%: to fit an image within the **5MB limit**, the binary file must be **3.3MB** or less.
Data URIs that do not follow these rules may be rejected with a 400 Bad Request error.
## Inputs using ephemeral uploads
See [our documentation on ephemeral uploads](/assets/uploads) for more.
## Considerations of URLs, data URIs, and ephemeral uploads
If you do not already have your asset stored in object storage, submitting your asset with a data URI can save you a step. However, the data URI size limit may be too small for some assets. If you cannot be sure that all assets are safely within the un-encoded size limit, you should upload assets to object storage instead.
Submitting a request with data URIs instead of URLs will change the performance characteristics of your integration. Data URIs are part of the request payload, and thus cause your HTTP requests to take longer to submit: all data must be sent serially to our servers. Because the request body JSON must be processed before the assets can be extracted from their data URIs, this may increase the latency of our server responses.
URLs, on the other hand, can be immediately processed in parallel. This means the time between submitting your HTTP request and the start of processing is likely much lower. However, latency between our servers and the server hosting your assets may increase the total request time. Using a CDN or object storage service will help to minimize this cost.
Runway [ephemeral uploads](/assets/uploads) offer the benefits of object storage (like URLs) without needing to set up your own infrastructure. Assets are uploaded from your server to Runway’s object storage, returning a `runway://` URI that can be used anywhere a HTTPS URL could be used. Importantly, these URIs can only be used for 24 hours after being created. It’s also important to note that ephemeral uploads are rate limited, and have a minimum file size of 512 bytes (0.5KB).
## Type-specific requirements
### Images
For fields that accept images, the asset must use one of the following encodings, along with the corresponding `Content-Type` header:
| Codec | `Content-Type` header |
| ----- | --------------------------- |
| JPEG | `image/jpg` or `image/jpeg` |
| PNG | `image/png` |
| WebP | `image/webp` |
GIF images are not supported.
### Videos
For fields that accept videos, the asset must use one of the following codecs, along with the corresponding `Content-Type` header:
| Container format | Usual file extension | Expected content type | Supported codecs |
| ---------------- | -------------------- | --------------------- | ------------------------------------------------------------------------------- |
| MP4 | `.mp4` | `video/mp4` | H.264, H.265/HEVC, AV1 |
| QuickTime | `.mov` | `video/quicktime` | H.264, H.265/HEVC, Apple ProRes (422 Proxy, 422 LT, 422, 422 HQ, 4444, 4444 XQ) |
| Matroska | `.mkv` | `video/x-matroska` | H.264, H.265/HEVC, VP8, VP9, AV1 |
| WebM | `.webm` | `video/webm` | VP8, VP9, AV1 |
| 3GPP | `.3gp` | `video/3gpp` | H.264 |
| Ogg | `.ogv` | `video/ogg` | Theora |
The following formats are supported but discouraged due to quality, performance, industry support, and file size:
| Container format | Usual file extension | Expected content type | Supported codecs |
| ---------------- | -------------------- | --------------------- | ----------------------- |
| QuickTime | `.mov` | `video/quicktime` | MJPEG |
| Matroska | `.mkv` | `video/x-matroska` | MPEG2 (H.262) |
| AVI | `.avi` | `video/x-msvideo` | H.264, MJPEG, MSMPEG4v3 |
| Flash Video | `.flv` | `video/x-flv` | FLV1, H.264 |
| MPEG | `.mpg`, `.mpeg` | `video/mpeg` | MPEG2 (H.262) |
Note that file extension is not considered by the API. Use this value for reference only.
* **H.264 / AVC** - Most widely supported modern codec
* **H.265 / HEVC** - High efficiency successor to H.264
* **AV1** - Royalty-free, modern codec
* **VP8 / VP9** - Google’s codecs, primarily for WebM
* **Apple ProRes** - Professional editing codec (422 Proxy, 422 LT, 422, 422 HQ, 4444, 4444 XQ)
* **MPEG2 (H.262)** - Legacy codec for DVDs and broadcasts (discouraged)
* **MJPEG** - Motion JPEG, frame-by-frame compression (discouraged)
* **Theora** - Open codec for Ogg containers
* **FLV1** - Legacy Flash Video codec (discouraged)
* **MSMPEG4v3** - Legacy Microsoft codec (discouraged)
Ruby
Ruby (`ruby`) on `POST /v1/video_to_hdr` accepts SDR sources only. Videos whose streams are tagged as HDR (a PQ or HLG transfer function, or BT.2020 primaries) are rejected. Sources with an alpha channel (ProRes 4444, WebM with alpha) keep it in the `hdr_prores` and EXR deliveries; `hdr10` and `hlg` cannot carry alpha. :::
### Audio
For fields that accept audio, the asset must use one of the following codecs, along with the corresponding `Content-Type` header:
| Container format | Usual file extension | Content type | Supported codecs |
| ---------------- | -------------------- | ---------------------------------------- | ---------------------- |
| MP3 | `.mp3` | `audio/mpeg`, `audio/mp3` | MP3 (MPEG-1/2 Layer 3) |
| WAV | `.wav` | `audio/wav`, `audio/wave`, `audio/x-wav` | PCM (uncompressed) |
| FLAC | `.flac` | `audio/flac`, `audio/x-flac` | FLAC (lossless) |
| M4A | `.m4a` | `audio/mp4`, `audio/x-m4a` | AAC, ALAC |
| AAC | `.aac` | `audio/aac`, `audio/x-aac` | AAC (raw) |
* **MP3 (MPEG-1/2 Layer 3)** - Universal compatibility, lossy compression
* **AAC (Advanced Audio Coding)** - Modern lossy codec, better quality than MP3 at same bitrate
* **FLAC (Free Lossless Audio Codec)** - Lossless compression, popular for archival
* **PCM (Pulse Code Modulation)** - Uncompressed audio, typically in WAV containers
* **ALAC (Apple Lossless Audio Codec)** - Apple’s lossless codec, typically in M4A containers
## Aspect ratios and auto-cropping of inputs
### Video inputs
When using video models, be aware of the supported `ratio` parameters, which configures the dimensions of the output files.
Examples:
* **Gen-4.5 Text-to-Video** supports Landscape `1280:720` and Portrait `720:1280` outputs only.
* **Gen-4.5 Image-to-Video** supports Landscape `1280:720` `1584:672` `1104:832`, Portrait `720:1280` `832:1104` `672:1584` and Square `960:960` outputs.
* **Gen-4 Turbo** and **Act-Two** support Landscape `1280:720` `1584:672` `1104:832`, Portrait `720:1280` `832:1104` and Square `960:960` outputs.
* **Aleph 2.0** preserves the input video’s resolution (up to 1080p). Input videos must be 2–30 seconds and 30 FPS or lower.
* **MiniMax H3 Max** supports `resolution` of `480p` or `768p`. Durations are 5–15 seconds. There is no `ratio` parameter. Image-to-video accepts a first frame or first and last keyframes (each at least 256 pixels on both sides); output aspect ratio follows the input image. Optional `promptExpansionMode` is `disabled`, `balanced` (the default), or `quality`.
* **WAN 3.0** supports 480p, 720p, and 1080p (default `auto_1080p`). Durations are 2–30 seconds. Up to 10 image references, 5 video references, and 5 audio references (combined video and audio duration each under 15 seconds). Image-to-video accepts a start frame or first/last keyframes; keyframes cannot be mixed with references.
* **Seedance 2.5** supports 18 `width:height` ratios across 480p, 720p, and 1080p (default `1280:720`). Durations are 4–30 seconds. 480p 16:9 / 9:16 use `854:480` / `480:854`. Input and reference videos must be at least 480p. Video-to-video supports `mode: "reference"` (default) or `mode: "extend"`.
* **Seedance 2.0** supports 24 `width:height` ratios across 480p, 720p, 1080p, and 4K.
* **Seedance 2.0 Fast** supports 12 `width:height` ratios across 480p and 720p only.
* **Seedance 2.0 Mini** supports 12 `width:height` ratios across 480p and 720p only.
* **MiniMax H3** supports `ratio` values `adaptive`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, and `9:16`, with `resolution` of `768P` or `2K` (default `2K`). Durations are 5–15 seconds. `adaptive` requires at least one reference image or video. Keyframe (`position: first`/`last`) and unpositioned reference-image modes cannot be mixed; reference audio is only valid with unpositioned reference images (not keyframes).
* **Grok Imagine Video 1.5 Text-to-Video** supports `ratio` values `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, and `2:3`, with `resolution` of `480p`, `720p`, or `1080p` (default `480p`). Durations are 1–15 seconds. Up to 7 image references (addressable in the prompt as `[Image 1]`, `[Image 2]`, …) and 3 audio references (each 3–15 seconds). Audio references require at least one image reference, and requests with image references are capped at 720p.
* **Grok Imagine Video 1.5 Image-to-Video** uses `resolution` (`480p` / `720p` / `1080p`, default `480p`) to set output quality. Output aspect ratio follows the input image. Only a single `first` frame is supported via `promptImage`.
* **HappyHorse 1.0 Text-to-Video** supports 10 `width:height` ratios across 720p and 1080p (`1280:720`, `1920:1080`, `720:1280`, `1080:1920`, `960:960`, `1440:1440`, `1108:832`, `1662:1248`, `832:1108`, `1248:1662`).
* **HappyHorse 1.0 Image-to-Video** uses `resolution` (`720P` / `1080P`, default `720P`) to set output quality. Output aspect ratio follows the input image. Prompt images must be at least 300px on each side.
* **Gemini Omni Flash Text-to-Video** and **Image-to-Video** support Landscape `1280:720` and Portrait `720:1280` outputs only (always 720p, default `1280:720`).
* **Gemini Omni Flash Video-to-Video** has no `ratio` parameter; output is 720p with orientation (landscape 16:9 or portrait 9:16) matched to the input video. Input videos can be at most 10 seconds.
* **Magnific Video Upscaler** (`magnific_video_upscaler_creative`) accepts input videos up to 30 seconds. Set `resolution` to `720p`, `1k`, `2k` (default), or `4k` for target output quality. Include `model: magnific_video_upscaler_creative` on `POST /v1/video_upscale`.
* **Enhance Frame Rate** (`enhance_frame_rate`) accepts input videos up to 300 seconds. Required `targetFramerate` is `24`, `25`, `30`, `48`, `50`, `60`, `120`, `23_98`, `29_97`, or `59_94`. Include `model: enhance_frame_rate` on `POST /v1/video_upscale`.
If your input asset is not exactly of the `ratio` you specify, the model will auto-crop your asset from the center to the aspect ratio parameter provided.
Third party models (e.g., `veo3.1`, `veo3.1_fast`, `wan3`, `h3_max`, `grok_imagine_1_5`, `grok_imagine_image_2`, `muse_image`, `gpt_image_2_5_flare`, `gpt_image_2_5_sunburst`, `happyhorse_1_0`, `gemini_omni_flash`, etc.) may crop or resize inputs in other ways.
### Image references
Image references may be resized if they are too large or small to be provided to the model you choose. It is not recommended to provide reference images smaller than 640×640px or larger than 4K.
### Input asset aspect ratio requirements
For models that accept image or video references, the asset’s aspect ratio (width ÷ height) must fall within the supported ranges below:
| Model | Input type | Min aspect ratio | Max aspect ratio |
| --------------------------------- | ----------------------------------- | ---------------- | ---------------- |
| Gen-4 Turbo Image-to-Video | Prompt image | 0.5 | 2.358 |
| Gen-4 Image-to-Video | Prompt image | 0.5 | 2.358 |
| Gen-4.5 Image-to-Video | Prompt image | 0.5 | 2 |
| Act-Two | Character image | 0.5 | 2.358 |
| Act-Two | Character video | 0.5 | 2.358 |
| Act-Two | Reference video | 0.5 | 2.358 |
| Seedance 2.5 Image-to-Video | Prompt image (first/last/reference) | 0.4 | 4 |
| Seedance 2.5 Text-to-Video | Reference image | 0.4 | 4 |
| Seedance 2.5 Video-to-Video | Reference image | 0.4 | 4 |
| Seedance 2 Image-to-Video | Prompt image (first/last/reference) | 0.4 | 4 |
| Seedance 2 Text-to-Video | Reference image | 0.4 | 4 |
| Seedance 2 Video-to-Video | Reference image | 0.4 | 4 |
| Seedance 2.0 Fast Image-to-Video | Prompt image (first/last/reference) | 0.4 | 4 |
| Seedance 2.0 Fast Text-to-Video | Reference image | 0.4 | 4 |
| Seedance 2.0 Fast Video-to-Video | Reference image | 0.4 | 4 |
| Seedance 2.0 Mini Image-to-Video | Prompt image (first/last/reference) | 0.4 | 4 |
| Seedance 2.0 Mini Text-to-Video | Reference image | 0.4 | 4 |
| Seedance 2.0 Mini Video-to-Video | Reference image | 0.4 | 4 |
| MiniMax H3 Max Image-to-Video | Prompt image (first/last) | 0.2 | 4 |
| MiniMax H3 Image-to-Video | Prompt image (first/last/reference) | 0.2 | 4 |
| MiniMax H3 Text-to-Video | Reference image | 0.2 | 4 |
| MiniMax H3 Video-to-Video | Reference image | 0.2 | 4 |
| Veo 3.1 / 3.1 Fast Image-to-Video | First/last keyframes | 0.5 | 2 |
| HappyHorse 1.0 Image-to-Video | Prompt image | 0.55 | 1.8 |
| Gemini Omni Flash Image-to-Video | Prompt image | 0.5 | 2 |
| Gemini 2.5 Flash Text-to-Image | Reference image | 0.25 | 4 |
---
# API Output Formats
> Understand Runway Dev output formats and responses. Learn how to handle generated videos, images and metadata from AI generation requests.
After a task succeeds, the `GET /v1/tasks/:id` endpoint will return a response like this:
```json
{
"id": "d2e3d1f4-1b3c-4b5c-8d46-1c1d7ee86892",
"status": "SUCCEEDED",
"createdAt": "2024-06-27T19:49:32.335Z",
"output": [
"https://dnznrvs05pmza.cloudfront.net/output.mp4?_jwt=..."
]
}
```
The `output` member will contain one or more URLs that link to the result of your generation.
It’s important to note that these URLs are ephemeral: they will expire within 24-48 hours of accessing the API. We expect you to download the data at this endpoint and save it to your own storage. Since these URLs will expire, do not expose them directly in your product.
---
# Ephemeral uploads
> Upload large files to Runway Dev for processing
When providing files as [inputs](/assets/inputs), there are size limits for assets provided by URL or data URI. URLs need to be downloaded and data URIs must be processed as part of the request body: both consume resources at the time a generation is started. To avoid these limits, you can upload ephemeral files to Runway Dev using the uploads API.
## Uploading files
You can upload a file to Runway by using our [SDKs](/api-details/sdks/).
* Node
You can pass Node `fs` streams or `File`s (or [`File`-like objects](https://github.com/runwayml/sdk-node/blob/main/src/internal/to-file.ts#L37-L52)) to `createEphemeral`.
```ts
import * as fs from 'node:fs';
import RunwayML from '@runwayml/sdk';
const client = new RunwayML();
const myFile = fs.createReadStream('./path/to/file.mp4');
const { uri } = await client.uploads.createEphemeral(myFile);
console.log(uri); // runway://...
```
Other files can be uploaded by passing them to the `toFile` helper from `@runwayml/sdk`. Supported types include:
* `Blob` and [`Blob`-like objects](https://github.com/runwayml/sdk-node/blob/main/src/internal/to-file.ts#L11-L32)
* `Buffer`
* `ArrayBuffer`
* Typed arrays (e.g., `Uint8Array`)
* `DataView`
* `Response` and [`Response`-like objects](https://github.com/runwayml/sdk-node/blob/main/src/internal/to-file.ts#L57-L66)
* Any [async iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncIterator) object that yields `string`s, `Buffer`s, `ArrayBuffer`s, `ArrayBufferView`s, `Blob`-like objects, or `DataView`s.
```ts
import * as fs from 'node:fs/promises';
import RunwayML, { toFile } from '@runwayml/sdk';
const client = new RunwayML();
const { uri } = await client.uploads.createEphemeral(
toFile(
await fs.readFile('./path/to/file.mp4')
// You must pass a filename
'file.mp4',
),
);
console.log(uri); // runway://...
```
* Python
You can pass the following types to `create_ephemeral`:
* `pathlib.Path` object or an object that implements `os.PathLike`
* An `IOBase` object (e.g., `BytesIO`) with a `name` property containing the filename
```python
from pathlib import Path
from runwayml import RunwayML
client = RunwayML()
my_file = Path('./path/to/file.mp4')
response = client.uploads.create_ephemeral(file=my_file)
print(response.uri) # runway://...
```
If you do not have a `Path` or `IOBase` with a name, you can pass a two-tuple in the form `(filename, content)` where `filename` is the name of the file and `content` is one of:
* A file-like object (e.g., the output of `open()`)
* `bytes`
```python
from runwayml import RunwayML
client = RunwayML()
with open('./path/to/file.mp4') as my_file:
response = client.uploads.create_ephemeral(
file=('file.mp4', my_file),
)
print(response.uri) # runway://...
```
The resulting `runway://` URI can be used anywhere that a URL or data URI can be used in the API.
### Considerations
* `runway://` URIs are only valid for 24 hours.
* The maximum uploadable file is 200MB. The minimum uploadable file is 512 bytes.
* You must have purchased credits to use this feature.
* There is a rate limit on the upload of ephemeral files.
Ephemeral uploads may be used multiple times, which can conserve bandwidth. If you intend to use a file multiple times, consider using ephemeral uploads. Be aware, though, that the URI will expire 24 hours after creation and the file must be re-uploaded.
## Using ephemeral uploads without an SDK
If you use our REST API directly, you can still use ephemeral uploads. By calling `POST /v1/uploads` with the following JSON body, you can start an upload:
```json
{
"filename": "filename.mp4",
"type": "ephemeral"
}
```
* `filename`: A string containing the filename of the file you are uploading. The file extension must be representative of the file’s contents.
* `type`: Must be set to `"ephemeral"`.
The server will respond with the following details:
```json
{
"uploadUrl": "https://...",
"fields": { ... },
"runwayUri": "runway://..."
}
```
The `runwayUri` value is the value that may be used when creating a new generation on Runway Dev.
To upload the file to Runway’s servers, create a `POST` request to the URL at `uploadUrl`. Pass the fields in the dictionary `fields` as the multipart form-encoded POST body, and the contents of the file as the `file` field.
Once the upload completes successfully, the `runway://` URI is ready to use.
If the upload fails, do not retry. Instead, make a new request to `/v1/uploads` and start over. Be sure to follow our guidelines for [handling errors](/errors/errors/) to ensure your integration robustly handles different kinds of failure modes.
---
# HTTP Error Codes
> Understand Runway Dev HTTP error codes and responses. Troubleshoot common errors, status codes and learn how to handle API exceptions properly.
You may receive a variety of errors from our API. This matrix shows what you might expect, why, and whether it is safe to retry these requests.
| HTTP Status | Description | May retry? |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| 400 | There is a problem with one of the inputs for the request. Expect a JSON response with an `error` member with a human-readable explanation of the problem. | No |
| 401 | The provided API key is not valid. | No |
| 404 | Requests will return a 404 when the referenced resource is not available | No |
| 405 | If an endpoint is called with a HTTP method that it does not support, this response code will be returned. | No |
| 429 | If the client makes too many requests to the API within a period of time, this response code will be returned. This may be returned when an integration’s limits have been reached. | Yes |
| 502 | This error is returned when Runway is shedding load | Yes |
| 503 | This error is returned when Runway is shedding load | Yes |
| 504 | This error is returned when Runway is overloaded and not able to satisfy the request | Yes |
When retrying requests due to an error, implement [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) and jitter. To implement jitter, add a random delay of up to 50% to your retry timing: doing this prevents [thundering herds](https://en.wikipedia.org/wiki/Thundering_herd_problem).
Note: [Runway’s SDKs](/api-details/sdks) will handle retries automatically.
---
# Handle Task Failures
> Troubleshoot task failures on Runway Dev. Learn about common generation errors, retry strategies and how to handle failed AI video requests.
When a task fails, the [Get Task endpoint](/api/#tag/Task-management/paths/~1v1~1tasks~1%7Bid%7D/get) endpoint returns a `failureCode` indicating the problem that occurred during processing.
## `SAFETY` failures
Failure codes that start with `SAFETY.` indicate that the task was rejected because of content moderation. Content moderation is performed on both task inputs as well as outputs.
When a failure code is in the form `SAFETY.INPUT.*`, it indicates that one of the inputs contained content that was deemed unsupportable. When in the form `SAFETY.OUTPUT.*`, it indicates that content moderation rejected the output of the task.
The end of the failure code indicates the likely source of rejection. `SAFETY.INPUT.TEXT`, for instance, indicates that prompt text was rejected. If multiple inputs would be rejected, you will receive a failure for the first one that was tested.
While we make a best-effort attempt to ensure the accuracy of the third component of these failure codes, they may not correspond exactly to inputs. You may, for instance, receive a `SAFETY.INPUT.TEXT` failure on a task that provides no `promptText` argument. You should treat these as diagnostic messages only rather than exposing them to users.
You should not retry these generations.
## `INTERNAL.BAD_OUTPUT` failures
Failure codes in the form `INTERNAL.BAD_OUTPUT.*` represent generations that were rejected by our internal systems for quality or system error reasons.
The most common failure of this category is `INTERNAL.BAD_OUTPUT.01`. Common causes for this error include:
* Logos, watermarks, or overlaid text in input media
* Prompt including explicit text generation requests
* Prompt requested that a media generation prompt be written rather than provided directly (e.g. “write a prompt for…”)
You may retry these generations, they may succeed if corrections were made to prompts based on the above common errors.
## `INPUT_PREPROCESSING.SAFETY.TEXT`
This failure code indicates that input prompt text was rejected for content moderation reasons.
You should not retry these generations.
## `INPUT_PREPROCESSING.INTERNAL`
This failure code indicates that there was a problem performing content moderation.
You may retry these generations, but you should add a delay.
## `ASSET.INVALID`
One of the inputs that you provided (an image, video, etc.) is not acceptable for the type of task that you ran. This often indicates a problem with the dimensions, duration, or other properties of the media you provided.
You should not retry these errors, as they indicate a problem with your inputs.
## `THIRD_PARTY.UNAVAILABLE`
When invoking a generation with a model that’s provided by a third party, it’s possible for the third party to fail to provide an output due to unavailability (e.g., an outage, load shedding, etc.).
You should not retry these errors immediately as they are unlikely to succeed. You may wait and retry the generations.
## `INTERNAL` or a `null` value
`INTERNAL` or an undefined or null value indicates that there was an internal problem processing the task.
You may retry these generations, but you should add a delay.
---
# API Troubleshooting Guide
> Debug issues with your Runway Dev integration. Find solutions for common problems, error messages and integration challenges with our troubleshooting guide.
## Troubleshooting assets
When submitting an asset, the API may return a `400 Bad Request` response if the asset cannot be used. If you’re using SDKs, a `BadRequestError` will be [thrown in Node](https://github.com/runwayml/sdk-node?tab=readme-ov-file#handling-errors) or [raised in Python](https://github.com/runwayml/sdk-python?tab=readme-ov-file#handling-errors).
The message in the error response body will include two pieces of pertinent information: the field that the error occurred for (e.g., `promptImage`) and the reason for the failure.
### Common failures
#### You’re receiving a `401 Unauthorized` response
If you’re using [our SDKs](/api-details/sdks/), you may not have set your API key. Check that you’re providing your key with the `RUNWAYML_API_SECRET` environment variable, or as an argument to the RunwayML SDK client constructor.
Next, be sure your API key is well-formed. Keys start with `key_` and are followed by 128 hexidecimal characters (`/^key_[0-9a-f]{128}$/` as a regular expression). Be sure there is no whitespace at the end of your key.
If you’re not using our SDKs:
1. First, check that you’re using the correct hostname. You should be using `api.dev.runwayml.com` for your request, not `api.runwayml.com`.
2. Be sure you’re passing the key in the `Authorization` header. It should look like `Authorization: Bearer key_0123456789abcdef`.
Other reasons why an API key might be rejected with a 401 response:
* The key has been disabled in the developer portal
* The account associated with the key was suspended
#### You’re receiving a `400 Bad Request` response
This means that the input you provided is not correct.
First, you’ll want to inspect the output of the response. You can see this output in the developer portal by clicking “Manage” at the top, then “Request History”. Select the failing request to see the response. 400 Bad Request error responses are usually formatted with a description of each error.
#### A Model Router request returns a “no eligible model” error
When you route a request through a [Model Router](/model-routers), the request can fail if no model satisfies the configuration’s constraints and the request together. The error identifies which constraint(s) emptied the eligible pool — for example, your maximum credits per generation and the requested duration leaving nothing eligible.
To resolve it, update the configuration in the Developer Portal to adjust the constraints, commonly by adding additional enabled models or raising the maximum credits per generation. See [Configuring a Model Router](/model-routers/configuration) for the available settings.
Here’s a breakdown of a sample error:
```json
{
"error": "Validation of body failed",
"docUrl": "https://docs.dev.runwayml.com/api",
"issues": [
{
"code": "custom",
"path": ["promptImage"],
"message": "Assets must use an approved Content-Type response header. We received \"application/octet-stream\", which is not allowed."
}
]
}
```
1. The **issues array** contains a list of each problem encountered while inspecting your request.
2. The **error code** shows the type of problem. In this example, the error is a custom error, not a problem with the structure of the input.
3. The **error path** tells you the location of the error. A path of `["promptImage"]` tells you that the problem is with the `promptImage` parameter. If the path was `["contentModeration","publicFigureThreshold"]`, it would indicate that the problem is with the `publicFigureThreshold` field nested inside `contentModeration`.
4. The **error message** tells you what is wrong. In this case, Runway attempted to fetch the image URL in `promptImage` with a HTTP request, but the server returned a `Content-Type` response header that’s not supported.
### Common error reasons
* Invalid data URI.
The provided data URI is malformed and could not be parsed. Be sure you’re using a library to encode the URI.
* Unsupported asset type. Data URIs must include the content type of the value they encode.
Your data URI specifies a media type that’s not supported. See the list of [supported media types](/assets/inputs#type-specific-requirements).
* Invalid URL
You provided a URL that is non-standard and cannot be parsed.
* Only HTTPS URLs are allowed.
All URLs must start with `https://`. You cannot use `http://` or other schemes, like `ftp://`.
* URLs must be hosted on a domain.
You cannot provide a URL that points to an IP address. For instance, `https://11.22.33.44/foo/bar` would be rejected. You can instead create an A or AAAA record for your domain that points at the IP address of your host (in the example here, an A record pointing to `11.22.33.44`). Be sure to set up HTTPS on the host for that record.
* Failed to fetch asset. The URL may be incorrect or the server hosting the asset may be down.
When we attempted to fetch the asset, we encountered a non-HTTP connection issue. This might be a DNS issue, TCP connection issue, TLS problem, protocol error, or an unexpectedly closed connection. Check that the URL is working and that connections are not being rejected.
* Failed to fetch asset. Received HTTP response code ”…”
When we attempted to fetch the asset, we did not get a 200 status code. The response code that we received is provided in the reason. Be aware that we do not follow redirects (via the `Location` HTTP response header).
* Timeout while fetching asset.
It took longer than ten seconds to download the provided asset.
* Assets must use an approved Content-Type response header. We received application/octet-stream, which is not allowed.
Your server returned `application/octet-stream` for the `Content-Type` HTTP response header. This is not allowed. See the list of [supported media types](/assets/inputs#type-specific-requirements).
* Unsupported Content-Type response header: ”…”.
Your server returned an unsupported value for the `Content-Type` HTTP response header, which is noted in the response. See the list of [supported media types](/assets/inputs#type-specific-requirements).
* Content-Length not provided
Your server did not specify a `Content-Length` HTTP response header. Lengths must be provided; we do not support streaming responses of unknown length.
* Asset size exceeds XX.XMB.
Your server specified a `Content-Length` HTTP response header that exceeds the maximum size for the asset type. This error may also be returned if the number of bytes returned by the server does not match the number specified in the `Content-Length` response header. The maximum size is specified in the reason and in the [inputs](/assets/inputs) documentation.
* Asset size exceeds XX.XMB.
Your server specified a `Content-Length` HTTP response header that exceeds the maximum size for the asset type. The maximum size is specified in the reason.
* Invalid asset dimensions. Height and width must not exceed 8000px. Got XXxYY.
The provided asset is larger than 8000px on one of its sides. Assets must be less than 8000px on either side.
* Invalid asset aspect ratio. width / height ratio must be between XX and YY. Got ZZ.
The aspect ratio (the asset width divided by the asset height) must be between the values XX and YY. The computed aspect ratio is included in the reason as ZZ.
### Debugging failures
You can investigate the cause(s) for many common failures by simulating our request for your asset. To do this, we’ll run a cURL command against the URL you’ll specify for your asset. For this example, we’ll use the asset URL `https://example.com/assets/image.jpg`.
```sh
curl "https://example.com/assets/image.jpg" \
-I \
-H "User-Agent: RunwayML API/1.0"
```
You’ll receive output that looks like this:
```text
% curl "https://example.com/assets/image.jpg" \
-I \
-H "User-Agent: RunwayML API/1.0"
HTTP/2 200
content-type: image/jpg
content-length: 123456
vary: Accept-Encoding
cache-control: max-age=14400
accept-ranges: bytes
alt-svc: h3=":443"; ma=86400
```
1. Your server should be returning a `200` status code.
2. Be sure you’re returning an acceptable `Content-Type`.
3. A `Content-Length` should be provided with an accurate file size.
---
# Production Launch Checklist
> Prepare your Runway Dev integration for production. Review our go-live checklist for security, performance and best practices before launching.
Before going live, make sure that you’ve checked and double-checked that everything is in order. This is a checklist of things that you might not think of.
## 1. Manage your usage
### Tier up
Limits on your project are governed by [tiers](/usage/tiers). If you haven’t done much testing or haven’t added many credits to your project, your tier may not allow enough generations per day or enough [concurrent generations](/usage/tiers#concurrency-limit) to satisfy your users’ demand.
Tiering up involves adding credits and waiting set intervals (predetermined by the tier). If you have an estimate for how many generations you’ll be creating, you should tier up to a tier that allows for that many generations per day.
### Set up autobilling
Make sure you have set up autobilling for your project. Autobilling will ensure that your integration doesn’t run out of credits unexpectedly. To set up autobilling, you’ll set up a payment method to be charged. You’ll also provide a threshold below which your credit balance will be recharged at, and the number of credits to add.
You can learn more about autobilling in the [autobilling docs](/usage/autobilling).
## 2. Test your integration
Make sure you’ve tested your integration thoroughly. You should be sure that your integration can tolerate different kinds of failures, like `429 Too Many Requests` errors (indicating your integration has reached the rate limit) and `503 Service Unavailable` errors (indicating a service outage).
A full list of errors is documented on [our errors page](/errors/errors).
### Check your integration’s validation
Also be sure to check the [API documentation](/api) to ensure inputs that you are passing are validated. For example, passing a `promptImage` referencing an image that’s too large or an unsupported codec will result in a `400 Bad Request` error. Test with a variety of inputs to ensure you haven’t missed any edge cases.
All URLs that you pass should be sure to follow the guidance in the [inputs documentation](/assets/inputs).
## 3. Secure your integration
Keeping your integration secure is important to make sure your key is not abused. There are a few important steps to making sure your integration is built securely.
If you find that any key was stored insecurely, immediately disable the key. You can do this from the API Keys tab in the developer portal.
### Ensure your key is stored securely
Your API key should never be hard-coded into your application. Instead, load your key from secure storage (like a secrets manager), or from environment variables that are set securely.
Double check that your key is not stored in your codebase, as anyone with access to your source code (or who obtains a copy of your source code) could abuse your key. You can easily search for your key with `git grep`:
```sh
# Search a git repository for Runway API key prefixes
git grep "key_"
```
Recommended key storage methods:
* [HashiCorp Vault](https://www.hashicorp.com/products/vault)
* [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/)
* [Google Cloud Secret Manager](https://cloud.google.com/secret-manager)
* [Azure Key Vault](https://azure.microsoft.com/en-us/services/key-vault/)
* [Render environment variables](https://docs.render.com/configure-environment-variables)
* [Heroku config vars](https://devcenter.heroku.com/articles/config-vars)
### Stop sharing keys
Create API keys liberally and revoke them when they are no longer needed. If you have a staging environment, create a new API key for it that’s separate from your production API key. If you create keys for developers to test with on their local machines, each developer should have their own key.
Any keys that are shared between individuals or environments should be disabled and replaced.
## 4. Monitor your integration
Knowing how your integration is behaving in production is important for diagnosing issues. We recommend a few metrics for you to measure:
1. **API error rate**: While some errors are expected (like `404 Not Found` errors when making idempotent task deletion requests), you should be sure that you are not receiving errors in production. Errors like `429 Too Many Requests` indicate that your integration has been temporarily shut off after reaching a limit.
2. **API request count**: You should know how many requests your integration is making per day. This will help you understand how many credits you are using and how close you are to your tier limits.
3. **Throttled task count**: While it’s safe to treat tasks whose status is `THROTTLED` as though they are `PENDING`, too many throttled tasks could be a sign that your integration is approaching your generation limit.
### Ensure you’re receiving emails
You’ll receive emails about your integration at the email address that you signed up for the developer portal with. Make sure that this email address is monitored and that emails from Runway are not being marked as spam. You’ll receive emails about autobilling charges and charge failures: failing to receive these notices may cause your integration to run out of credits.
### Avoid account suspension
Runway will [moderate unsafe requests](/api-details/moderation). Too many moderated requests will lead to account suspension.
Ensure that the use case for your integration is not in [our moderated categories](/api-details/moderation#moderated-content-categories). If needed, ensure you have implemented content moderation before making requests to Runway.
---
# API Attribution Requirements
> Follow Runway Dev attribution guidelines. Learn how to properly credit AI-generated content when using Runway's models in your applications.
When attributing to Runway, please use “Powered by Runway” and link to Runwayml.com from the user interface.
## Branding assets
You can use the below assets to attribute:
 [Download Dark Logo (PNG)](https://runway-static-assets.s3.amazonaws.com/site/images/api-page/powered-by-runway-black.png)\
[Download Dark Logo (SVG)](https://runway-static-assets.s3.amazonaws.com/site/images/api-page/powered-by-runway-black.svg)
 [Download Light Logo (PNG)](https://runway-static-assets.s3.amazonaws.com/site/images/api-page/powered-by-runway-white.png)\
[Download Light Logo (SVG)](https://runway-static-assets.s3.amazonaws.com/site/images/api-page/powered-by-runway-white.svg)
---
# Automatic Billing Setup
> Set up autobilling for Runway Dev usage. Configure automatic payments, credit purchases and billing thresholds for uninterrupted AI video generation.
To help prevent your project from running out of credits, you can use autobilling to automatically top up your project’s credits. [Create an account](https://dev.runway.com/) to get started.
## Setting up autobilling
On the billing tab of your project, choose the option to set up autobilling. Setting up and changing autobilling needs the Admin or Billing admin role — see [Projects and roles](/usage/organizations-and-roles).
First, you’ll need to choose thresholds for autobilling:
1. The “recharge below” value is the threshold below which your credits should be topped up.
2. The “recharge amount” value is the number of credits that will be purchased. This must be at least 1000 credits (or $10).
Next, you’ll need to provide a payment method. You can add a payment method through Stripe.
## Autobilling process
Every hour, we’ll check whether your credit balance has dropped below your autobilling “recharge below” threshold. If it has, we’ll attempt to charge the payment method on file for the number of credits specified by the “recharge amount”. Be aware that sales tax may be applied to the charge depending on your location.
If the payment fails, we’ll notify you by email. We’ll retry the charge after 24 hours. If the payment still fails, we’ll notify you by email and retry a final time 24 hours later. If all three attempts fail, we will not reattempt autobilling.
### Fixing autobilling
Depending on the reason for the autobilling payment failure, you may or may not need to provide a new payment method. For example, a declined charge due to insufficient funds may not require a new payment method, while a declined charge due to an expired card will.
After providing the new payment details, you will have the option in the portal to manually trigger autobilling. If the manually-triggered payment succeeds, autobilling that has been stopped due to three successive failures will be re-enabled.
## Tier considerations
Each usage tier specifies a maximum monthly spend amount. This is the maximum number of credits that can be purchased in any 30 day window. If your project’s current usage tier has a remaining monthly spend that’s lower than your “recharge amount”, the recharge amount will be capped at the remaining monthly spend.
If your project’s remaining monthly spend is below $10, autobilling will fail.
---
# AWS Marketplace
> Subscribe to Runway Dev through AWS Marketplace and bill usage to your AWS account. Learn how onboarding works and what changes for your project.
You can subscribe to Runway Dev through [AWS Marketplace](https://aws.amazon.com/marketplace) and have your usage billed to your AWS account.
## How it works
An AWS Marketplace subscription links a Runway Dev project you own — new or existing — to your AWS account.
While the subscription is active, the project’s API usage is reported to AWS periodically and appears on your AWS bill. Existing Runway credits in the project are spent first. AWS billing applies once those credits run out.
Reported AWS Marketplace usage counts toward the spend criteria for automatic [usage tier](/usage/tiers) upgrades. Qualifying credit purchases made before the subscription was attached continue to count toward your project’s tier.
To request higher limits, select **Request exception** on your project’s Usage page in the Developer Portal. The process is the same for projects billed through AWS Marketplace.
## Subscribing
Subscribe to the [Runway Dev listing](https://aws.amazon.com/marketplace/pp/prodview-iruhzes2gogto) in AWS Marketplace. AWS then redirects you to the Developer Portal, where you log in (or create an account) and choose or create the project to attach the subscription to.
For general AWS guidance, see [Subscribing to SaaS products](https://docs.aws.amazon.com/marketplace/latest/buyerguide/saas-subscriptions.html).
## Using the API
Linking a subscription does not change how you access or use the API. You continue to [use Runway Dev](/guides/using-the-api) and your project as before: existing API keys continue to work, and your access to models and features remains unchanged.
## Limitations
* Existing Runway Dev credits in the project are spent first. AWS billing applies only once those credits run out.
* You cannot purchase additional credits or use [autobilling](/usage/autobilling) while a subscription is attached.
## Unsubscribing
Cancel your subscription from the AWS Marketplace console — see [Canceling your SaaS subscription](https://docs.aws.amazon.com/marketplace/latest/buyerguide/cancel-subscription.html#cancel-saas-subscription).
Canceling stops future AWS Marketplace billing after the cancellation is processed, and the project then returns to standard credit-based billing. Canceling does not refund usage already billed to your AWS account.
---
# Manage Teams & Permissions
> Manage projects and user roles in Runway Dev. Set up team permissions and access controls for API usage.
You can add and remove members from your project to share access to key management, usage stats, and billing setup.
## Adding members to your project
Visit the Members page in Runway Dev to invite members by email address, and pick the role they should have. Invitations default to Admin, so set the role before sending.
If they do not already have an account, they will be prompted to create one and join your project.
If they already have an account, they will see a notification that they have been invited to join your project. This appears under invitations on the top navigation bar.
Inviting someone who already has an invitation pending replaces it, and the role on the newest invitation applies.
## Project roles
Every member holds one of three roles, which applies across the whole project.
| Role | Access |
| ------------- | -------------------------------------------------------------------------------------- |
| Admin | Everything. |
| Billing admin | Credits, payment methods, autobilling, and members. Cannot create or disable API keys. |
| Developer | API keys. Cannot manage credits, payment methods, autobilling, or members. |
All three roles can use the Playground, build Model Routers, and read usage and request history. Linking a Runway web app workspace under Manage → Connections needs Admin or Billing admin.
The member who created the project is listed as its owner. The owner has the same access as an Admin, and cannot be given another role, removed, or leave the project.
Where your role does not allow an action, the control is greyed out with a note on who to ask.
## Changing a member’s role
Admins and Billing admins can change a member’s role, including their own, from the Members page: open the menu on the member’s row and choose Edit role.
## Removing members from your project
Admins and Billing admins can remove members from the Members page, using the same menu. Any member can leave the project themselves.
Removing a user from your project does not revoke their API key access. Because keys are project-scoped (not user-scoped), you must disable keys separately to fully cut off access.
---
# API Usage Tiers & Limits
> Understand Runway Dev usage tiers and rate limits. Learn about request quotas, scaling options and tier benefits for different usage levels.
In order to protect our API against abuse and to ensure fair access to our models, we have limits in place that govern how many generations you can create. [Create an account](https://dev.runway.com/) to get started.
## Usage Tiers
Each project on Runway Dev is subject to a set of limits. The tier sets the limits of your project. The limits are per model, per project. For example, imagine you are on Tier 3. Your project can have 5 concurrent Gen-4.5 generations and 5 concurrent Veo 3.1 generations simultaneously.
Most models within the same modality share the same concurrency limits, determined by your tier and listed below. Ruby, Enhance Frame Rate, and Magnific upscalers share a separate limit table (matching each other). When your project reaches the spend criteria for the next tier, the tier upgrade applies automatically with no waiting period.
Gen-4.5 (gen4.5)
⚠
Or try [Model Routers](/model-routers) to never need to manage deprecations again.
| Tier | Max concurrency | Max gens/day | Max spend/mo. | Criteria to reach tier |
| ---- | --------------- | --------------------------- | ------------- | ---------------------------------- |
| 1 | 1 2 2 1 | 50 200 200 50 | $100 | |
| 2 | 3 3 3 3 | 500 1,000 1,000 500 | $500 | Immediately after $50 purchased |
| 3 | 5 5 5 5 | 1,000 2,000 2,000 1,000 | $2,000 | Immediately after $100 purchased |
| 4 | 10 10 10 10 | 5,000 10,000 10,000 5,000 | $20,000 | Immediately after $1,000 purchased |
| 5 | 20 20 20 20 | 25,000 30,000 30,000 25,000 | $100,000 | Immediately after $5,000 purchased |
For custom tier information, higher limits, or guaranteed concurrency, file an exception request from the usage page when logged in to the developer portal. These and other benefits fall under [enterprise partnerships](/#enterprise-benefits)
## Details
### Concurrency limit
This is the *maximum* number of tasks the API will allow you to run concurrently. If you submit more tasks than this limit, your tasks will have a `status` of `"THROTTLED"`, indicating that the task is stored on our servers but has not been enqueued for processing. Throttled tasks will be enqueued in approximately the order that they were submitted in.
Note that all video generation models share the same concurrency limits, as do all image generation models. Runway Characters has the same concurrency limits as Gen-4.5 and other video models. Ruby (`ruby`), Enhance Frame Rate (`enhance_frame_rate`), and Magnific upscalers share the same concurrency and daily limits as each other — select them in the table above for the per-tier values. To discuss custom concurrency options, reach out to
In rare cases, you may experience lower than maximum concurrency depending on system load. If you are interested in guaranteed (minimum) concurrency, please contact us using the limits exception form in the usage page of the developer portal.
##### Concurrency limit example
To help you reason about how these limits work, here’s an example using some approximations.
Assume you want to generate 200 videos and you have a concurrency limit of 5:
1. You can submit all 200 video request tasks at the same time.
2. Runway handles the queueing logic and starts executing them in rapid fashion 5-at-a-time, in sequential order based on creation time.
3. The first 5 videos finish in 15 seconds and the 6th to 10th videos begin generating. They finish in 15 additional seconds.
4. All 200 videos are complete within 10 minutes (15 seconds x 200 videos / 5 concurrency).
### No maximum requests-per-minute limit
There is **no maximum requests-per-minute limit**, as long as your requests are within your maximum daily generations limit.
If you submit more generations than can execute simultaneously on your concurrency limit, our API queues the additional requests. You do not need to add rate-limiting logic to your integration.
### Maximum daily generations
This is the maximum number of generations you can create in a 24-hour rolling window. The limit resets continuously based on when each request was made, not at a fixed daily reset time.
If you exceed this limit, you’ll receive a `429 Too Many Requests` response to the task creation request, indicating you’ve exceeded your quota.
### Maximum monthly spend
This is the amount of money your project is allowed to spend on credits in a 30-day window. You will be prevented from purchasing more than this amount, and autobilling will cap any automatic recharges at your remaining monthly spend.
---
# Export Workspace Usage and Audit Logs
> Pull per-generation credit usage and audit log history for the Runway web app workspaces your organization administers. Use the API for chargeback, audit pipelines, and security reviews.
Enterprise plans only
These endpoints only work for organizations on an enterprise plan. Requests from any other project return `401`.
Three endpoints report on the Runway web app workspaces your API project is linked to: one row per generation with the credits it cost, and audit log entries as a list or one at a time with full detail.
The usual reasons to use them:
* Charging credits back to the client or cost center that spent them.
* Feeding audit events into the log and security tooling you already run.
* Pulling a complete trail of Runway activity for a security review.
For one-off answers, use the web app: [Enterprise Analytics](https://help.runwayml.com/hc/en-us/articles/27339017751699-Enterprise-Analytics) and [Enterprise Audit Logs](https://help.runwayml.com/hc/en-us/articles/53089650822803-Enterprise-Audit-Logs) both filter on screen and export to CSV. The API is for keeping something in sync without a person in the loop.
`/v1/organization/usage` is different: it reports what this API project spent on its own calls. Web app credits and API credits are [separate pools](https://help.runwayml.com/hc/en-us/articles/50683115755155-Runway-API-FAQs).
## Before you start
The API project has to be [linked to a Runway account](https://help.runwayml.com/hc/en-us/articles/50682640721555-Linking-Developer-and-Web-App-accounts): generate a one-time code in the developer portal under Manage → Connections, then paste it into the web app.
Whoever creates that link sets what the API project can read:
* A link created by a person covers every organization workspace where that person is an [admin](https://help.runwayml.com/hc/en-us/articles/43200006470163-Role-permissions-table).
* A link created while acting as a workspace covers that one workspace.
You cannot widen that scope from the API. With no link, requests fail with `400` and `No workspace is linked to this API project.`
Every request needs the standard headers:
```sh
Authorization: Bearer $RUNWAYML_API_SECRET
X-Runway-Version: 2024-11-06
```
## Export a month of credit usage
`/v1/organization/webapp/usage` returns one row per generation, newest first. Both `from` and `to` are required here. `from` is inclusive, `to` is exclusive.
* cURL
```sh
curl -G https://api.dev.runwayml.com/v1/organization/webapp/usage \
-H "Authorization: Bearer $RUNWAYML_API_SECRET" \
-H "X-Runway-Version: 2024-11-06" \
--data-urlencode "from=2026-01-01T00:00:00Z" \
--data-urlencode "to=2026-02-01T00:00:00Z"
```
* Node
No SDK has a typed method for these, so use the client’s generic `get`:
```ts
import RunwayML from '@runwayml/sdk';
const client = new RunwayML();
const page = await client.get('/v1/organization/webapp/usage', {
query: { from: '2026-01-01T00:00:00Z', to: '2026-02-01T00:00:00Z' },
});
```
Each row says who generated what, where, and at what cost:
```json
{
"data": [
{
"timestamp": "2026-01-15T18:04:11.000Z",
"userId": 12345,
"email": "member@acme.com",
"workspaceId": 6789,
"workspaceName": "Acme Video Team",
"tool": "Gen-4 Video",
"credits": 50
}
],
"hasMore": true,
"nextCursor": "MjAyNi0wMS0xNVQxODowNDoxMS4wMDBa"
}
```
Two fields need care. `email` is empty once that person is deleted, so key your reports on `userId`. `timestamp` is when the generation was charged, which is what a bill reconciles against.
These are raw rows rather than summaries. There is no aggregate endpoint; totals like credits per workspace or active users per month are yours to compute, which is what the chargeback example below does.
## Page through every row
Both list endpoints share one envelope: `data`, `hasMore`, `nextCursor`. `limit` accepts 1 to 100, default 50. For the next page, send `nextCursor` back as `cursor` with the same filters. Treat cursors as opaque strings and pass them through verbatim. You are done once `hasMore` is `false` and `nextCursor` is `null`.
```ts
type UsageRow = {
timestamp: string;
userId: number;
email: string;
workspaceId: number;
workspaceName: string;
tool: string;
credits: number;
};
const rows: Array = [];
let cursor: string | null = null;
while (true) {
const page = (await client.get('/v1/organization/webapp/usage', {
query: {
from: '2026-01-01T00:00:00Z',
to: '2026-02-01T00:00:00Z',
limit: 100,
...(cursor ? { cursor } : {}),
},
})) as { data: Array; hasMore: boolean; nextCursor: string | null };
rows.push(...page.data);
if (!page.hasMore || page.nextCursor === null) break;
cursor = page.nextCursor;
}
```
A busy month runs to thousands of rows, so mind the rate limit below.
## Report on specific workspaces
Two optional filters work on all three endpoints. `workspaceIds` takes up to 50 comma-separated IDs and defaults to every workspace the linked account administers. An ID outside your scope fails the whole request with `400`: a typo cannot quietly narrow a report. `organizationId` picks the [organization](https://help.runwayml.com/hc/en-us/articles/40261817303699-Organization-spaces-for-Enterprise): optional with one linked, required with several. Add either to any of the three requests:
```sh
--data-urlencode "organizationId=0195a3f2-1e5f-7abc-8def-0123456789ab" \
--data-urlencode "workspaceIds=6789,6790"
```
## Roll usage up for chargeback
Every row carries `workspaceId` and `credits`, so a chargeback report is a group-by over the rows you already have:
```ts
const perWorkspace = new Map();
for (const row of rows) {
const spent = perWorkspace.get(row.workspaceName) ?? 0;
perWorkspace.set(row.workspaceName, spent + row.credits);
}
console.log(Object.fromEntries(perWorkspace));
```
Which gives you the numbers to invoice against:
```json
{
"Acme Video Team": 12480,
"Acme Stills": 3215,
"Acme Social": 890
}
```
Group by `email` for a per-person breakdown, or by `tool` to see where the spend goes. Enterprise credits come from [one shared pool](https://help.runwayml.com/hc/en-us/articles/32117491177619-Enterprise-Credits); how you split them is your call.
## Read the audit log
`/v1/organization/webapp/audit_logs` returns the same events an admin sees under Organization Settings → Audit Logs, newest first, with the same envelope and filters. `from` and `to` are optional here. Omit both to walk the full history backwards.
Two filters are specific to it. `actions` takes up to 50 audit actions and rejects unsupported values with `400`. `actorEmails` takes up to 50 emails, and an address Runway does not recognize returns an empty page rather than an error.
Supported actions cover logins and SSO provisioning, membership changes, asset and sharing activity, and billing events, including `AssetDownloaded` and `CreditsTransferred`. The [API reference](/api#tag/Organization) lists every accepted value.
```sh
curl -G https://api.dev.runwayml.com/v1/organization/webapp/audit_logs \
-H "Authorization: Bearer $RUNWAYML_API_SECRET" \
-H "X-Runway-Version: 2024-11-06" \
--data-urlencode "actions=MemberInvited,MemberRemoved" \
--data-urlencode "from=2026-01-01T00:00:00Z" \
--data-urlencode "to=2026-02-01T00:00:00Z"
```
```json
{
"data": [
{
"eventId": "0195a3f2-1e5f-7abc-8def-0123456789ab",
"timestamp": "2026-01-20T09:30:00.000Z",
"action": "MemberInvited",
"actorUsername": "jane",
"actorEmail": "jane@acme.com",
"actorDeleted": false,
"workspaceId": 6789,
"workspaceName": "Acme Video Team"
}
],
"hasMore": false,
"nextCursor": null
}
```
`actorUsername` and `actorEmail` can both be `null`, so do not depend on either to identify the actor. `actorDeleted` means that person has since been deleted.
## Get the full detail for one event
For everything recorded about one event, fetch it by `eventId`:
```sh
curl https://api.dev.runwayml.com/v1/organization/webapp/audit_logs/0195a3f2-1e5f-7abc-8def-0123456789ab \
-H "Authorization: Bearer $RUNWAYML_API_SECRET" \
-H "X-Runway-Version: 2024-11-06"
```
You get the list fields plus action-specific `metadata` and the request details an investigation needs:
```json
{
"metadata": {
"Invited member": "new.member@acme.com",
"Role": "member"
},
"resourceType": "membership",
"resourceId": "123",
"clientIpAddress": "203.0.113.10",
"userAgent": "Mozilla/5.0",
"requestId": "req-abc"
}
```
`metadata` uses readable keys such as `Invited member` and `Previous role`, and only the keys relevant to that action appear, so read it defensively.
This endpoint takes `organizationId` too. A missing event and an event outside your scope both return `404`, so a `404` is not proof that nothing happened.
## Run it on a schedule
For a nightly export, ask for a closed time window rather than saving a cursor between runs. A cursor is only valid with the filters it was issued alongside:
```sh
--data-urlencode "from=2026-01-20T00:00:00Z" \
--data-urlencode "to=2026-01-21T00:00:00Z"
```
Because `to` is exclusive, consecutive windows meet without double counting the boundary row.
Audit logs allow another approach: start at the newest entry and stop paging once you reach an `eventId` you already stored.
## Errors and rate limits
Each endpoint allows 10 requests every 10 seconds per API project, then answers `429 Too Many Requests`. A short sleep between pages keeps a paging loop under it.
| Status | What it means |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400` | A validation failure in `from`, `to`, `cursor`, `actions`, `workspaceIds`, `organizationId`, or `actorEmails`. Also: no linked account, a missing `organizationId` when several are linked, or a workspace out of scope. |
| `401` | A missing or invalid API key, an organization not on an enterprise plan, a linked account with no organization workspace, or an `organizationId` not linked to this project. |
| `404` | The audit log entry does not exist or is not visible to your linked workspaces. Detail endpoint only. |
| `429` | Rate limit exceeded. |
Follow the guidance on [handling errors](/errors/errors/) so a scheduled export survives the occasional `429` without losing a day of data.
---
# API Changelog & Updates
> Track Runway Dev changes and updates. View version history, new features, breaking changes and improvements to AI video generation endpoints.
A comprehensive history of updates, new features, and improvements to Runway Dev. [Create an account](https://dev.runway.com/) to get started today.
#### Enhance Frame Rate on Runway Dev
September 17th, 2026 - Enhance Frame Rate (`enhance_frame_rate`) is now available on Runway Dev. Convert a video to a target frame rate of `24`, `25`, `30`, `48`, `50`, `60`, `120`, `23_98` (23.98 fps), `29_97` (29.97 fps), or `59_94` (59.94 fps). Inputs can be at most 300 seconds. Billed at 1 credit per 2 seconds. Use the [video upscale endpoint](/api#tag/Start-generating/paths/~1v1~1video_upscale/post) with `model: "enhance_frame_rate"` to get started.
#### Ruby ACEScg sequences are now referenced to the source
September 12th, 2026 - The `hdr_exr_acescg_sequence_1_3` and `hdr_exr_acescg_sequence_2_0` outputs of [`/v1/video_to_hdr`](/api#tag/Start-generating/paths/~1v1~1video_to_hdr/post) are now built from the source plate: the plate brought into ACEScg through the inverse ACES SDR (Rec.709) Output Transform, with the highlight detail Ruby recovers added on top. Read with the stock `ACES - ACEScg` input transform, the ACES SDR view reproduces the source and the ACES HDR views render the same scene with the recovered highlights. Previously these sequences were the HDR10 picture inverted through the ACES 1000-nit Output Transform, which matched `hdr10` in an HDR view but lifted midtones and desaturated the image in any SDR view. The `colorimetry.json` sidecar now records `construction: plate-referenced`. Gen-4.5 ACEScg outputs are unchanged.
#### Alpha channel support on `/v1/video_to_hdr`
September 11th, 2026 - Ruby now preserves the alpha channel of a source video on [`/v1/video_to_hdr`](/api#tag/Start-generating/paths/~1v1~1video_to_hdr/post). Sources with alpha (ProRes 4444, WebM with alpha, RGBA codecs) are detected automatically; no request parameter is needed. The EXR deliveries (`hdr_exr_sequence`, `hdr_exr_acescg_sequence_1_3`, `hdr_exr_acescg_sequence_2_0`) write the alpha as the `A` channel, and `hdr_prores` is delivered as ProRes `4444` regardless of `proresProfile`, the only tier with an alpha plane. The alpha is passed through unchanged and is not premultiplied. `hdr10` and `hlg` cannot carry alpha and deliver the video without it. Pricing is unchanged.
#### GPT Image 2.5 on Runway Dev
September 8th, 2026 - OpenAI’s GPT Image 2.5 Flare (`gpt_image_2_5_flare`) and GPT Image 2.5 Sunburst (`gpt_image_2_5_sunburst`) are now available on Runway Dev. Both generate images from a prompt of up to 32,000 characters, accept up to 16 reference images (with optional prompt-referenceable tags), support 30 `width:height` ratios across 1K, 2K, and 4K tiers plus an `auto` resolution, and take `outputCount` from 1–10. `quality` is `low`, `medium`, `high` (the default), `xhigh`, or `max`. Sunburst can return transparent backgrounds with `background: "transparent"`; Flare supports `opaque` and `auto` only. Billed at 1–76 credits per image by quality and resolution, plus 1 credit per reference image per generated image. Use the [text to image endpoint](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) to get started.
#### MiniMax H3 Max on Runway Dev
September 3rd, 2026 - MiniMax H3 Max (`h3_max`) is now available on Runway Dev. Generate videos from a text prompt or a start-frame image, with an optional last-frame keyframe. Durations are 5–15 seconds at `480p` or `768p`. Use `promptExpansionMode` to keep the prompt as written (`disabled`), apply a short rewrite (`balanced`, the default), or spend extra time rewriting (`quality`). Billed at 5 credits per second at `480p` and 8 credits per second at `768p`. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post) and [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) endpoints to get started.
#### ACEScg EXR delivery
August 31st, 2026 - HDR outputs can now be delivered as scene-referred ACEScg OpenEXR sequences — in both ACES 1.3 and ACES 2.0 variants, with `outputFormat: "hdr_exr_acescg_sequence_1_3"` or `"hdr_exr_acescg_sequence_2_0"` matching your pipeline’s config version — on [`/v1/video_to_hdr`](/api#tag/Start-generating/paths/~1v1~1video_to_hdr/post) and on Gen-4.5 HDR generations. The delivered picture is inverted through the matching ACES Output Transform (Rec.2100 PQ, 1000-nit) into the ACEScg working space, so the frames drop straight into ACES-configured comps: read them with the stock `ACES - ACEScg` input transform and your ACES viewing pipeline reproduces the delivered picture, with the same zip contract as `hdr_exr_sequence` (colorimetry and provenance sidecars, `audio.wav` when the source has audio) and the same 20 / 40 credits-per-second rate as the other HDR profiles.
#### WAN 3.0 on Runway Dev
August 26th, 2026 - WAN 3.0 (`wan3`) is now available on Runway Dev. Generate up to 30 seconds of video with native audio from a text prompt or a start-frame image. WAN 3.0 is built for reference-driven shots — pass images, video, or audio to keep characters and style consistent, or use first and last keyframes to lock the edit. Output at 480p, 720p, or 1080p. Billed at 5 credits per second at 480p, 10 at 720p, and 20 at 1080p. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post) and [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) endpoints to get started.
#### Muse Image on Runway Dev
August 26th, 2026 - Meta Muse Image (`muse_image`) is now available on Runway Dev. Generate images from text with optional reference images — when references are provided, the model edits and combines them as the prompt describes. Supports prompts up to 4,000 characters, up to 10 reference images, `outputCount` from 1–10, and eight `width:height` ratios plus `auto`. Billed at 1 credit per image, multiplied by `outputCount`. Use the [text to image](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) endpoint to get started.
#### SDR to HDR in Runway API
August 20th, 2026 - Ruby (`ruby`) is now available via the Runway API. Convert any SDR video — uploads or generations from any model — into true HDR, delivered as 10-bit HEVC in HDR10 (`outputFormat: "hdr10"`, the default) or HLG (`"hlg"`) with BT.2020 signaling and measured HDR10 metadata, as a BT.2020 + PQ ProRes `.mov` editorial mezzanine (`"hdr_prores"`; tier selectable with `proresProfile` — `422`, `422 HQ`, or `4444`, defaulting to `422 HQ`), or as a `.zip` of half-float OpenEXR frames carrying the upconverted signal as linear BT.2020 light for compositing (`"hdr_exr_sequence"`; the zip includes colorimetry and provenance sidecars, plus `audio.wav` when the source has audio). The conversion preserves the source’s own pixels and audio: brightness is extended into HDR headroom with a bounded, color-preserving grade, and nothing is re-rendered. Inputs must be SDR (HDR-tagged videos are rejected), at most 30 seconds, and under 4096 pixels per side. Billed at 20 credits per second, or 40 credits per second when the source is larger than 4 megapixels (roughly 4K). Use the [`/v1/video_to_hdr`](/api#tag/Start-generating/paths/~1v1~1video_to_hdr/post) endpoint to get started.
#### HDR output formats for Gen-4.5 and Aleph 2.0
August 20th, 2026 - Gen-4.5 text to video and image to video can now deliver directly in HDR and post-production formats via `outputFormat`: `hdr10` and `hlg` streaming HDR, `sdr_rec709_10bit` for 10-bit SDR grading, and mastering-grade `hdr_pq_12bit_master` (12-bit lossless), `hdr_prores` (ProRes 422 HQ), `hdr_png_sequence` (bit-exact 16-bit frames), and `hdr_exr_sequence` (half-float OpenEXR frames as linear BT.2020 light, compositor-native). HDR outputs are true HDR renders — graded into BT.2020 with measured HDR10 metadata — not tone-mapped afterward. Aleph 2.0 adds `sdr_rec709_10bit` for 10-bit SDR delivery; to deliver an Aleph edit in HDR, chain it through [`/v1/video_to_hdr`](/api#tag/Start-generating/paths/~1v1~1video_to_hdr/post). These formats are being enabled progressively per account. Non-mp4 formats add 5 credits per second for `prores` and `png_sequence`, or 20 credits per second for 10-bit and deeper profiles (including EXR), rising to 40 credits per second when the output is larger than 4 megapixels (roughly 4K). See [Professional and HDR output formats](/guides/models#professional-and-hdr-output-formats) to get started.
#### Seedance 2.5 1080p
August 15th, 2026 - Seedance 2.5 (`seedance2_5`) now supports 1080p output on text-to-video, image-to-video, and video-to-video. Pass a 1080p `ratio` such as `1920:1080` (16:9) or `1080:1920` (9:16). 4K stays on Seedance 2.0. Billed at 68 credits per second of output and 34 credits per second of input and reference video. The 80 credit minimum is unchanged. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post), [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post), and [video to video](/api#tag/Start-generating/paths/~1v1~1video_to_video/post) endpoints to get started.
#### Grok Imagine Image 2 on Runway Dev
August 11th, 2026 - Grok Imagine Image 2 (`grok_imagine_image_2`) is now available on Runway Dev. Generate images from text with optional reference images, an `edit` mode for direct image editing or combining references, `quality` of `low` or `medium` (default `medium`), `outputCount` from 1–4, and fixed `width:height` ratios across 1K and 2K plus `auto_1k` and `auto_2k`. Up to 3 reference images. Billed at 4–8 credits per image by quality and resolution, plus 1 credit per reference image charged once per request (not per output). Use the [text to image](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) endpoint to get started.
#### Grok Imagine Video 1.5 on Runway Dev
August 7th, 2026 - Grok Imagine Video 1.5 (`grok_imagine_1_5`) is now available on Runway Dev. Generate videos from text or a start-frame image with optional native audio, prompt-addressable image references, and audio references. Text-to-video supports `ratio` values `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, and `2:3`, with `resolution` of `480p`, `720p`, or `1080p` (default `480p`). Durations are 1–15 seconds. Up to 7 image references and 3 audio references (each 3–15 seconds); audio references require at least one image reference, and requests with image references are capped at 720p. Image-to-video uses a single `first` frame (`promptImage`); output aspect ratio follows the input image. Billed at 10 credits per second at 480p, 16 at 720p, and 29 at 1080p, plus 1 credit per image or audio reference (including an image-to-video start frame). Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post) and [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) endpoints to get started.
#### Seedance 2.5 on Runway Dev
August 7th, 2026 - Seedance 2.5 (`seedance2_5`) is now available on Runway Dev. Generate cinematic videos from text, images, or video with optional generated audio, larger reference budgets, and durations from 4–30 seconds at 480p or 720p. Text-to-video can run from references alone (omit `promptText` when at least one image, video, or audio reference is provided). Video-to-video accepts `mode: "reference"` (default) or `mode: "extend"` — extend requires `promptText` and matches the input aspect ratio, so `ratio` may not be provided. Reference limits: up to 30 images, 10 videos, and 10 audio clips (combined reference video and audio duration must stay under 30 seconds; video-to-video reserves one video slot for `promptVideo`). Input videos must be at least 480p. At 480p, ratios `864:496` and `496:864` deliver standard 854×480 / 480×854 output rather than the literal pixel counts. Billed at 30 credits per second of output at 720p and 20 at 480p, plus 15 (720p) or 10 (480p) credits per second of input and reference video; reference images and audio are free. Minimum 80 credits per generation. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post), [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post), and [video to video](/api#tag/Start-generating/paths/~1v1~1video_to_video/post) endpoints to get started.
#### Hailuo 3.0 on Runway Dev
August 5th, 2026 - Hailuo 3.0 (`hailuo3`) is now available on Runway Dev. Generate videos from text, images, or video with support for keyframe control, reference images, reference videos, and reference audio. Hailuo 3.0 supports text-to-video, image-to-video, and video-to-video generation modes, with durations from 5–15 seconds and output at `768P` or `2K`. Billed at 10 credits per second at `768P` and 15 credits per second at `2K`, plus 2 credits per reference image; reference video is billed at the same per-second rate as output (capped at 15 seconds). Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post), [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post), and [video to video](/api#tag/Start-generating/paths/~1v1~1video_to_video/post) endpoints to get started.
#### Gen-3 Alpha Turbo and Gen-4 Aleph sunset
July 30th, 2026 - Gen-3 Alpha Turbo (`gen3a_turbo`) and Gen-4 Aleph (`gen4_aleph`) are no longer available on Runway Dev. Requests that use these model identifiers will fail. Upgrade from Gen-3 Alpha Turbo to Gen-4.5 (best quality) or Gen-4 Turbo (fastest), and from Gen-4 Aleph to Aleph 2.0 (`aleph2`). See [available models](/guides/models) and [pricing](/guides/pricing) for current options.
#### Eleven v3 on Runway Dev
July 30th, 2026 - Eleven v3 (`eleven_v3`) is now available on Runway Dev. Generate expressive speech with audio tags like `[laughs]` and `[whispers]` in the script. Same Runway preset voices as Multilingual v2. Billed at 1 credit per 50 characters, with a 1 credit minimum. Use the [text to speech](/api#tag/Start-generating/paths/~1v1~1text_to_speech/post) endpoint to get started.
#### Organization workspace reporting
July 28th, 2026 - Organizations on an enterprise plan can now export per-generation credit usage and audit log history for the Runway web app workspaces linked to their API project. `/v1/organization/webapp/usage` returns one row per generation with the credits it cost, and `/v1/organization/webapp/audit_logs` returns audit entries that can be filtered by `actions`, `actorEmails`, and `workspaceIds`, with a companion endpoint for the full detail of a single event. See the [workspace reporting guide](/usage/workspace-reporting) and the [Organization API reference](/api#tag/Organization) to get started.
#### Model Router
July 23rd, 2026 - Model Router is now available on Runway Dev. Create a saved routing configuration once and reference it by `configId` to route video, image, and audio generations to the best model for your use case — the router filters to eligible models and selects one based on your optimization preference (cost, latency, or quality), so you never have to name a model. Configure model allow and deny lists and optional per-modality credit ceilings (`video`, `image`, `audio`), and preview routing decisions with `dryRun` before generating. See [Model Routers](/model-routers) and the [Model Router API reference](/api#tag/Model-Router) to get started.
#### Veo negative prompt
July 10th, 2026 - Optional `negativePrompt` is now available on `veo3`, `veo3.1`, and `veo3.1_fast` text-to-video and image-to-video requests. Pass text describing what should not appear in the output (up to 1,000 characters). Omit the field to use Runway’s default negative prompt. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post) and [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) endpoints to get started.
#### Seedream 5.0 Lite on Runway Dev
July 10th, 2026 - Seedream 5.0 Lite (`seedream5_lite`) is now available on Runway Dev. Generate images from text with optional reference images for multi-image fusion and interactive editing. Supports prompts up to 4,000 characters, up to 14 reference images, `outputCount` from 1–4, optional `outputFormat` (`png` or `jpeg`, default `png`), and 16 `ratio` values across 2K and 3K at eight aspect ratios (`1:1`, `4:3`, `3:4`, `16:9`, `9:16`, `3:2`, `2:3`, `21:9`). Billed at 4 credits per image at any resolution, multiplied by `outputCount`. Use the [text to image](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) endpoint to get started.
#### Seedream 5.0 Pro on Runway Dev
July 8th, 2026 - Seedream 5.0 Pro (`seedream5_pro`) is now available on Runway Dev. Generate images from text with optional reference images for multi-image fusion and interactive editing. Supports prompts up to 4,000 characters, up to 10 reference images, `outputCount` from 1–4, optional `outputFormat` (`png` or `jpeg`, default `png`), and 14 fixed `ratio` values across 1K and 2K at seven aspect ratios (`1:1`, `4:3`, `3:4`, `16:9`, `9:16`, `3:2`, `2:3`), plus `auto_1k` and `auto_2k` to let the model pick aspect ratio at a fixed resolution tier. Billed at 5 credits per 1K image and 9 credits per 2K image, multiplied by `outputCount`. Use the [text to image](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) endpoint to get started.
#### Gemini Omni Flash on Runway Dev
July 1st, 2026 - Gemini Omni Flash (`gemini_omni_flash`) is now available on Runway Dev. Generate videos from text, a first-frame image, or an existing video, with output at 720p and optional generated audio. Text-to-video and image-to-video support durations from 3–10 seconds (default 5) at landscape `1280:720` or portrait `720:1280`. Video-to-video edits an input video of up to 10 seconds — output matches the input’s duration and orientation — and accepts up to 5 reference images to guide the edit. Text-to-video and image-to-video are billed at 10 credits per second (plus 1 credit for the first-frame image on image-to-video), and video-to-video at 11 credits per second of input video plus 1 credit per reference image. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post), [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post), and [video to video](/api#tag/Start-generating/paths/~1v1~1video_to_video/post) endpoints to get started.
#### Seed Audio 1.0 on Runway Dev
June 30th, 2026 - Seed Audio 1.0 (`seed_audio`) is now available on Runway Dev. Generate speech and sound effects from text, with optional audio references of up to 30 seconds to guide the output. Seed Audio 1.0 supports up to 120 seconds of generated audio and can output in WAV, MP3, and Ogg Opus formats. It is billed at 0.25 credits per second, with a 5 credit minimum per generation. Use the [text to speech](/api#tag/Start-generating/paths/~1v1~1text_to_speech/post) and [sound effect](/api#tag/Start-generating/paths/~1v1~1sound_effect/post) endpoints to get started.
#### Seedance 2.0 Mini on Runway Dev
June 26th, 2026 - Seedance 2.0 Mini (`seedance2_mini`) is now available on Runway Dev. Generate videos from text, images, or video with support for keyframe control, reference images, reference videos, and generated audio. Seedance 2.0 Mini supports image-to-video, text-to-video, and video-to-video generation modes, with durations from 4–15 seconds and output at 480p or 720p. Seedance 2.0 Mini is billed at 16 credits per second, with a 64 credit minimum per generation. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post), [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post), and [video to video](/api#tag/Start-generating/paths/~1v1~1video_to_video/post) endpoints to get started.
#### Ad Localization Recipe
June 25th, 2026 - The Ad Localization Recipe (`ad_localization`) is now available on Runway Dev. Localize an existing ad image for a target language while preserving visual creative and layout. Billed at 21 credits per localized image. Use the [Ad Localization Recipe](/recipes/ad-localization) guide and [API reference](/api#tag/Recipes/paths/~1v1~1recipes~1ad_localization/post) to get started.
#### 4K support for Seedance 2.0
June 24th, 2026 - Seedance 2.0 (`seedance2`) now supports 4K output. Six new 4K `ratio` values are available across the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post), [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post), and [video to video](/api#tag/Start-generating/paths/~1v1~1video_to_video/post) endpoints: `3840:1646` (21:9), `3840:2160` (16:9), `3840:2880` (4:3), `3840:3840` (1:1), `2880:3840` (3:4), and `2160:3840` (9:16). These are in addition to the existing 480p, 720p, and 1080p options, and the default `ratio` remains `1280:720`. 4K generations are billed at 150 credits per second.
#### Magnific Video Upscaler
June 11th, 2026 - Magnific Video Upscaler (`magnific_video_upscaler_creative`) is now available on Runway Dev. Upscale input videos up to 30 seconds to `720p`, `1k`, `2k` (default), or `4k` output resolution, with optional controls for creativity, sharpen, smart grain, flavor, and fps boost. Always set `model` to `magnific_video_upscaler_creative` on the [video upscale endpoint](/api#tag/Start-generating/paths/~1v1~1video_upscale/post). Billing is per output frame — see [video upscale pricing](/guides/pricing#video-upscale-pricing).
#### Seedance 2.0 Fast on Runway Dev
June 5th, 2026 - Seedance 2.0 Fast (`seedance2_fast`) is now available on Runway Dev. Generate videos faster from text, images, or video with support for keyframe control, reference images, reference videos, and generated audio. Seedance 2.0 Fast supports image-to-video, text-to-video, and video-to-video generation modes, with durations from 4–15 seconds and output at 480p or 720p. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post), [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post), and [video to video](/api#tag/Start-generating/paths/~1v1~1video_to_video/post) endpoints to get started.
#### Aleph 2.0 on Runway Dev
June 2nd, 2026 - Aleph 2.0 is now available on Runway Dev. Edit existing videos with text prompts and optional keyframe images placed at specific timestamps. Aleph 2.0 supports input videos from 2–30 seconds, up to 5 keyframe images, and optional content moderation settings. Use the model identifier `aleph2` with the [video to video endpoint](/api#tag/Start-generating/paths/~1v1~1video_to_video/post). The `aleph2_alpha` identifier remains available as a deprecated alias.
#### HappyHorse 1.0
May 29th, 2026 - HappyHorse 1.0 (`happyhorse_1_0`) is now available on Runway Dev. Generate videos from text or from a first-frame image with durations from 3–15 seconds. Text-to-video supports 10 output dimensions across 720p and 1080p. Image-to-video preserves your input aspect ratio and accepts an optional motion prompt. Use the [text to video](/api#tag/Start-generating/paths/~1v1~1text_to_video/post) and [image to video](/api#tag/Start-generating/paths/~1v1~1image_to_video/post) endpoints to get started.
#### Seedance 2.0 on Runway Dev
May 28th, 2026 - Seedance 2.0 is now available on Runway Dev. Generate high-quality videos from text, images, or video with support for keyframe control, reference images, reference videos, and generated audio. Seedance 2.0 supports image-to-video, text-to-video, and video-to-video generation modes, with durations from 4–15 seconds.
#### Gemini 3 Pro Image (Nano Banana Pro)
April 30th, 2026 - Gemini 3 Pro Image, also known as Nano Banana Pro (`gemini_image3_pro`), is now available on Runway Dev. Generate images with up to 5,500-character prompts and up to 14 reference images, at 1K, 2K, or 4K resolution across 10 aspect ratios. Use the [text to image endpoint](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) to get started.
#### GPT Image 2
April 23rd, 2026 - OpenAI’s GPT Image 2 (`gpt_image_2`) is now available on Runway Dev. Supports up to 16 reference images (with optional prompt-referenceable tags), 30 `width:height` ratios across 1K, 2K, and 4K tiers plus an `auto` resolution, and tiered pricing by resolution and quality. Unlike `gpt_image_1`, transparent backgrounds are not supported. Use the [text to image endpoint](/api#tag/Start-generating/paths/~1v1~1text_to_image/post) to get started.
#### Gen-4.5 on Runway Dev
February 10th, 2026 - Gen-4.5 is now available on Runway Dev. Generate high-quality videos from text alone or from images with improved quality and control. Gen-4.5 supports both text-to-video and image-to-video generation modes, with durations from 2-10 seconds. Learn more at [Gen-4.5 announcement](https://runwayml.com/research/introducing-runway-gen-4.5).
#### ElevenLabs Clean Audio
October 16th, 2025 - ElevenLabs Voice Isolation is available directly on Runway Dev. Strip background noise from any recording and isolate crisp, clear speech—built for film, podcast, and interview workflows.
#### ElevenLabs Voice Dubbing
October 16th, 2025 - ElevenLabs Dubbing is available directly on Runway Dev. Translate your content into 29 languages with AI-generated speech that maintains the speaker’s original voice characteristics and emotional tone.
#### Google Veo 3.1
October 15th, 2025 - Google Veo 3.1 text to image and image to video are now available on Runway Dev. Generate with even greater fidelity and control with first and last keyframe support, the new Reference to Video feature and support for full 1080p outputs. Learn more at the link below.
#### ElevenLabs text to Sound Effects
October 8th, 2025 - Flexible generation times for Runway video models are now available on Runway Dev. Choose any duration from 2-10 seconds using Gen-4 Turbo. Pay only for what you generate.
#### Flexible Generation Length
October 8th, 2025 - Flexible generation times for Runway video models are now available on Runway Dev. Choose any duration from 2-10 seconds using Gen-4 Turbo. Pay only for what you generate.
#### Text to Speech
September 25th, 2025 - Starting today, ElevenLabs’ Multilingual v2 Text to Speech is available directly on Runway Dev. Generate natural, emotionally-aware speech in 29 languages while maintaining consistent voice quality and personality.
#### API Playground
September 24th, 2025 - Today we’re launching the Runway Dev Playground—a new interactive environment that lets developers test and refine their integrations before going to production. Build with confidence and ship faster. The Runway Dev Playground provides a full sandbox environment with all our latest models.
#### Third Party Models
September 23rd, 2025 - Select third party models are now available on Runway Dev. All designed to make your creative workflows even more robust and controllable within Runway. Starting with Google Veo3 and Nano Banana (gemini\_2.5\_flash).
#### Launch Gen-4 Image Turbo on Runway Dev
August 19th, 2025 - Introducing our fastest image model. Generate with reference images in 10 seconds or less. Gen-4 Image Turbo costs 2.5-4x less than non-turbo and achieves a 93.3% quality Dreambench++ Score compared to standard Gen-4 Image generations.
#### Aleph on Runway Dev
August 1st, 2025 - [Aleph](https://runwayml.com/research/introducing-runway-aleph) is now available on Runway Dev, allowing you to bring an entirely new to way to edit, transform and generate videos directly into your apps, products, platforms and websites.
#### Act-Two on Runway Dev
July 21st, 2025 - Act-Two is now available on Runway Dev, allowing you to bring our most advanced motion capture directly into your apps, products, platforms and websites.
#### Runway MCP Server
June 13th, 2025 - Our [MCP server](https://github.com/runwayml/runway-api-mcp-server) is now available on GitHub. Now you can connect Claude, or any MCP-compatible assistant, directly to Runway’s generation capabilities, allowing you to build AI agents that can generate videos, images and more as part of automated workflows.
#### Launch Gen-4 Image on Runway Dev
May 16th, 2025 - Gen-4 Image is now available on Runway Dev, allowing anyone to integrate its powerful multimodal generation capabilities directly into their apps, products, platforms and websites.
---
# API Version 2024-11-06
> API change log
The `2024-11-06` API version introduces changes to the `/v1/image_to_video` endpoint.
## `ratio`
The `ratio` parameter no longer accepts `16:9` and `9:16`. Instead, it now accepts the resolution for the output video directly. The accepted values are:
* `1280:768`
* `768:1280`
These new values will be accepted by the previous API version (`2024-09-13`), allowing you to incrementally upgrade, however be aware that this older API version will be phased out over time.
## `promptImage`
The `promptImage` parameter was previously defined as a `string`. It is now equivalent to the following:
* TypeScript
```ts
type promptImage =
| string
| Array<{
uri: string;
position: 'first' | 'last';
}>;
```
* Python
```python
from typing import Union, List, Literal, TypedDict
class ImagePosition(TypedDict):
uri: str
position: Literal['first', 'last']
PromptImage = Union[str, List[ImagePosition]]
```
The following two are equivalent:
```json
{
"promptImage": "https://example.com/image.jpg"
}
```
```json
{
"promptImage": [
{
"uri": "https://example.com/image.jpg",
"position": "first"
}
]
}
```
If you were to set `position` to `"last"`, the generated video will end with the image instead of starting with it.
```json
{
"promptImage": [
{
"uri": "https://example.com/image.jpg",
"position": "last"
}
]
}
```
You can also pass two images to the `promptImage` parameter:
```json
{
"promptImage": [
{
"uri": "https://example.com/image1.jpg",
"position": "first"
},
{
"uri": "https://example.com/image2.jpg",
"position": "last"
}
]
}
```
In the above example, the generated video will start with `image1.jpg` and end with `image2.jpg`.
Caution
Each image in the `promptImage` array must have a unique `position`.
## `seed`
The maximum value of `seed` is now `4294967295` (or `2^32 - 1`), up from `999999999`.