Skip to main content

Video Models

Video models use Prysm's OpenAI-compatible video endpoint. The endpoint is task-based: a create request returns a video task ID, then you query the task status and download the MP4 after completion.

Start with these three values

  • base_url: {{BASE_URL}}
  • api_key: your Prysm API key from the console
  • model: the video model name shown in the model marketplace, for example volcengine/doubao-seedance-2-0-260128

Basic flow

  1. Call POST {{BASE_URL}}/v1/videos to create a video task.
  2. Save the response id as VIDEO_ID.
  3. Call GET {{BASE_URL}}/v1/videos/{VIDEO_ID} to check task status.
  4. When the status is completed, the response includes result.url with the temporary video URL. Use GET {{BASE_URL}}/v1/videos/{VIDEO_ID}/content to get a 307 redirect to the upstream video URL (no gateway bandwidth consumed).

Clients can poll task status. If a client stops polling, the backend still continues task status handling and completion billing. To show or download the result, the client still needs to query status or content with VIDEO_ID.

Text to video

curl -sS -X POST "{{BASE_URL}}/v1/videos" \
-H "Authorization: Bearer YOUR_PRYSM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "volcengine/doubao-seedance-2-0-260128",
"prompt": "A small paper boat floating on a calm blue pond, soft morning light, cinematic camera movement, no text, no subtitles.",
"seconds": 5,
"size": "1280x720"
}'

xAI Grok video model example:

curl -sS -X POST "{{BASE_URL}}/v1/videos" \
-H "Authorization: Bearer YOUR_PRYSM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-video",
"prompt": "A small paper boat floating on a calm blue pond, cinematic lighting, no text.",
"seconds": 5,
"size": "1280x720"
}'

Image to video

For one image reference, use input_reference with a publicly reachable HTTPS image URL.

curl -sS -X POST "{{BASE_URL}}/v1/videos" \
-H "Authorization: Bearer YOUR_PRYSM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "volcengine/doubao-seedance-2-0-260128",
"prompt": "Animate the product image with a slow commercial camera push-in, clean highlights, no text, no subtitles.",
"input_reference": "https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic1.jpg",
"seconds": 5,
"size": "1280x720"
}'

For multiple images or provider-native multimodal content, use extra_body.content:

{
"model": "volcengine/doubao-seedance-2-0-260128",
"prompt": "Animate this reference image.",
"seconds": 5,
"size": "1280x720",
"extra_body": {
"content": [
{"type": "text", "text": "Animate this reference image."},
{"type": "image_url", "image_url": {"url": "https://example.com/product.png"}}
]
}
}

Video to video

Video reference input can also use input_reference. Host the video file first and pass a reachable HTTPS URL.

curl -sS -X POST "{{BASE_URL}}/v1/videos" \
-H "Authorization: Bearer YOUR_PRYSM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "volcengine/doubao-seedance-2-0-260128",
"prompt": "Keep the same subject and lighting, extend the motion with a smooth cinematic camera move, no text, no subtitles.",
"input_reference": {
"type": "video_url",
"video_url": {
"url": "https://example.com/input.mp4"
}
},
"seconds": 5,
"size": "1280x720"
}'

For multiple references or more provider-native parameters, use extra_body.content:

{
"model": "volcengine/doubao-seedance-2-0-260128",
"prompt": "Create a new shot using the motion and style of the reference video.",
"seconds": 5,
"size": "1280x720",
"extra_body": {
"content": [
{"type": "text", "text": "Create a new shot using the motion and style of the reference video."},
{"type": "video_url", "video_url": {"url": "https://example.com/input.mp4"}}
]
}
}

Video editing and extension

Prysm provides /v1/videos/edits and /v1/videos/extensions endpoints for editing existing videos and extending video duration.

Video editing (xAI Grok example):

curl -sS -X POST "{{BASE_URL}}/v1/videos/edits" \
-H "Authorization: Bearer YOUR_PRYSM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-video",
"video": {
"id": "cgt-xxx"
},
"prompt": "Change the background to a sunset beach scene.",
"seconds": 5,
"size": "1280x720"
}'

Video extension (xAI Grok example):

