Sora 2 Pro Image to Video API
openai/sora-2-pro/image-to-videoSora 2 Pro (Image to Video) animates high-fidelity static reference images into cinematic videos up to 1080p Full HD, supporting auto aspect ratio matching, resolution options from 720p to 1080p, and native synchronized acoustics. It locks subject identity, intricate surface textures, and nuanced illumination while producing smooth three-dimensional camera trajectories and believable physical dynamics.
openai/sora-2-pro/image-to-video
Choose another model to keep creating

Seedance 2.5
ByteDance Seed's Seedance 2.5 video model with separate text-to-video, start/end-frame image-to-video, and multimodal reference-to-video API workflows at 480p, 720p, or 1080p for 4 to 30 seconds.
From
$0.140
per output second

MiniMax H3
MiniMax H3 on Vidgo API with separate text-to-video, start/end-frame image-to-video, and multimodal reference-to-video workflows at fixed 2K output.
From
$0.105
per second

Seedance 2.0
ByteDance Seedance 2.0 Standard and Fast video generation with text, ordered start/end frames, or multimodal image, video, and audio references.
From
$0.100
per output second

Hailuo 2.3
MiniMax's Hailuo 2.3 video model for realistic human motion, expressive characters, and text-to-video or first-frame guided generation at 768p and 1080p.
From
$0.175
per video

