Skip to content

Generating through a Model Router

Once you’ve created a configuration, you route a generation by calling the generate endpoint for your modality with your config ID in the configId field and a model-agnostic input payload:

ModalityEndpoint
VideoPOST /v1/generate/video
ImagePOST /v1/generate/image
AudioPOST /v1/generate/audio

The router filters to eligible models for that modality, selects one according to your optimization preference, generates the output, and returns the result along with metadata about the model it chose.

Pass your config ID in the configId field and put generation options under input. You don’t specify a model — the router selects one for you.

import RunwayML, { TaskFailedError } from '@runwayml/sdk';
const client = new RunwayML();
// Route a video generation through a Model Router config
try {
const task = await client.generate.video
.create({
configId: 'preview-fast',
input: {
// Point this at your own image file
referenceImages: [
{
uri: 'https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_(cropped).jpg',
role: 'first',
},
],
promptText: 'A timelapse on a sunny day with clouds flying by',
aspectRatio: '16:9',
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);
}
}

Same pattern as video: configId plus an input object. Image input fields include promptText, optional referenceImages, aspectRatio, resolution, and outputCount. See the API reference for the full schema.

import RunwayML, { TaskFailedError } from '@runwayml/sdk';
const client = new RunwayML();
// Route an image generation through a Model Router config
try {
const task = await client.generate.image
.create({
configId: 'preview-fast',
input: {
promptText: 'A product photo of a ceramic mug on a marble counter, soft daylight',
aspectRatio: '1:1',
resolution: '2k',
},
})
.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);
}
}

Audio uses POST /v1/generate/audio. Set input.type to speech (speak promptText as a script) or audio (treat promptText as a description of the desired sound). Optional fields include voice, referenceAudios, duration, and loop — see the API reference.

import RunwayML, { TaskFailedError } from '@runwayml/sdk';
const client = new RunwayML();
// Route an audio generation through a Model Router config
try {
const task = await client.generate.audio
.create({
configId: 'preview-fast',
input: {
type: 'speech',
promptText: 'Welcome to the studio. Today we are testing routed audio.',
},
})
.waitForTaskOutput();
console.log('Task complete:', task);
} catch (error) {
if (error instanceof TaskFailedError) {
console.error('The audio failed to generate.');
console.error(error.taskDetails);
} else {
console.error(error);
}
}

Every successful response includes metadata describing the routing decision, so you can debug behavior and understand why a model was chosen:

  • The model that was actually used.
  • The config ID that was applied.
  • The optimization preference in effect.
  • The realized cost of the generation, in credits.

You’re billed for the model the router selects, at that model’s standard rate. See Pricing for per-model rates.

Today you can dry-run a Model Router request from the API or in the Developer Portal — SDK support is coming soon. Use dry-run requests to test a routing decision without generating or charging credits. To do so, call the generate endpoint with dryRun: true (curl or any raw HTTP client):

Terminal window
curl -X POST https://api.dev.runwayml.com/v1/generate/video \
-d '{
"configId": "preview-fast",
"dryRun": true,
"input": {
"referenceImages": [
{
"uri": "https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_(cropped).jpg",
"role": "first"
}
],
"promptText": "A timelapse on a sunny day with clouds flying by",
"aspectRatio": "16:9",
"duration": 5
}
}' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $RUNWAYML_API_SECRET" \
-H "X-Runway-Version: 2024-11-06"

A dry run returns the same metadata shape as a real generation — the model that would be used, the config ID and preference applied, and an estimated cost based on current pricing — but no asset is generated, stored, or returned, and the request is not billed as a generation. If the request and config together would produce a no eligible model error, the dry run returns that same error, so you see exactly what a real call would do.

A reliable pattern for agents and automation:

  1. Create or update a config with POST /v1/routers (or patch settings on an existing id).
  2. Optionally dry-run with HTTP dryRun: true on the modality endpoint you’ll use live (/v1/generate/video, /v1/generate/image, or /v1/generate/audio) and the same input you plan to use.
  3. Read routing.model, routing.estimatedCost, and routing.resolvedSettings — adjust the config or input if the choice or cost is wrong.
  4. Call the live generate endpoint (SDK generate.video.create, generate.image.create, or generate.audio.create, or HTTP without dryRun), then wait for the task (waitForTaskOutput / wait_for_task_output, or poll GET /v1/tasks/:id).
  5. On a no eligible model error, widen the allowlist, raise that modality’s credit ceiling, or soften aspect/duration — then dry-run again.

Keep the dry-run and live payloads identical except for dryRun, so the routing decision you inspected matches what you bill.

A 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 for that modality. See Configuring a Model Router for the available settings.