Seedance 2.0: text / image / first-last frame / reference-video to video, with built-in synced audio — OpenAI-compatible async API, curl & Python examples
Seedance 2.0 (ByteDance) is a multimodal video generation model. It supports four input types — text-to-video, image-to-video, first-last frame, and reference-video — and the output includes synced audio by default. RuAPI exposes an OpenAI-compatible async video API: submit a task → poll status → download the video. Billed in USDT, no foreign card required.
Audio is on by default — Seedance 2.0 videos come with a synced audio track (dialogue / ambient / SFX), no extra parameters needed.
Generated videos are kept for 7 days only. Download and save them right after generation; the link stops working once it expires.
input_type usually doesn’t need to be set — it’s inferred from the number of images/videos; you can also set it explicitly via metadata.input_type.
Mode
How to pass input
Inferred input_type
Text-to-video
prompt only
text_to_video
Image-to-video
metadata.images — 1 image
reference
First-last frame
metadata.images — 2 images
first_last_frame
Reference-video
metadata.videos — 1 video
reference
Images / videos must be publicly reachable URLs (the upstream fetches them); images support JPG / PNG / WebP, videos support MP4. base64 inline is not supported (an oversized request body will fail).
Below, each mode shows only step 1 “Submit”; steps 2 (poll) and 3 (download) are identical for all modes.
import requestsresp = requests.post( "https://www.ruapi.ai/v1/videos", headers={"Authorization": "Bearer sk-YOUR_KEY"}, json={ "model": "doubao-seedance-2.0-fast", "prompt": "Night city, neon reflecting on wet streets, cyberpunk style, camera slowly pushing in", "seconds": "5", "metadata": {"resolution": "720p", "ratio": "16:9"}, },)print(resp.json()["id"]) # get the task id, then poll & download as in the full script above
Put 1 short video URL in metadata.videos; the model reinterprets it while keeping the subject’s motion (e.g. restyle or change the scene).
curl https://www.ruapi.ai/v1/videos \ -H "Authorization: Bearer sk-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "doubao-seedance-2.0-fast", "prompt": "Keep the person's motion from the video, restyle to a neon cyberpunk street", "seconds": "5", "metadata": { "resolution": "480p", "ratio": "9:16", "videos": ["https://your-domain/dance.mp4"] } }'
import requestsresp = requests.post( "https://www.ruapi.ai/v1/videos", headers={"Authorization": "Bearer sk-YOUR_KEY"}, json={ "model": "doubao-seedance-2.0-fast", "prompt": "Keep the person's motion from the video, restyle to a neon cyberpunk street", "seconds": "5", "metadata": { "resolution": "480p", "ratio": "9:16", "videos": ["https://your-domain/dance.mp4"], }, },)print(resp.json()["id"])
Reference-video is picky about input: use a short clip that is ≤ 15 seconds with a clear subject (e.g. a person). Cartoons, clips without an obvious subject, or overly long videos often fail. It’s best if the reference’s aspect ratio matches your target ratio (e.g. a vertical source → 9:16).
images and videos are arrays — you can pass several references at once (both verified):
Multiple images: put 3 or more images in images (officially up to 9). The model combines subject / scene / style across them. With 3+ images, input_type is auto-detected as reference.
Multiple videos: put 2 or more clips in videos (officially up to 3, total duration ≤ 15 seconds).
curl https://www.ruapi.ai/v1/videos \ -H "Authorization: Bearer sk-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "doubao-seedance-2.0-fast", "prompt": "Combine the subject and style from these images into one coherent video, natural camera motion", "seconds": "5", "metadata": { "resolution": "720p", "ratio": "16:9", "images": [ "https://your-domain/ref1.jpg", "https://your-domain/ref2.jpg", "https://your-domain/ref3.jpg" ] } }'
import requestsresp = requests.post( "https://www.ruapi.ai/v1/videos", headers={"Authorization": "Bearer sk-YOUR_KEY"}, json={ "model": "doubao-seedance-2.0-fast", "prompt": "Combine the subject and style from these images into one coherent video, natural camera motion", "seconds": "5", "metadata": { "resolution": "720p", "ratio": "16:9", "images": [ "https://your-domain/ref1.jpg", "https://your-domain/ref2.jpg", "https://your-domain/ref3.jpg", ], }, },)print(resp.json()["id"])
Same for videos: replace images with videos and pass several short clips (each ideally ≤ 7 seconds with a clear subject, ≤ 15 seconds total).
Video is billed per token (resolution × duration). A pre-charge is held on submit, then recalculated by actual usage on completion — the difference is refunded. The final charge is what actually got deducted. See the pricing page.
Check two things: is the model name correct (doubao-seedance-2.0-fast), and is the address https://www.ruapi.ai/v1/videos (with /v1).
Stuck on queued / in_progress
That’s normal. Generation usually takes 1-3 minutes; keep polling and don’t set the interval too short.
Downloaded file is empty / won't open
It’s likely been more than 7 days and the upstream link expired. Download right after generation.
Reference-video task failed
This mode is picky about input. Make sure the reference video is ≤ 15 seconds, has a clear subject, and is a publicly reachable MP4. Cartoons or clips without an obvious subject often fail.
Which address do I poll?
Use the pluralGET /v1/videos/{id}. It’s the OpenAI-compatible format, and metadata.url in the response is directly the download link.