Aug 30, 2026
How to Use the Seedance API: Generate Video from Text or Images (2026)
Cost Optimization
A working guide to the Seedance API: text to video and image to video with Seedance 2.5 and 2.0, async job flow, prompt patterns, and a Python client.

Submit a job, poll for the result, get an mp4 URL. Here's the whole flow, with the prompt patterns that make Seedance outputs worth keeping.
Seedance 2.5 and 2.0 are available as APIs on the Yotta AI Gateway, which means you can generate video with the same key and billing you'd use for the Gateway's text models. This guide covers the full flow: authentication, text to video, image to video, polling, parameters, and what good prompts look like. If you're deciding between the two models first, start with the Seedance 2.5 vs 2.0 comparison. For how the Seedance family stacks up against other video models, see Kling vs Seedance and the best AI video models roundup.
What you need
An API key from the Yotta console. Video requests authenticate with an X-API-KEY header. Four Seedance models are available:
| Model string | What it does |
| seedance-2.5-t2v | Text to video, up to 30s, 480p to 1080p |
| seedance-2.5-i2v | Image to video, up to 30s, 480p to 1080p |
| seedance-2.0-t2v | Text to video, up to 15s, 480p to 4K |
| seedance-2.0-i2v | Image to video, up to 15s, 480p to 4K |
The async pattern
Video generation is not a single request-response. Every job follows the same three steps:
- POST the job to /text-to-video/generations or /image-to-video/generations. You get back a request_id.
- GET /text-to-video/generations/{request_id} (or the i2v equivalent) to check status.
- When status is completed, the response carries an output_url for the finished video. The failed and cancelled statuses are the terminal error states.
Text to video
curl -X POST "$BASE_URL/text-to-video/generations" \
-H "X-API-KEY: $YOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5-t2v",
"parameters": {
"prompt": "A single continuous shot inside a small pizza shop on a rainy evening. The camera dollies through the wet storefront glass toward the counter. Warm practical light, visible steam, realistic textures. Audio: rain outside softening as the camera enters, oven flame, no music.",
"duration": 8,
"resolution": "720p",
"aspect_ratio": "16:9",
"generate_audio": true,
"watermark": false,
"output_format": "mp4"
}
}'
The key parameters:
- prompt: up to 20,000 characters, but the recommended working range is up to about 1,000 English words. More direction produces better results (see prompt patterns below).
- duration: integer seconds, 4 to 30 on Seedance 2.5 and 4 to 15 on 2.0. Pass -1 for smart duration mode, where the model picks a length that fits the prompt.
- resolution: 480p, 720p, or 1080p on 2.5; 2.0 adds 4k. Default is 720p.
- aspect_ratio: adaptive (default), 16:9, 9:16, 1:1, 4:3, 3:4, or 21:9.
- generate_audio: defaults to true, and doesn't change the price either way.
- watermark: defaults to false.
Image to video
Same pattern, different endpoint, plus frame anchors:
curl -X POST "$BASE_URL/image-to-video/generations" \
-H "X-API-KEY: $YOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0-i2v",
"parameters": {
"prompt": "City skyline transitions from day to sunset, time-lapse photography.",
"first_frame": "https://your-cdn.example.com/skyline-day.png",
"last_frame": "https://your-cdn.example.com/skyline-sunset.png",
"duration": 4,
"resolution": "720p",
"aspect_ratio": "adaptive"
}
}'
- first_frame is required: a URL to the image the video starts from. Formats: jpeg, png, webp, bmp, tiff, gif, heic, heif. Each image up to 30MB, request body up to 64MB, aspect ratio between 0.4 and 2.5, width and height between 300 and 6000 pixels.
- last_frame is optional and pins where the clip ends, which is how you get controlled transitions like the day-to-sunset example.
- On i2v, adaptive aspect ratio follows the source image.
A minimal Python client
import time
import requests
class VideoGenClient:
def __init__(self, base_url, api_key):
self.base_url = base_url.rstrip("/")
self.headers = {"Content-Type": "application/json", "X-API-KEY": api_key}
def submit(self, endpoint, model, parameters):
r = requests.post(
f"{self.base_url}/{endpoint}/generations",
headers=self.headers,
json={"model": model, "parameters": parameters},
)
r.raise_for_status()
return r.json()["data"]["request_id"]
def wait(self, endpoint, request_id, poll=3, timeout=600):
start = time.time()
while time.time() - start < timeout:
r = requests.get(
f"{self.base_url}/{endpoint}/generations/{request_id}",
headers=self.headers,
)
r.raise_for_status()
data = r.json()["data"]
if data["status"] == "completed":
return data["output_url"]
if data["status"] in ("failed", "cancelled"):
raise RuntimeError(f"Generation {data['status']}")
time.sleep(poll)
raise TimeoutError("Generation timed out")
client = VideoGenClient(BASE_URL, API_KEY)
req = client.submit("text-to-video", "seedance-2.5-t2v", {
"prompt": "A paper boat drifting down a rain-swollen gutter, cinematic macro shot",
"duration": 6,
"resolution": "720p",
"generate_audio": True,
})
print(client.wait("text-to-video", req))
Prompt patterns that actually work
Seedance responds to direction, not vibes. The patterns that consistently produce usable output:
Write a shot list with timestamps. Seedance 2.5 takes frame-precise direction: “0-3 seconds: establish the room in an extreme wide shot. 3-5 seconds: cut to a medium shot as she turns.” Structuring the prompt as timed beats is the single biggest quality lever for longer clips.
Direct the audio explicitly. Both models generate audio jointly with video. Name the sounds you want and the ones you don't: “rain ambience, oven flame, a faint sizzle, no music, no narration.” Unprompted audio is where outputs drift.
Pin dialogue verbatim. If a character speaks, put the exact line in quotes and state that mouth movements must match and the clip must not end before the line finishes.
Say what must not happen. Negative constraints work: no text overlay, no logo, no distorted fingers, no camera cuts. Production users end up with a standard block of these.
Iterate cheap, render expensive. Prompt iteration at 480p costs $0.08 to $0.11 per second depending on model. Lock the prompt, then re-run the final at 1080p or, on Seedance 2.0, 4K. Full rate table on the pricing page.
Frequently asked questions
How long does a generation take?
It scales with duration and resolution. Poll rather than assume; the client above polls every 3 seconds with a 10 minute timeout, which comfortably covers 30 second 1080p jobs.
Can I generate longer than 30 seconds?
Not in one request. Seedance 2.5 supports multi-round extension: generate a clip, then extend it in follow-up rounds while keeping the scene consistent.
Which Seedance 2.x model is cheapest to experiment with?
Seedance 2.0 at 480p ($0.08 per second). A 4 second test clip costs $0.32. The Gateway catalog also carries cheaper video models outside the 2.x family, like Seedance 1.5 Pro, if you just want to test a pipeline. See the comparison post for when the 2.5 premium is worth it.
Do I control the seed?
Yes, seed is a supported request parameter, along with camera_fixed for locking the camera on i2v jobs and callback_url if you'd rather be notified than poll.
Does the API return the video file?
It returns a URL to the rendered mp4 (or mov on Seedance 2.5). Download and store it on your side; treat the URL as a delivery mechanism, not permanent storage.
Is this the same key as the rest of the Gateway?
Yes. Video endpoints live on the Yotta AI Gateway alongside the text catalog, with unified billing. Launch details are in the announcement.