curl -sS -X POST "{{BASE_URL}}/v1/videos/extensions" \
-H "Authorization: Bearer YOUR_PRYSM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-video",
"video": {
"id": "cgt-xxx"
},
"seconds": 5,
"size": "1280x720"
}'
  • /v1/videos/edits: Edits the source video according to the prompt instruction.
  • /v1/videos/extensions: Extends the source video duration; optional prompt specifies continuation content.
  • Both endpoints use video.id to specify the source video task ID and return a new video task ID.

Query status

curl -sS \
-H "Authorization: Bearer YOUR_PRYSM_API_KEY" \
"{{BASE_URL}}/v1/videos/VIDEO_ID"

Common statuses:

StatusMeaning
queued / running / processingThe task is still generating
completedThe video is complete
failedThe task failed
cancelledThe task was cancelled
expiredThe task expired

When the task reaches completed, the response includes a result object:

{
"id": "cgt-xxx",
"status": "completed",
"result": {
"url": "https://media.x.ai/.../video.mp4",
"duration": 5.0,
"width": 1280,
"height": 720,
"format": "mp4"
},
"expires_at": "2026-07-30T12:00:00Z"
}
  • result.url is a temporary URL. Use it promptly.
  • result.duration, result.width, result.height, result.format provide media metadata (provider-dependent, may be null).
  • expires_at is present only when the upstream provides an accurate expiry time.

Download video

# 307 redirect to the upstream video URL (no gateway bandwidth consumed)
curl -L -H "Authorization: Bearer YOUR_PRYSM_API_KEY" \
"{{BASE_URL}}/v1/videos/VIDEO_ID/content" \
--output video.mp4

The --location (-L) flag is required for curl to follow the 307 redirect. The Prysm gateway does not download or proxy video bytes — it redirects clients directly to the upstream media server.

Common parameters

ParameterTypeDescription
modelstringVideo model name from the console or model marketplace
promptstringVideo generation instruction
secondsnumberRequested video duration
sizestringCommon values: 1280x720, 720x1280, 1920x1080, 1080x1920
input_referencestring / objectImage or video reference URL; strings are treated as image URLs
extra_body.contentarrayProvider-native multimodal input for multiple images, video references, and advanced parameters
extra_body.durationnumberProvider-native duration; takes priority over seconds
extra_body.ratiostringProvider-native aspect ratio, such as 16:9 or 9:16
extra_body.resolutionstringProvider-native resolution, such as 720p or 1080p
extra_body.seednumberFixed random seed when supported by the provider
extra_body.watermarkbooleanWatermark control when supported by the provider
referencesarrayxAI reference image mode: array of up to 7 image URLs
video.idstringEdit/extension mode: source video task ID

Billing

  • Video tasks are billed after the provider confirms completed.
  • Task creation, status queries, and content downloads are lifecycle operations.
  • Repeated queries for the same completed task only bill the completed result once.
  • failed, cancelled, and expired tasks are not billed as completed videos.
  • Image input, video input, resolution, and duration can produce different costs. Use usage records and billing ledger entries as the source of truth.

Troubleshooting

SymptomCheck
401 or 403API key validity and target video model permission
404base_url, /v1/videos path, or VIDEO_ID
400size, seconds, input_reference, or extra_body.content format
Image or video reference cannot be usedThe reference file must be reachable through an HTTPS URL
Task takes too longQuery task status and capture request time, model name, and VIDEO_ID from logs

Seedance 2.5

Model ID: volcengine/doubao-seedance-2-5-260628 (doubao-seedance-2-5-260628).

Task Types

Seedance 2.5 supports five task types through the POST /v1/videos endpoint:

Task TypeTriggerConstraints
Text-to-videoText onlyNo special ratio/duration restrictions
First frame / First+last framecontent with role=first_frame (optional last_frame)ratio must be adaptive
Reference-to-videoContains reference_image/reference_video/reference_audioNo special ratio/duration restrictions
Video editomni_reference_task_type=editMust contain reference_video; ratio must be adaptive; duration must be -1; reference video 4–30s
Video extendomni_reference_task_type=extendMust contain reference_video; ratio must be adaptive; duration must be -1 or 4–30

Default is valid: the official defaults are ratio=adaptive and duration=-1. The adapter does not infer task type — reference_video alone cannot distinguish reference, edit, or extend.

