Animate the supplied chameleon photo as a natural-history macro shot. Preserve its exact striped skin, horns-free head, curled tail, branch and dry rocky terrarium. The visible turret eye slowly rotates toward the camera while the nearest forefoot opens its two opposing toe groups and reaches a short distance forward onto the same branch. End after the foot grips securely. Very subtle breathing. Fixed camera, no color transformation, no tongue strike, no new limbs. No text, logos or watermarks.
Kling O3 Pro Image to Video API
kwaivgi/kling-video-o3-pro/image-to-videoGenerate 3–15-second videos with Kling O3 Pro from a starting image and an optional ending frame. Supports single-shot and multi-shot generation. Explicitly set sound; multi-shot requires audio.
Multi-shot requires sound. The form sets duration to the shot total.
Duration: 5 s (3-15)
![Image Urls[0]](https://cdn.vidgo.ai/apis/models/kwaivgi/kling-video-o3-pro/image-to-video/v1/01/input-start.png)
Examples
REST API Reference
Quick Start
Submit a task and query its status.
Step 1: Set up authentication
Create an API key in the dashboard and attach Authorization: Bearer <API_KEY> when submitting a task.
- Submit Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Authorization Header
- Authorization: Bearer VIDGO_API_KEY
Step 2: Submit a task
POST /api/generate/submit: kwaivgi/kling-video-o3-pro/image-to-video
REQUEST_BODY=$(cat <<'JSON'
{
"model": "kwaivgi/kling-video-o3-pro/image-to-video",
"input": {
"duration": 5,
"sound": true,
"multi_shots": true,
"multi_prompt": [
{
"prompt": "Begin with the supplied photograph. Preserve the female geologist, white helmet, charcoal jacket with teal collar, orange instrument and safety railing. Medium-wide view: she watches a distant lava fountain beyond the secured platform. Warm lava light touches her jacket; wind moves a loose hair strand. Restrained documentary realism, safe distance. Audio: quiet wind and low distant rumble. No text, logos or watermarks.",
"duration": 2
},
{
"prompt": "Cut to a closer three-quarter view of the same geologist on the same platform. Preserve her face, white helmet, teal collar and orange instrument. She lowers her gaze from the volcano to the instrument and makes one small thumb adjustment. Maintain warm lava reflections against cool twilight. Finish looking down. Low distant rumble and glove movement; no speech, alarm or music. No text, logos or watermarks.",
"duration": 3
}
],
"image_urls": [
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-video-o3-pro/image-to-video/v1/01/input-start.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 completion
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.
Status Endpoint
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-submitted-example",
"status": "not_started",
"created_time": "2026-09-22T00:00:00Z"
}
}{
"code": 200,
"data": {
"task_id": "WTSYQAI2J76PVHFW",
"status": "finished",
"files": [
{
"file_type": "video",
"file_url": "https://cdn.vidgo.ai/apis/models/kwaivgi/kling-video-o3-pro/image-to-video/v1/01/output.mp4"
}
],
"created_time": "2026-09-22T18:46:21",
"error_message": null,
"progress": 100
}
}Complete executable script
Expand to review an end-to-end script with automatic polling, error handling, and timeout safeguards.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "kwaivgi/kling-video-o3-pro/image-to-video",
"input": {
"duration": 5,
"sound": true,
"multi_shots": true,
"multi_prompt": [
{
"prompt": "Begin with the supplied photograph. Preserve the female geologist, white helmet, charcoal jacket with teal collar, orange instrument and safety railing. Medium-wide view: she watches a distant lava fountain beyond the secured platform. Warm lava light touches her jacket; wind moves a loose hair strand. Restrained documentary realism, safe distance. Audio: quiet wind and low distant rumble. No text, logos or watermarks.",
"duration": 2
},
{
"prompt": "Cut to a closer three-quarter view of the same geologist on the same platform. Preserve her face, white helmet, teal collar and orange instrument. She lowers her gaze from the volcano to the instrument and makes one small thumb adjustment. Maintain warm lava reflections against cool twilight. Finish looking down. Low distant rumble and glove movement; no speech, alarm or music. No text, logos or watermarks.",
"duration": 3
}
],
"image_urls": [
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-video-o3-pro/image-to-video/v1/01/input-start.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
doneRequest Parameters (input object)
Put generation parameters inside input. Use standard JSON numbers and booleans. For compatibility, integer strings such as "5" are accepted. Boolean strings true/1/yes/y/on mean true; false/0/no/n/off mean false. These strings are case-insensitive and trimmed. Numeric 1 and 0 are also accepted for boolean fields. Numeric and boolean prompt values are converted to text; 0, false and null are treated as empty. Objects and arrays are not accepted as prompts. The API validates prompts up to 2,500 characters. Some multi-shot generation requests have failed when a shot prompt exceeded 512 characters. We recommend keeping each shot prompt within 512 characters; this recommendation does not change the API validation limit.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| prompt | string | Conditional | - | Required when multi_shots=false. Describe the scene, action and camera movement. Use nonblank text, up to 2,500 characters after trimming. Omit prompt when multi_shots=true. |
| multi_shots | boolean | Yes | - | Required: explicitly send false for a single shot or true for multiple shots. Single-shot mode requires prompt. Multi-shot mode requires multi_prompt and sound=true, with no nonblank top-level prompt. Omitting this field is an error. |
| multi_prompt | array | Conditional | - | Required when multi_shots=true; omit in single-shot mode. Supply at least one shot, each with a nonblank prompt of up to 2,500 characters and an integer duration of 1–12 seconds. Shot durations must sum to the top-level duration (3–15 seconds). Extra fields inside a shot are ignored. |
| duration | integer | Yes | - | Required integer from 3 to 15 seconds. In multi-shot mode, this must equal the sum of all shot durations. Credits are calculated using this value. |
| sound | boolean | Yes | - | Required: explicitly send true to generate audio or false for video without audio. Single-shot mode accepts either value; multi-shot mode requires true. |
| aspect_ratio | string | No | - | May be omitted. If provided, use 16:9, 9:16 or 1:1. Image-to-video ignores this value; framing is determined by the input image. |
| image_urls | array | Yes | - | Required: an array of 1–2 images. The first is the starting frame; the optional second is the ending frame. Accepts public HTTP(S) URLs, image Data URIs or raw Base64 image data. |
Response Fields (Status Query)
Details returned by GET /api/generate/status/{task_id}:
| Field | Type | Description |
|---|---|---|
| code | integer | HTTP/business response status code (200 indicates success). |
| data.task_id | string | Globally unique task identifier. |
| data.status | string | Task lifecycle state: not_started, running, finished, or failed. |
| data.files | array | Array of output assets containing file_url and file_type upon completion. |
| data.error_message | string | null | Error diagnostic details if the task status is failed. |
Task Lifecycle
Clients should poll status until reaching either the finished or failed terminal state:
not_startedQueued
runningGenerating
finishedReady
failedFailed
Polling & Error Handling
- Polling frequencyStart polling with a 2 to 3-second interval, gradually increasing to 5 seconds for extended takes.
- Network resiliencyTransient 5xx responses or timeouts do not signify task failure; retry status requests after a short backoff.
- Webhook callbacksProvide a top-level callback_url in your submission payload to receive completion notifications automatically.
Specifications
| Specification | Value | Description |
|---|---|---|
| Model | kwaivgi/kling-video-o3-pro/image-to-video | Kuaishou Kling O3 flagship 1080p image-to-video tier supporting single-frame initiation and dual-keyframe physical motion interpolation with studio-grade native audio. |
| Duration | 3-15 s | Required integer, 3–15 seconds. In multi-shot mode it must equal the sum of shot durations. Billing uses this duration. |
Kling O3 Pro Image to Video
Generate 3–15-second videos with Kling O3 Pro from a starting image and an optional ending frame. Supports single-shot and multi-shot generation. Explicitly set sound; multi-shot requires audio.
Why Choose This Model
Precision Dual-Keyframe InterpolationRigidly anchors initial and terminal keyframes in 3D scene space, automatically calculating physically consistent interpolation curves and camera paths.
1080p Micro-Texture PreservationRetains skin micro-pores, fine fabric weaves, glass highlights, and nuanced gradient shadows without blurriness or artifacts in full 1080p.
Rock-Solid Asset & Character IdentityDeep feature correlation networks prevent character facial drift, garment changes, or prop distortion during complex dynamic motion.
Native Action & Ambient Audio SynthesisSynthesizes multi-channel environmental ambience, contact Foley sound effects, and lip-sync dialogue directly aligned with physical visual motion.
Flexible Duration & Multi-Shot PacingRenders continuous clips from 3 to 15 seconds, supporting single-shot dynamic takes as well as structured multi-shot scene sequences.
Parameters
| Parameter | Requirement | Description |
|---|---|---|
| prompt | Conditional | Required when multi_shots=false. Describe the scene, action and camera movement. Use nonblank text, up to 2,500 characters after trimming. Omit prompt when multi_shots=true. Default - |
| multi_shots | Yes | Required: explicitly send false for a single shot or true for multiple shots. Single-shot mode requires prompt. Multi-shot mode requires multi_prompt and sound=true, with no nonblank top-level prompt. Omitting this field is an error. Default - |
| multi_prompt | Conditional | Required when multi_shots=true; omit in single-shot mode. Supply at least one shot, each with a nonblank prompt of up to 2,500 characters and an integer duration of 1–12 seconds. Shot durations must sum to the top-level duration (3–15 seconds). Extra fields inside a shot are ignored. Default - |
| duration | Yes | Required integer from 3 to 15 seconds. In multi-shot mode, this must equal the sum of all shot durations. Credits are calculated using this value. Default - |
| sound | Yes | Required: explicitly send true to generate audio or false for video without audio. Single-shot mode accepts either value; multi-shot mode requires true. Default - |
| aspect_ratio | No | May be omitted. If provided, use 16:9, 9:16 or 1:1. Image-to-video ignores this value; framing is determined by the input image. Default - |
| image_urls | Yes | Required: an array of 1–2 images. The first is the starting frame; the optional second is the ending frame. Accepts public HTTP(S) URLs, image Data URIs or raw Base64 image data. Default - |
How to Use
Upload high-resolution keyframesProvide 1 starting visual still (required), and optionally upload 1 ending still to anchor the terminal state.
Describe action and camera trajectoryDetail physical motion progression, velocity, and camera movement connecting the initial and final keyframes.
Set duration and audio channelsSelect an integer runtime between 3 and 15 seconds, and toggle native synchronized audio generation on or off.
Dispatch rendering taskSubmit via API or click Run; the diffusion model computes spatio-temporal physics across the entire timeline.
Review and export 1080p footageInspect subject consistency and kinetic continuity, then download your watermark-free 1080p MP4 master.
Pricing
Credits = top-level duration × per-second rate. 1 credit = $0.005. If generation fails, consumed credits are automatically and fully refunded.
| Usage | Rate | Details |
|---|---|---|
| Without sound | 13 credits/s ($0.065/s) | Professional 1080p keyframe animation without audio. |
| With sound | 16 credits/s ($0.080/s) | Full 1080p video paired with studio-grade native synchronized audio. |
Best Use Cases
High-End Fashion & E-Commerce MotionTransform static studio photoshoots into breathing 1080p runway sequences with natural fabric flutter.
VFX Keyframe Precision TransitionsDefine exact opening and closing composition stills, letting the model synthesize physically coherent VFX motion.
Digital Avatar & Character AnimationRetain character facial geometry with zero drift while introducing expressive dialogue and head turns.
Architectural Visualizations & ToursConvert architectural still renders into dynamic fly-through sequences with realistic lighting transitions.
Pro Tips
- When utilizing dual keyframes, maintain consistent lighting direction and subject proportions across both stills for optimal physical interpolation.
- Center your prompt on transitional movement: explain how the character moves from the opening pose to the final posture.
- Provide clean, uncompressed source images where the primary subject has clear depth separation from the background.
- To generate dialogue in a specific language, enclose spoken lines in quotation marks within the prompt and ensure the subject's face is unobstructed.
- Avoid demanding abrupt 180-degree camera flips; gradual kinetic development produces the most realistic physics.
Notes
- image_urls supports 1 to 2 images (the first as start frame, the second as end frame). The output aspect ratio naturally reflects source image dimensions.
- Enabling multi_shots requires sound=true and mandates that individual shot durations sum exactly to the overall duration.
- Tasks execute asynchronously; use the returned task_id to poll status until reaching finished or failed.
Kling O3 Pro Image to Video API FAQ
What does this endpoint generate?
Generate 3–15-second videos with Kling O3 Pro from a starting image and an optional ending frame. Supports single-shot and multi-shot generation. Explicitly set sound; multi-shot requires audio.
How do I use starting and ending frames?
Required: an array of 1–2 images. The first is the starting frame; the optional second is the ending frame. Accepts public HTTP(S) URLs, image Data URIs or raw Base64 image data.
How is the video aspect ratio determined?
May be omitted. If provided, use 16:9, 9:16 or 1:1. Image-to-video ignores this value; framing is determined by the input image.
How do I set up multiple shots?
Required: explicitly send false for a single shot or true for multiple shots. Single-shot mode requires prompt. Multi-shot mode requires multi_prompt and sound=true, with no nonblank top-level prompt. Omitting this field is an error. Required when multi_shots=true; omit in single-shot mode. Supply at least one shot, each with a nonblank prompt of up to 2,500 characters and an integer duration of 1–12 seconds. Shot durations must sum to the top-level duration (3–15 seconds). Extra fields inside a shot are ignored.
How do I control audio and prompt length?
Required: explicitly send true to generate audio or false for video without audio. Single-shot mode accepts either value; multi-shot mode requires true. The API validates prompts up to 2,500 characters. Some multi-shot generation requests have failed when a shot prompt exceeded 512 characters. We recommend keeping each shot prompt within 512 characters; this recommendation does not change the API validation limit.
How are duration and credits calculated?
Duration is 3–15 seconds. Video without audio costs 13 credits/s; video with audio costs 16 credits/s. Credits equal the top-level duration multiplied by the applicable rate.
What happens if generation fails or my request times out?
Invalid parameters are rejected before a generation task is created or credits are deducted. If an accepted generation task later reaches failed, its deducted credits are refunded. A client timeout alone does not mean the task failed; query its task_id before submitting again.