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 consolemodel: the video model name shown in the model marketplace, for examplevolcengine/doubao-seedance-2-0-260128
Basic flow
- Call
POST {{BASE_URL}}/v1/videosto create a video task. - Save the response
idasVIDEO_ID. - Call
GET {{BASE_URL}}/v1/videos/{VIDEO_ID}to check task status. - When the status is
completed, the response includesresult.urlwith the temporary video URL. UseGET {{BASE_URL}}/v1/videos/{VIDEO_ID}/contentto 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 thepromptinstruction./v1/videos/extensions: Extends the source video duration; optionalpromptspecifies continuation content.- Both endpoints use
video.idto 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:
| Status | Meaning |
|---|---|
queued / running / processing | The task is still generating |
completed | The video is complete |
failed | The task failed |
cancelled | The task was cancelled |
expired | The 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.urlis a temporary URL. Use it promptly.result.duration,result.width,result.height,result.formatprovide media metadata (provider-dependent, may be null).expires_atis 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
| Parameter | Type | Description |
|---|---|---|
model | string | Video model name from the console or model marketplace |
prompt | string | Video generation instruction |
seconds | number | Requested video duration |
size | string | Common values: 1280x720, 720x1280, 1920x1080, 1080x1920 |
input_reference | string / object | Image or video reference URL; strings are treated as image URLs |
extra_body.content | array | Provider-native multimodal input for multiple images, video references, and advanced parameters |
extra_body.duration | number | Provider-native duration; takes priority over seconds |
extra_body.ratio | string | Provider-native aspect ratio, such as 16:9 or 9:16 |
extra_body.resolution | string | Provider-native resolution, such as 720p or 1080p |
extra_body.seed | number | Fixed random seed when supported by the provider |
extra_body.watermark | boolean | Watermark control when supported by the provider |
references | array | xAI reference image mode: array of up to 7 image URLs |
video.id | string | Edit/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, andexpiredtasks 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
| Symptom | Check |
|---|---|
401 or 403 | API key validity and target video model permission |
404 | base_url, /v1/videos path, or VIDEO_ID |
400 | size, seconds, input_reference, or extra_body.content format |
| Image or video reference cannot be used | The reference file must be reachable through an HTTPS URL |
| Task takes too long | Query 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 Type | Trigger | Constraints |
|---|---|---|
| Text-to-video | Text only | No special ratio/duration restrictions |
| First frame / First+last frame | content with role=first_frame (optional last_frame) | ratio must be adaptive |
| Reference-to-video | Contains reference_image/reference_video/reference_audio | No special ratio/duration restrictions |
| Video edit | omni_reference_task_type=edit | Must contain reference_video; ratio must be adaptive; duration must be -1; reference video 4–30s |
| Video extend | omni_reference_task_type=extend | Must 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.contentandinput_reference/image/referencesmust not appear together. - Prompt and text merging:
promptis required and must be non-empty. Ifcontent[]already contains a valid text item (type="text"with non-empty non-blank text), all text items are preserved andpromptis 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,
},
)