Seedance 2.1 API: Prompts, Parameters & Integration Guide
Most coverage of Seedance 2.1 right now is spec sheets and release-date rumors. This is the hands-on version: the exact Muapi async submit-poll pattern, the 2.0-to-2.1 migration path, and the production error handling you need before you ship it. One important caveat up front — as of mid-2026 ByteDance has teased Seedance 2.1 but there is no confirmed official release date, and the Muapi endpoints are live but flagged coming-soon. Build against them now so you are ready on day one.
What's New in Seedance 2.1 (and What It Means for Your Code)
Seedance 2.1 lands roughly a 20% overall quality improvement over Seedance 2.0 — for context on how 2.0 stacks up against the competition, see our Seedance 2.0 vs. Kling 3.0 breakdown. That shows up as enhanced temporal consistency (less flicker and drift across frames), more realistic motion, smarter prompt adherence, and clean 1080p output.
The detail that matters for your codebase: 2.1 is not an architectural overhaul. Your 2.0 workflows, prompt syntax, and the async submit-poll pattern transfer directly. There is exactly one new capability worth re-plumbing for — native audio generation. So frame the migration as: same integration, better output, one new switch.
Seedance 2.1 on Muapi: Endpoints, Parameters & Pricing
Two variants, two endpoints:
- Text-to-Video —
POST https://muapi.ai/api/v1/seedance-2.1-text-to-video(playground) - Image-to-Video —
POST https://muapi.ai/api/v1/seedance-2.1-image-to-video(playground)
Shared input parameters:
| Parameter | Type | Notes |
|---|---|---|
prompt | string | Required. Scene + motion description. |
image_url | string | i2v only, required. Source image to animate. |
last_image | string | i2v only, optional. Last-frame target for first-last control. |
aspect_ratio | enum | 16:9, 9:16, 1:1, 3:4, 4:3, 21:9. Default 16:9. |
resolution | enum | 480p, 720p, 1080p. Default 720p. |
duration | int | 4–12 seconds. Default 5. |
generate_audio | boolean | Native audio. Default true. |
camera_fixed | boolean | Lock camera position. Default false. |
Pricing. Both variants start at 0.4 credits per generation, and resolution drives the final cost — 720p and 1080p run higher than the 480p floor. The new Mini tier undercuts the existing Seedance lineup, so re-run your cost math during migration. Credits are debited from your wallet on completion (failed jobs don't burn credits). For free integration testing, pass is_test: true to use sandbox keys before you spend real credits.
Your First Text-to-Video Call (Async Submit + Poll)
Seedance generation is asynchronous. The canonical Muapi flow is three steps:
- Submit —
POSTyour payload with thex-api-keyheader. You get back{ "request_id": "..." }. - Poll —
GET https://muapi.ai/api/v1/predictions/{request_id}/resultuntil status is terminal. - Download — pull the
videoURL from the completed payload.
Status values you will see: queued, pending, processing, completed, failed, cancelled. Only completed, failed, and cancelled are terminal — keep polling on the others.
Critically, a generation takes 30–120s. Size your app's timeouts and polling loop for that window, or you will abort jobs that were about to succeed.
import time
import requests
API_KEY = "YOUR_API_KEY"
BASE = "https://muapi.ai/api/v1"
HEADERS = {"x-api-key": API_KEY, "Content-Type": "application/json"}
# --- cURL equivalent of the submit call ---
# curl -X POST https://muapi.ai/api/v1/seedance-2.1-text-to-video \
# -H "x-api-key: YOUR_API_KEY" \
# -H "Content-Type: application/json" \
# -d '{"prompt":"A colossal floating city drifts above luminous clouds at dusk",
# "aspect_ratio":"16:9","resolution":"1080p","duration":8,"generate_audio":true}'
def submit_t2v(prompt):
payload = {
"prompt": prompt,
"aspect_ratio": "16:9",
"resolution": "1080p",
"duration": 8,
"generate_audio": True,
"camera_fixed": False,
# "is_test": True, # sandbox: free testing, no credits spent
}
r = requests.post(f"{BASE}/seedance-2.1-text-to-video",
headers=HEADERS, json=payload, timeout=30)
r.raise_for_status()
return r.json()["request_id"]
# --- Image-to-Video variant: same flow, add image_url (+ optional last_image) ---
def submit_i2v(prompt, image_url):
payload = {
"prompt": prompt,
"image_url": image_url, # required for i2v
"resolution": "1080p",
"duration": 8,
"generate_audio": True, # native audio: ambient, SFX, dialogue
}
r = requests.post(f"{BASE}/seedance-2.1-image-to-video",
headers=HEADERS, json=payload, timeout=30)
r.raise_for_status()
return r.json()["request_id"]
def poll(request_id, max_wait=300):
url = f"{BASE}/predictions/{request_id}/result"
delay, waited = 2.0, 0
while waited < max_wait:
resp = requests.get(url, headers=HEADERS, timeout=30)
if resp.status_code == 429: # rate limited: back off, don't hammer
time.sleep(delay)
waited += delay
delay = min(delay * 2, 30) # exponential backoff, capped
continue
resp.raise_for_status()
data = resp.json()
status = data.get("status")
if status == "completed":
return data["output"]["video"]
if status in ("failed", "cancelled"):
raise RuntimeError(f"Generation {status}: {data}") # inspect full payload
# queued / pending / processing -> keep waiting
time.sleep(delay)
waited += delay
delay = min(delay * 1.5, 20)
raise TimeoutError(f"{request_id} not done after {max_wait}s")
if __name__ == "__main__":
rid = submit_t2v("A neon-lit street market in the rain, slow cinematic dolly forward")
video_url = poll(rid)
print("Video:", video_url)
requests.get(video_url, timeout=120) # download bytes as needed
Image-to-Video with Native Audio
The i2v variant is the t2v payload plus image_url (required) and an optional last_image for first-last-frame control. Your prompt here should describe motion and camera, not the scene — the image already supplies the scene.
The headline 2.1 feature is native audio generation. Set generate_audio: true (it's the default) and the model produces ambient sound, SFX, and synchronized dialogue during generation — not a separate TTS pass bolted on afterward. That synchronization is the point: lip and action timing come out aligned because audio and video are generated together.
One hard limit to respect: up to 5 reference images or 1 reference video per request. Exceeding it tends to cause silent truncation or vague validation errors rather than a clean rejection, so cap your inputs client-side before submitting.
Production Patterns: Webhooks, Rate Limits & Error Handling
Webhooks over polling. At scale, stop polling and append ?webhook=https://you/cb to your submit call. Muapi pushes the terminal result to your endpoint, freeing you from a thousand open polling loops.
Rate limits (HTTP 429). Tight 1-second polling across many jobs is the fastest way to get 429'd. Use exponential backoff (as in the code above) and bounded concurrency — cap in-flight jobs and queue the rest rather than firing everything at once.
The generic "Generation Failed" trap. Don't treat failed as opaque. Inspect the full failed status payload for the granular reason (bad image URL, unsupported combination, content rejection), then implement idempotent retries keyed on your own job ID so a retry never double-charges or double-creates.
The silent-fallback mistake. Always target the exact 2.1 endpoint / model ID. Leaving a 2.0 endpoint in place means you silently keep generating 2.0 output while believing you've upgraded.
Migrating from Seedance 2.0 to 2.1
Planning to go further? Seedance 2.5 adds native 4K, 16-second clips, and advanced audio — worth reading before you architect a long-term pipeline.
A short checklist:
- Swap the endpoint to
seedance-2.1-text-to-video/seedance-2.1-image-to-video. - Keep your prompts — smarter adherence means fewer prompt hacks, not a rewrite.
- Opt into native audio via
generate_audiowhere it adds value. - Confirm ranges —
duration4–12s,resolutionup to 1080p. - Re-test cost — the Mini tier and 1080p change the math.
Everything else — submit, poll, download — stays identical.
FAQ
Is Seedance 2.1 backward compatible with my Seedance 2.0 API integration, or do I need to change my prompt syntax and endpoints?
Your prompt syntax and integration pattern carry over unchanged — 2.1 is a quality upgrade, not an architectural overhaul. The one thing you must change is the endpoint: point to seedance-2.1-text-to-video or seedance-2.1-image-to-video. Leaving the 2.0 endpoint in place silently keeps you on 2.0. Optionally enable generate_audio to use the new native audio.
Does Seedance 2.1 still use the async submit-poll-download pattern, and how long does a generation take?
Yes, identical flow: POST returns a request_id, you poll GET /predictions/{request_id}/result until status is completed (or failed/cancelled), then download the video URL. Expect 30–120 seconds per job, so set timeouts and your polling loop accordingly. For scale, switch to the ?webhook= push delivery instead of polling.
How do I avoid HTTP 429 rate-limit errors when batching many Seedance 2.1 video jobs concurrently?
Replace fixed 1-second polling with exponential backoff (double the delay on each 429, capped around 30s), and bound your concurrency so you only ever have a fixed number of jobs in flight. Better still, use the ?webhook= parameter so Muapi pushes results to you — that removes polling traffic entirely and is the cleanest way to scale.
Related
- Seedance 2.0 Mini API: Prompts, Pricing & Integration Guide — the fastest/cheapest Seedance tier for high-volume workflows
- Seedance 2.5 API: Native 4K, 16s Clips & Advanced Audio — the next step up from 2.1
- Seedance 2.0 vs. Kling 3.0: Which Physics Engine Actually Wins? — how the previous generation compares
- The State of AI Video in 2026 — full landscape comparison including Sora, Kling, and Seedance
- Seedance Evolution: From 1.5 to 2.0 — history of the Seedance model line





