Kling 4.0 Image to Video API
kwaivgi/kling-v4.0/image-to-videoKling 4.0 Image to Video animates a start image into a 3–30 second 720p or 1080p video with stereo audio, optionally finishing on an end frame you choose. It keeps the subject, framing and look of your image while adding the motion, camera work and sound in your prompt.
Drag and drop files, paste from clipboard, or provide a URL. Required. 1–2 JPEG, PNG or WebP images: start frame, then optional end frame.
2/2 files added
Switch to JSON to write multi-shot prompts with multi_prompt.
REST API
Quick Start
Make your first Kling 4.0 Image to Video request in three steps. The example sends a start and end frame for a 6-second clip and returns a task_id.
Connect to the Vidgo API
Create an API key, keep it on your server, and send it in the Authorization header as a Bearer token.
- Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Authentication
- Authorization: Bearer VIDGO_API_KEY
Submit one generation task
Run the short example with a prompt and at least one image in image_urls.
curl --request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "kwaivgi/kling-v4.0/image-to-video",
"input": {
"prompt": "The climber from the first image reaches up, finds a hold, and pulls herself onto the ledge shown in the second image. Chalk dust drifts from her hand, the rope sways gently below. Camera holds a steady side angle with a slight upward tilt. Late-afternoon sun on sandstone. Audio: wind across the rock face, a short exhale, carabiner clink. No text, no logos, no watermark.",
"duration": 6,
"resolution": "720p",
"image_urls": [
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/image-to-video/v1/01/input-start-frame.webp",
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/image-to-video/v1/01/input-end-frame.webp"
]
}
}'Wait for the result
Use the returned task_id to check the same task until it reaches finished or failed. On success, read data.files[].file_url.
Track status
GET https://api.vidgo.ai/api/generate/status/{task_id}Poll every few seconds while the status is not_started or running, and stop on finished or failed. On success, read data.files[].file_url. For longer clips, lengthen the interval gradually or add callback_url to the submit request.
not_startedrunningfinishedfailed{
"code": 200,
"data": {
"task_id": "JWDB8PZQOCAI2DMO",
"status": "not_started",
"created_time": "2026-11-05T07:05:15"
}
}{
"code": 200,
"data": {
"task_id": "JWDB8PZQOCAI2DMO",
"status": "finished",
"files": [
{
"file_url": "https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/image-to-video/v2/01/output-01.mp4",
"file_type": "video"
}
],
"created_time": "2026-11-05T07:05:15",
"error_message": null,
"progress": 100
}
}Complete runnable example
Open this after the three-step flow is clear. It combines submission, polling, terminal-state handling and result extraction in one script.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "kwaivgi/kling-v4.0/image-to-video",
"input": {
"prompt": "The climber from the first image reaches up, finds a hold, and pulls herself onto the ledge shown in the second image. Chalk dust drifts from her hand, the rope sways gently below. Camera holds a steady side angle with a slight upward tilt. Late-afternoon sun on sandstone. Audio: wind across the rock face, a short exhale, carabiner clink. No text, no logos, no watermark.",
"duration": 6,
"resolution": "720p",
"image_urls": [
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/image-to-video/v1/01/input-start-frame.webp",
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/image-to-video/v1/01/input-end-frame.webp"
]
}
}
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')
if [ -z "$TASK_ID" ]; then
printf 'Submit response did not include task_id:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
while true; do
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')
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 2
;;
*)
printf 'Unexpected task status: %s
' "$STATUS" >&2
exit 1
;;
esac
doneRequest Parameters
model and callback_url belong at the request root; generation parameters belong inside input.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| model | string | Yes | — | Fixed to kwaivgi/kling-v4.0/image-to-video. |
| callback_url | string (URL) | No | — | A public HTTP(S) URL that receives the task result when it finishes. |
| input | object | Yes | — | Generation parameters: 1–2 images and prompt or multi_prompt, plus optional duration and resolution. |
| input.prompt | string | No | — | Single prompt, 1–26,000 characters. Exactly one of prompt or multi_prompt. |
| input.multi_prompt | object[] | No | — | Shots of {prompt, duration?}; totals 3–30 s. If duration is also sent it must equal the total. |
| input.image_urls | string[] | Yes | — | 1–2 URLs: [start_frame] or [start_frame, end_frame]. |
| input.duration | integer | No | 5 | 3–30 s. |
| input.resolution | string | No | 720p | 720p or 1080p. |
Response Fields
Submission returns the task identity immediately. Status responses add progress, output files or a failure message as the task advances.
| Field | Type | Description |
|---|---|---|
| code | integer | Application result code. Successful responses use 0 or 200. |
| message | string | Human-readable response or error message when present. |
| data.task_id | string | Task identifier used in the status endpoint path. |
| data.status | string | Current state: not_started, running, finished or failed. |
| data.created_time | string | Task creation time in date-time format. |
| data.progress | number | Completion percentage when the provider reports progress. |
| data.files[] | array | Generated output files returned after a successful task. |
| data.files[].file_url | string | Public URL of the generated video. |
| data.files[].file_type | string | Generated file type, such as video. |
| data.files[].watermark_url | string | null | Watermarked output URL when one is available. |
| data.error_message | string | null | Failure detail when status is failed. |
Task Lifecycle
Treat not_started and running as non-terminal states. finished and failed are terminal; stop polling when either is returned.
not_startedThe task has been accepted and is queued to start.
runningThe video is being generated. Keep polling the status endpoint.
finishedThe task is complete. Read the video URL from data.files[].file_url.
failedGeneration failed. Read data.error_message for details and stop polling.
Polling and Errors
- Authentication401 means the Bearer API key is missing or invalid. Check your key in the dashboard before retrying.
- Validation400 means a request field is invalid or belongs to another endpoint. Check image_urls (1–2 URLs) and prompt or multi_prompt.
- Polling intervalPoll every few seconds while the task runs, and lengthen the interval gradually for longer clips.
- Terminal statesPoll only while the status is not_started or running. Stop on finished or failed.
- Callback optionAdd callback_url at the request root to receive the final result without continuous polling.
Model Specifications
| Specification | Value | Description |
|---|---|---|
| Model | kwaivgi/kling-v4.0/image-to-video | Model identifier for asynchronous image-to-video generation with an optional end frame. |
| Duration | 3–30 | Whole seconds; defaults to 5. |
| Resolution | 720p | 1080p | Defaults to 720p. |
| Pricing | 28.5 / 42.5 credits/s | 720p / 1080p, per output second. |
Related Models
Kling 4.0 Image to Video API FAQ
What is the Kling 4.0 Image to Video API?
Kling 4.0 Image to Video is a Kuaishou model for animating still images, released by Kling AI in October 2026. It turns a start image, and optionally an end image, into a 3–30 second video at 720p or 1080p with a stereo audio track. The model keeps the subject and framing of your image as the opening frame and plans the motion toward the end frame when you provide one. You can call it programmatically or try it from the playground above.
How do start and end frames work in Kling 4.0 Image to Video?
List the URLs in image_urls in order. The first image opens the clip and a second image, if present, is where it ends; the prompt describes how to get from one to the other.
What aspect ratio does Kling 4.0 Image to Video use?
The output follows the shape of the start image. Crop the image to 16:9, 9:16 or another ratio before uploading to set the frame.
Can Kling 4.0 Image to Video use multiple shots from one image?
Yes. Send multi_prompt instead of prompt to split the clip into shots with their own descriptions and durations, totalling 3–30 seconds.
How much does Kling 4.0 Image to Video cost?
It costs 28.5 credits ($0.1425) per output second at 720p and 42.5 credits ($0.2125) at 1080p. A 6-second 720p clip is 171 credits.
How long can a Kling 4.0 Image to Video clip run?
From 3 to 30 seconds in one pass, defaulting to 5. Longer clips work best when the prompt describes several stages of the action.
When should I use Kling 4.0 Reference to Video instead of Image to Video?
Image to Video locks your image as the first frame. Choose Reference to Video when you want a character, product or setting carried into new scenes without fixing the opening frame, or when you need several references at once.