Native extra_body.content Usage

extra_body.content is supported for all Volcengine Seedance models (2.0 and 2.5).

  • Mutual exclusion: extra_body.content and input_reference/image/references must not appear together.
  • Prompt and text merging: prompt is required and must be non-empty. If content[] already contains a valid text item (type="text" with non-empty non-blank text), all text items are preserved and prompt is ignored. Otherwise, empty text items are removed and {"type":"text","text":prompt} is inserted at the beginning of the array.

extra_body Pass-Through Parameters

The following parameters pass through directly to Ark via extra_body:

omni_reference_task_type, output_format (mp4/mov), generate_audio, camera_fixed, draft, frames, service_tier, tools, safety_identifier, execution_expires_after.

Resolution Limits

Seedance 2.5 only supports 480p and 720p. Passing 1080p or 4k is rejected by local validation. Restricted tasks (edit, extend, first/last frame) reject size — use extra_body={"ratio":"adaptive","resolution":"720p"} instead.

Asset Limits

Up to 30 images + 10 videos + 10 audio assets (50 total). Total audio/video duration: 30 seconds.

Output Format MOV

Pass "output_format": "mov" in extra_body. The proxy redirects to the upstream pre-signed URL — MOV files are served directly by Ark. Check your player's MOV compatibility.

48-Hour Local Timeout

execution_expires_after in extra_body is passed through to Ark. The local execution_expires_at is capped at 172800 seconds (48 hours). When the local timeout is reached, the task is set to expired/free — an irreversible terminal state. No further upstream requests are made, and a late upstream succeeded does not change the state or charge.

Examples

Text-to-video:

from litellm import video_generation

response = video_generation(
model="volcengine/doubao-seedance-2-5-260628",
prompt="A paper boat floating on a calm blue pond, soft morning light, cinematic camera movement, no text, no subtitles.",
)

First frame + last frame:

response = video_generation(
model="volcengine/doubao-seedance-2-5-260628",
prompt="Add motion to this scene, smooth camera pan, no text, no subtitles.",
extra_body={
"content": [
{"type": "text", "text": "Add motion to this scene, smooth camera pan, no text, no subtitles."},
{"type": "image_url", "image_url": {"url": "https://example.com/first_frame.png"}, "role": "first_frame"},
{"type": "image_url", "image_url": {"url": "https://example.com/last_frame.png"}, "role": "last_frame"},
],
"ratio": "adaptive",
},
)

Reference-to-video (with image, video, and audio):

response = video_generation(
model="volcengine/doubao-seedance-2-5-260628",
prompt="Create a cinematic scene combining the reference elements, no text, no subtitles.",
extra_body={
"content": [
{"type": "text", "text": "Create a cinematic scene combining the reference elements, no text, no subtitles."},
{"type": "image_url", "image_url": {"url": "https://example.com/ref.png"}, "role": "reference_image"},
{"type": "video_url", "video_url": {"url": "https://example.com/ref.mp4"}, "role": "reference_video"},
{"type": "audio_url", "audio_url": {"url": "https://example.com/ref.mp3"}, "role": "reference_audio"},
],
},
)

Video edit:

response = video_generation(
model="volcengine/doubao-seedance-2-5-260628",
prompt="Change the background to a sunset beach scene, keep the subject, no text, no subtitles.",
extra_body={
"content": [
{"type": "text", "text": "Change the background to a sunset beach scene, keep the subject, no text, no subtitles."},
{"type": "video_url", "video_url": {"url": "https://example.com/input.mp4"}, "role": "reference_video"},
],
"omni_reference_task_type": "edit",
"ratio": "adaptive",
"duration": -1,
"output_format": "mov",
},
)

Video extend:

response = video_generation(
model="volcengine/doubao-seedance-2-5-260628",
prompt="Continue the motion with the same style, smooth cinematic camera move, no text, no subtitles.",
extra_body={
"content": [
{"type": "text", "text": "Continue the motion with the same style, smooth cinematic camera move, no text, no subtitles."},
{"type": "video_url", "video_url": {"url": "https://example.com/input.mp4"}, "role": "reference_video"},
],
"omni_reference_task_type": "extend",
"ratio": "adaptive",
"duration": 5,
},
)