Seedance 2.5 at BytePlus’s price
Generate clips with Seedance 2.5 (dreamina-seedance-2-5-260628) through your Ghostmotion workspace. It is BytePlus ModelArk’s own task API, with the same request body and task shape, so a BytePlus client changes only two things.
https://app.ghostmotion.ai/api/v1/seedanceAnd its key: send a Ghostmotion API key as Authorization: Bearer. The same keys, workspace credits and spending limits apply as for the video API. The Seedance API is available where your workspace has it; Integrations shows it when it does.
Price
Exactly BytePlus’s: its list price per million output tokens for the clip’s resolution (lower when a video is among the inputs), times the tokens the clip used, at one credit per US dollar. A 6-second 1080p clip that used 293,625 tokens costs 3.435413 credits. When BytePlus can’t make a task, the same task is made by another provider and still costs what BytePlus would have charged. A clip that isn’t made costs nothing.
1. Create a task
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/seedance/contents/generations/tasks" \
-H "Authorization: Bearer $GHOSTMOTION_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dreamina-seedance-2-5-260628",
"content": [
{
"type": "text",
"text": "A red kite over a beach at dusk, slow push-in"
},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/first-frame.jpg"
},
"role": "first_frame"
}
],
"resolution": "1080p",
"duration": 6,
"request_id": "kite-001"
}'The body is BytePlus’s: content holds one text item and any images (first_frame, last_frame or reference_image), reference videos and audio, as public https URLs. Set resolution (480p, 720p, 1080p), ratio and duration (4–30 seconds, or -1 for automatic). Fields BytePlus has but this API does not take, such as callback_url, are refused by name. Add request_id to retry without starting a second task.
2. Check it until it ends
export TASK_ID='ID_FROM_RESPONSE'
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/seedance/contents/generations/tasks/$TASK_ID" \
-H "Authorization: Bearer $GHOSTMOTION_API_KEY"Wait poll_after_seconds between checks. At succeeded, content.video_url is a link valid for one hour (read the task again for a fresh one), usage.completion_tokens is what the clip used, and credits.charged what it cost. A failed task’s error says why; it was not charged.
Through MCP
Where your workspace has the Seedance API, MCP clients also get create_seedance_task and get_seedance_task, with the same inputs and results.
Reference
Create a Seedance video
POST /api/v1/seedance/contents/generations/tasks
Generate a clip with Seedance 2.5 (dreamina-seedance-2-5-260628), in BytePlus ModelArk's own request shape. Returns the task id at once; poll get_seedance_task until it succeeds or fails. Costs exactly BytePlus's price, one credit per US dollar.
Required permission: videos:write
A BytePlus client only changes its base URL to {origin}/api/v1/seedance and its key. The price is BytePlus's list price for the tokens the clip used; when BytePlus can't make a task, the same task is made by another provider at the same price. Nothing made, nothing charged. The most a task could cost is held while it runs. Reuse request_id and the same body to retry without a second task.
Request body
request_idstring · optionalOptional retry identity: the same id and body returns the same task. Not part of BytePlus's API.
at least 1 character; up to 128 characters
modelstring · requiredThe model.
dreamina-seedance-2-5-260628
contentarray · requiredOne text item with the prompt, then any media items: up to 30 images, 10 videos and 10 audio clips.
content[].typestring · requiredWhat this item is.
text · image_url · video_url · audio_url
content[].textstring · optionalThe prompt, on the text item.
up to 5,000 characters
content[].image_urlobject · optionalcontent[].image_url.urlstring · requiredPublic https URL of the image. The model provider fetches it.
up to 2,048 characters
content[].video_urlobject · optionalcontent[].video_url.urlstring · requiredPublic https URL of the video (MP4 or MOV). The model provider fetches it.
up to 2,048 characters
content[].audio_urlobject · optionalcontent[].audio_url.urlstring · requiredPublic https URL of the audio. The model provider fetches it.
up to 2,048 characters
content[].rolestring · optionalAn image's role: first_frame (optionally with last_frame) makes those exact frames; reference_image guides a new shot. Videos are reference_video and audio reference_audio. A lone image without a role is the first frame.
first_frame · last_frame · reference_image · reference_video · reference_audio
ratiostring · optionalFrame shape. Defaults to 16:9, or adaptive (the input's shape) with a first frame or an edit or extension.
21:9 · 16:9 · 4:3 · 1:1 · 3:4 · 9:16 · adaptive
durationinteger · optionalLength in whole seconds, 4 to 30, or -1 for automatic. Defaults to 5 (automatic for an edit or extension).
minimum -1; maximum 30
resolutionstring · optionalOutput resolution. Defaults to 720p.
480p · 720p · 1080p
generate_audioboolean · optionalGenerate sound with the clip. Defaults to true.
watermarkboolean · optionalAdd a watermark. Defaults to false.
seedinteger · optionalSeed for repeatable results; -1 for random.
minimum -1; maximum 4294967295
omni_reference_task_typestring · optionalWith reference media: reference makes a new shot guided by them, edit changes the given video in place, extend continues it. Without it the model decides from the prompt.
reference · edit · extend
Example request
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/seedance/contents/generations/tasks" \
-H "Authorization: Bearer $GHOSTMOTION_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dreamina-seedance-2-5-260628",
"content": [
{
"type": "text",
"text": "A red kite over a beach at dusk, slow push-in"
},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/first-frame.jpg"
},
"role": "first_frame"
}
],
"resolution": "1080p",
"duration": 6,
"request_id": "kite-001"
}'Response · 200
{
"id": "0190e2c4-1b2c-4d3e-8f40-123456789abc",
"model": "dreamina-seedance-2-5-260628",
"status": "queued",
"created_at": 1793361600,
"updated_at": 1793361600,
"resolution": "1080p",
"ratio": "adaptive",
"duration": 6,
"framespersecond": 24,
"generate_audio": true,
"credits": {
"price": null,
"charged": null,
"reserved": 4.89
},
"poll_after_seconds": 10
}All response fields
idstring · requiredThe id returned when the task was created.
at least 1 character
modelstring · requiredThe model.
statusstring · requiredqueued, running, then succeeded or failed.
queued · running · succeeded · failed
contentobject · optionalcontent.video_urlstring · requiredAbsolute URL.
content.video_url_expires_atstring · requiredISO 8601 UTC timestamp.
usageobject · optionalusage.completion_tokensnumber · requiredOutput tokens the clip used: what its price is counted in.
usage.total_tokensnumber · requiredThe same count, as BytePlus reports it.
errorobject · optionalerror.codestring · requiredStable failure code.
error.messagestring · requiredWhy it failed; a failed task is not charged.
created_atnumber · requiredUnix seconds.
updated_atnumber · requiredUnix seconds.
seednumber · optionalThe seed asked for.
resolutionstring · requiredOutput resolution.
ratiostring · requiredFrame shape.
durationnumber · requiredLength asked for, or -1 for automatic.
framespersecondnumber · optionalFrames per second.
generate_audioboolean · optionalWhether sound was asked for.
creditsobject · requiredcredits.pricenumber | null · requiredBytePlus's price for the clip, in credits (one per USD); null until it succeeds.
credits.chargednumber | null · requiredCredits charged; null until the task ends.
credits.reservednumber · requiredCredits held while the task runs.
poll_after_secondsnumber · optionalPresent while queued or running: wait this long before checking again.
Errors
unauthorized, permission_denied, not_found, invalid_request, insufficient_credits, allowance_exhausted, cap_too_low, idempotency_conflict, rate_limited, internal_error, temporarily_unavailable.
Check a Seedance video
GET /api/v1/seedance/contents/generations/tasks/{task_id}
Get a Seedance task in BytePlus's task shape: its status, and when it succeeded the clip's link, the tokens it used and its price in credits. While queued or running, wait poll_after_seconds before checking again.
Required permission: projects:read
Terminal states are succeeded and failed; a failed task's error says why, and it was not charged. content.video_url is a Ghostmotion link that expires after one hour: read the task again for a fresh one. It follows a redirect to temporary storage and needs no bearer header.
Path parameters
task_idstring · requiredThe id returned when the task was created.
at least 1 character
Query parameters
No query parameters required.
Example request
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/seedance/contents/generations/tasks/$TASK_ID" \
-H "Authorization: Bearer $GHOSTMOTION_API_KEY"Response · 200
{
"id": "0190e2c4-1b2c-4d3e-8f40-123456789abc",
"model": "dreamina-seedance-2-5-260628",
"status": "succeeded",
"created_at": 1793361600,
"updated_at": 1793361600,
"resolution": "1080p",
"ratio": "adaptive",
"duration": 6,
"framespersecond": 24,
"generate_audio": true,
"credits": {
"price": 3.435413,
"charged": 3.435413,
"reserved": 0
},
"content": {
"video_url": "https://app.ghostmotion.ai/api/v1/media/example-token",
"video_url_expires_at": "2026-11-01T13:02:00.000Z"
},
"usage": {
"completion_tokens": 293625,
"total_tokens": 293625
}
}All response fields
idstring · requiredThe id returned when the task was created.
at least 1 character
modelstring · requiredThe model.
statusstring · requiredqueued, running, then succeeded or failed.
queued · running · succeeded · failed
contentobject · optionalcontent.video_urlstring · requiredAbsolute URL.
content.video_url_expires_atstring · requiredISO 8601 UTC timestamp.
usageobject · optionalusage.completion_tokensnumber · requiredOutput tokens the clip used: what its price is counted in.
usage.total_tokensnumber · requiredThe same count, as BytePlus reports it.
errorobject · optionalerror.codestring · requiredStable failure code.
error.messagestring · requiredWhy it failed; a failed task is not charged.
created_atnumber · requiredUnix seconds.
updated_atnumber · requiredUnix seconds.
seednumber · optionalThe seed asked for.
resolutionstring · requiredOutput resolution.
ratiostring · requiredFrame shape.
durationnumber · requiredLength asked for, or -1 for automatic.
framespersecondnumber · optionalFrames per second.
generate_audioboolean · optionalWhether sound was asked for.
creditsobject · requiredcredits.pricenumber | null · requiredBytePlus's price for the clip, in credits (one per USD); null until it succeeds.
credits.chargednumber | null · requiredCredits charged; null until the task ends.
credits.reservednumber · requiredCredits held while the task runs.
poll_after_secondsnumber · optionalPresent while queued or running: wait this long before checking again.
Errors
unauthorized, permission_denied, not_found, rate_limited, internal_error, temporarily_unavailable.