# Seedance 2.5 Reference to Video > Generate a video steered by up to 30 reference images — composite a product, character, location, or style plate into one shot by naming each reference in the prompt. ## Overview - **Endpoint**: `https://queue.modelrunner.run/bytedance/seedance-v2.5/reference-to-video` - **Model ID**: `bytedance/seedance-v2.5/reference-to-video` - **Category**: image-to-video - **Kind**: inference - **Tags**: video, image-to-video, reference-to-video, reference-image, character-consistency, video generation, audio, bytedance, seedance, seedance 2.5, 30-second-video ## Pricing - **Price**: $0.347 per output second ## Request Lifecycle This model runs on the ModelRunner **asynchronous queue API** — a single POST does not return the output. Every call requires an `Authorization: Key $MODEL_RUNNER_KEY` header. Run three steps: 1. **Submit** — `POST https://queue.modelrunner.run/bytedance/seedance-v2.5/reference-to-video` with a JSON body holding the input fields at the top level. The body may also include a reserved top-level `metadata` object — a flat string map (max 16 keys, key ≤64 / value ≤512 chars) stored on the request for your own tagging. It is never sent to the model; filter your request history with `GET https://queue.modelrunner.run/requests?metadata=` (exact key=value matches, AND-ed). The response carries request handles only (no output yet): ```json { "status": "IN_QUEUE", "request_id": "<21-char id>", "status_url": "https://queue.modelrunner.run/bytedance/seedance-v2.5/reference-to-video/requests//status", "response_url": "https://queue.modelrunner.run/bytedance/seedance-v2.5/reference-to-video/requests/", "cancel_url": "https://queue.modelrunner.run/bytedance/seedance-v2.5/reference-to-video/requests//cancel" } ``` 2. **Poll status** — `GET ` until `status` is `COMPLETED`. Possible values are `IN_QUEUE`, `IN_PROGRESS`, `COMPLETED`, `FAILED`, `CANCELLED`. A `FAILED` request responds with HTTP 400 and an `error` field. 3. **Read result** — `GET `. Returns the finished request, including the generated `output`: ```json { "id": "", "status": "COMPLETED", "output": ..., "input": ... } ``` The JavaScript and Python SDKs below perform steps 2–3 for you. In any language without an SDK (Swift, Go, Kotlin, etc.) you must implement the polling loop and the final result fetch yourself — see the cURL example for the full flow. ### Input Schema - **`prompt`** (`string`, _required_): Describe the shot, the action, the camera move, and the sound. Address the reference images positionally as @Image1, @Image2 and so on, numbered by their order in reference_images: with a product photo first and a room photo second, '@Image1 rests on the counter in @Image2, steam rising as the camera pushes in' places the product from the first reference inside the room from the second. A reference the prompt never names is usually ignored or blended into the others, so name every one you send. - **`duration`** (`integer`, _optional_): Clip length in seconds, from 4 to 30. Leave at -1 (the default) to let the model choose an appropriate whole-second length inside that range. Billing is per second of finished video, so -1 makes the cost of a run variable. - Default: `-1` - **`resolution`** (`resolution`, _optional_): Output resolution of the clip. 720p costs more per second of video than 480p. - Default: `"720p"` - Options: `"480p"`, `"720p"` - **`aspect_ratio`** (`aspect_ratio`, _optional_): Frame shape of the clip. Reference images do not dictate the framing on this variant, so pick the shape you want - a 16:9 request against 3:2 references returns a 16:9 clip. Use adaptive to let the model choose the framing instead. - Default: `"16:9"` - Options: `"16:9"`, `"4:3"`, `"1:1"`, `"3:4"`, `"9:16"`, `"21:9"`, `"adaptive"` - **`generate_audio`** (`boolean`, _optional_): Generate a synchronized soundtrack (dialogue, ambience and sound effects) together with the picture. Set false for a silent clip; the price is the same either way. - Default: `true` - **`reference_audios`** (`array`, _optional_): Experimental: up to 10 short audio references for the generated soundtrack, addressed as @Audio1, @Audio2 and so on. Each clip 2-30 seconds, 30 seconds combined at most; WAV or MP3, under 15 MB each. The clips are accepted and add nothing to the price, but their effect on the finished soundtrack has not been verified - treat the field as experimental. They cannot be sent on their own: at least one reference image is always required. - **`reference_images`** (`array`, _required_): 1 to 30 reference images that steer identity, wardrobe, product, location or style. The first entry is @Image1 in the prompt, the second @Image2, and so on. JPEG, PNG, WebP, BMP, TIFF or GIF; 300-6000 px on a side, aspect ratio between 1:2.5 and 2.5:1, under 30 MB each. The references do not fix the framing - set aspect_ratio for that. ### Output Schema _No `Output` schema properties are available._ ## Default Example **Input** ```json { "prompt": "@Image1 stands on the counter in @Image2 while the morning sun sweeps slowly across the room, a thin curl of steam rising from the spout as the camera pushes gently in past the stools. Ambient sound: an espresso machine hissing, cups clinking, quiet morning chatter.", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true, "reference_images": [ "https://media.modelrunner.ai/D2FAkKEZ7WbZsyjLhyC7T.jpeg", "https://media.modelrunner.ai/7BLQ9IGMlfwwjE2JPCNf8.jpeg" ] } ``` **Output** ```json "https://media.modelrunner.ai/sZcelxU1ikFN1ahYIDtIx.mp4" ``` ## Usage Examples ### cURL The queue API is asynchronous: submit the request, poll `status_url` until it is `COMPLETED`, then read the result from `response_url`. Requires `jq`. ```bash # 1. Submit the request (returns request handles, not the output) SUBMIT=$(curl --silent --request POST \ --url https://queue.modelrunner.run/bytedance/seedance-v2.5/reference-to-video \ --header "Authorization: Key $MODEL_RUNNER_KEY" \ --header "Content-Type: application/json" \ --data '{ "prompt": "@Image1 stands on the counter in @Image2 while the morning sun sweeps slowly across the room, a thin curl of steam rising from the spout as the camera pushes gently in past the stools. Ambient sound: an espresso machine hissing, cups clinking, quiet morning chatter.", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true, "reference_images": [ "https://media.modelrunner.ai/D2FAkKEZ7WbZsyjLhyC7T.jpeg", "https://media.modelrunner.ai/7BLQ9IGMlfwwjE2JPCNf8.jpeg" ] }') STATUS_URL=$(echo "$SUBMIT" | jq -r '.status_url') RESPONSE_URL=$(echo "$SUBMIT" | jq -r '.response_url') # 2. Poll until the request leaves the queue / in-progress state while true; do STATUS=$(curl --silent --url "$STATUS_URL" \ --header "Authorization: Key $MODEL_RUNNER_KEY" | jq -r '.status') echo "Status: $STATUS" case "$STATUS" in COMPLETED) break ;; FAILED|CANCELLED) echo "Request $STATUS"; exit 1 ;; esac sleep 1 done # 3. Read the finished request, including the generated output curl --silent --url "$RESPONSE_URL" \ --header "Authorization: Key $MODEL_RUNNER_KEY" ``` ### JavaScript ```javascript import { modelrunner } from "@modelrunner/client"; const result = await modelrunner.subscribe("bytedance/seedance-v2.5/reference-to-video", { input: { "prompt": "@Image1 stands on the counter in @Image2 while the morning sun sweeps slowly across the room, a thin curl of steam rising from the spout as the camera pushes gently in past the stools. Ambient sound: an espresso machine hissing, cups clinking, quiet morning chatter.", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true, "reference_images": [ "https://media.modelrunner.ai/D2FAkKEZ7WbZsyjLhyC7T.jpeg", "https://media.modelrunner.ai/7BLQ9IGMlfwwjE2JPCNf8.jpeg" ] } }); console.log(result.data); ``` ### Python ```python import asyncio import modelrunner_ai async def main(): response = await modelrunner_ai.submit_async( "bytedance/seedance-v2.5/reference-to-video", arguments={ "prompt": "@Image1 stands on the counter in @Image2 while the morning sun sweeps slowly across the room, a thin curl of steam rising from the spout as the camera pushes gently in past the stools. Ambient sound: an espresso machine hissing, cups clinking, quiet morning chatter.", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true, "reference_images": [ "https://media.modelrunner.ai/D2FAkKEZ7WbZsyjLhyC7T.jpeg", "https://media.modelrunner.ai/7BLQ9IGMlfwwjE2JPCNf8.jpeg" ] } ) result = await response.get() print(result["output"]) asyncio.run(main()) ``` ## Additional Resources - [Playground](https://modelrunner.ai/models/bytedance/seedance-v2.5/reference-to-video) - [OpenAPI Schema](https://modelrunner.ai/models/bytedance/seedance-v2.5/reference-to-video/openapi.json) - [LLM Instructions](https://modelrunner.ai/models/bytedance/seedance-v2.5/reference-to-video/llms.txt)