Kling 3.0
Kuaishou's most advanced video model with native 4K/60fps output, multi-shot storyboarding, multilingual audio, and character consistency for up to 3 people.
From
$0.135
per second
Discontinued: this model no longer accepts generation requests. The API documentation below is retained for reference only.
REST API
Quick Start
Authenticate, pass reference image and motion prompt, then retrieve 1080p animated video.
Step 1: Set up authentication
Include Authorization: Bearer VIDGO_API_KEY in all HTTP request headers.
- Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Authentication
- Authorization: Bearer VIDGO_API_KEY
Step 2: Submit image-to-video task
Send POST request to /api/generate/submit with model openai/sora-2-pro/image-to-video, prompt, image_urls, and auto aspect ratio.
REQUEST_BODY=$(cat <<'JSON'
{
"model": "openai/sora-2-pro/image-to-video",
"input": {
"prompt": "The young woman on the balcony turns her head slowly toward the camera and smiles softly, long hair flowing in the golden sunset breeze, cinematic warm light. Natural sound: gentle wind, soft distant ambience, a quiet breath. Realistic motion, no text, no logos.",
"duration": 4,
"resolution": "1080p",
"aspect_ratio": "auto",
"image_urls": [
"https://cdn.vidgo.ai/apis/models/openai/sora-2-pro/image-to-video/v1/01/input.png"
]
}
}
JSON
)
RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
CODE=$(printf '%s' "$RESPONSE" | jq -r '.code // empty')
if [ "$CODE" != "0" ] && [ "$CODE" != "200" ]; then
printf 'API error: %s
' "$RESPONSE" >&2
exit 1
fi
printf '%s
' "$RESPONSE"Step 3: Poll for video result
Poll with task_id while status is not_started or running, and stop at finished or failed. On success, read data.files[].file_url; on failure, read data.error_message.
Track status
GET https://api.vidgo.ai/api/generate/status/{task_id}Poll with task_id while status is not_started or running, and stop at finished or failed. On success, read data.files[].file_url; on failure, read data.error_message.
not_startedrunningfinishedfailed{
"code": 200,
"data": {
"task_id": "task-sora2-pro-i2v-781923",
"status": "running",
"created_time": "2026-09-17T10:00:00Z"
}
}{
"code": 200,
"data": {
"task_id": "task-unified-...",
"status": "finished",
"files": [
{
"file_url": "https://storage.vidgo.ai/generated/video.mp4",
"file_type": "video"
}
],
"created_time": "2026-08-22T10:00:00Z",
"progress": 100,
"error_message": null
}
}Complete script example
Expand for a complete script with HTTP and business-code checks, task_id validation, polling, terminal-state handling, and a 600-second polling timeout.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "openai/sora-2-pro/image-to-video",
"input": {
"prompt": "The young woman on the balcony turns her head slowly toward the camera and smiles softly, long hair flowing in the golden sunset breeze, cinematic warm light. Natural sound: gentle wind, soft distant ambience, a quiet breath. Realistic motion, no text, no logos.",
"duration": 4,
"resolution": "1080p",
"aspect_ratio": "auto",
"image_urls": [
"https://cdn.vidgo.ai/apis/models/openai/sora-2-pro/image-to-video/v1/01/input.png"
]
}
}
JSON
)
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
TASK_ID=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.data.task_id // .task_id // empty')
BUSINESS_CODE=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Submit failed:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
if [ -z "$TASK_ID" ]; then
printf 'Submit response did not include task_id:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
START_TIME=$(date +%s)
POLL_DELAY=2
while true; do
if [ $(( $(date +%s) - START_TIME )) -ge 600 ]; then
printf 'Timed out after 600 seconds
' >&2
exit 1
fi
STATUS_RESPONSE=$(curl --silent --show-error --fail-with-body \
--url "https://api.vidgo.ai/api/generate/status/$TASK_ID" \
--header "Authorization: Bearer $VIDGO_API_KEY")
STATUS=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.data.status // .status // empty')
BUSINESS_CODE=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Status request failed:
%s
' "$STATUS_RESPONSE" >&2
exit 1
fi
case "$STATUS" in
finished)
printf '%s' "$STATUS_RESPONSE" | jq -r '(.data.files // .files // [])[]?.file_url'
break
;;
failed)
printf '%s' "$STATUS_RESPONSE" | jq -r '.data.error_message // .error_message // "Generation failed"' >&2
exit 1
;;
not_started|running)
sleep "$POLL_DELAY"
if [ "$POLL_DELAY" -lt 10 ]; then POLL_DELAY=$((POLL_DELAY + 1)); fi
;;
*)
printf 'Unexpected task status: %s
' "$STATUS" >&2
exit 1
;;
esac
doneInput parameters
Parameters passed within the input object to /api/generate/submit:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| prompt | string | Yes | — | Action and camera motion prompt, at least 1 character. |
| image_urls | array | Yes | — | Array containing exactly one public image URL. Supported formats: JPEG, PNG, WebP (≤10MB). |
| duration | integer | No | 4 | 4, 8, 12, 16, or 20, in seconds. |
| aspect_ratio | string | No | 16:9 | auto, 16:9, or 9:16. auto is supported when image_urls is present. |
| resolution | string | No | 1024p | 720p, 1024p, or 1080p. |
Response Fields
Task creation payload and query status response details:
| Field | Type | Description |
|---|---|---|
| code | integer | Application result code; successful responses return 200. |
| message | string | Human-readable status or error message. |
| data.task_id | string | Unique asynchronous task identifier. |
| data.status | string | Current lifecycle: not_started, running, finished, or failed. |
| data.created_time | string | Task creation timestamp in ISO 8601 format. |
| data.files[] | array | Output files generated upon completion. |
| data.files[].file_url | string | Public URL for downloading or playing the generated video. |
| data.error_message | string | null | Detailed error explanation when task status is failed. |
Task Lifecycle
Poll status until reaching finished or failed:
not_startedTask accepted and waiting in compute dispatch queue.
runningDiffusion model is animating reference image frames in 1080p and synthesizing audio.
finishedGeneration completed; read video URL from data.files[0].file_url.
failedTask stopped due to invalid image or safety filter; inspect data.error_message.
Polling and Errors
- AuthenticationVerify Bearer API key in request header if 401 is received.
- Image & Resolution validationEnsure image_urls contains 1 valid URL and resolution is within 720p/1024p/1080p on 400 response.
- Polling intervalPoll with a 2-second base interval, extending gradually for longer jobs.
- Webhook callbackProvide callback_url at request top level to receive asynchronous POST notifications.
Endpoint limits
| Specification | Value | Details |
|---|---|---|
| Input mode | Text + One Image | A prompt guides motion, and image_urls provides exactly one required reference image. |
| Output | MP4 video with native audio | Asynchronous video generation with downloadable MP4 URL upon completion. |
| Duration | 4 / 8 / 12 / 16 / 20 seconds | Default is 4 seconds. |
| Aspect ratio | auto / 16:9 / 9:16 | Default is 16:9; auto inherits input image aspect ratio. |
| Resolution | 720p / 1024p / 1080p | Default is 1024p, supporting up to 1080p Full HD. |
| Image requirements | JPEG / PNG / WebP, ≤ 10MB | Must provide exactly one publicly accessible URL. |
| Billing basis | Per second × resolution rate | 720p: 48 credits/s; 1024p: 80 credits/s; 1080p: 112 credits/s. |
Related Models
Sora 2 Pro Image to Video API frequently asked questions
What is the Sora 2 Pro Image to Video API?
Sora 2 Pro Image to Video is OpenAI's flagship model for image-to-video generation. It uses a single reference image as a visual anchor, animating camera paths and subject movements according to text instructions into cinematic videos up to 1080p Full HD with native synchronized stereo audio. Built on OpenAI's most capable multimodal diffusion architecture, it preserves subject identity, micro-textures, and spatial lighting while generating smooth 3D motion dynamics. You can call it programmatically or try it from the playground above.
How do I use auto aspect ratio in Sora 2 Pro Image to Video?
Set aspect_ratio to "auto" in your request payload. The model automatically detects and matches the pixel aspect ratio of your uploaded reference image, using those proportions to guide the generated composition.
What resolutions are supported by Sora 2 Pro Image to Video?
The endpoint supports 720p, 1024p, and 1080p resolutions (the playground defaults to 1024p). The 1080p mode is tailored for high-end commercial delivery, fully resolving skin pores, fine fabric textures, and subtle reflections.
Does Sora 2 Pro Image to Video maintain character facial consistency?
Yes. Sora 2 Pro features advanced facial landmark extraction and 3D spatial projection. When you provide a well-lit, unobstructed reference portrait and focus text prompts on actions, the model preserves facial likeness consistently across turns, smiles, and head movements.
Can Sora 2 Pro Image to Video generate ambient audio for still images?
Yes. The model employs joint audiovisual reasoning, identifying scene elements in the keyframe (such as fireplaces, oceans, forests, or vehicles) and automatically synthesizing realistic synchronized stereo background audio and motion foley without external audio tools.
How many reference images does Sora 2 Pro Image to Video accept?
The endpoint accepts exactly 1 reference image passed in the image_urls array. The image functions as the initial start frame, and submitting arrays with more than 1 image will return a validation error.
What clip durations does Sora 2 Pro Image to Video offer?
A single call supports generating clips up to 20 seconds, with exact duration options of 4, 8, 12, 16, or 20 seconds (the playground defaults to 4 seconds). Fixed durations allow teams to calculate exact credit expenditures before submitting jobs.















