Kling 4.0 Reference to Video API
kwaivgi/kling-v4.0/reference-to-videoKling 4.0 Reference to Video turns reference images, videos and reusable elements into a 3–30 second 720p or 1080p video with stereo audio, cited as @Image1, @Video1 or @Element1. It keeps characters, products and settings consistent with your references inside the new scene you describe.
Drag and drop files, paste from clipboard, or provide a URL. Optional start frame: 1 JPEG, PNG or WebP image.
Drag and drop files, paste from clipboard, or provide a URL. Up to 10 images, cited in the prompt as @Image1, @Image2…
2/10 files added
Drag and drop files, paste from clipboard, or provide a URL. Up to 5 videos, 3–30 s each and 30 s combined, cited as @Video1… Billed as input video.
Switch to JSON to add kling_elements or multi-shot prompts with multi_prompt.
REST API
Quick Start
Make your first Kling 4.0 Reference to Video request in three steps. The example cites a character and a workshop image as @Image1 and @Image2 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 reference input.
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/reference-to-video",
"input": {
"prompt": "@Image1 is the character: a young violin maker with round glasses and a green work apron. @Image2 is the workshop: wooden benches, hanging violin bodies, a dusty window. In one continuous 8-second shot, she lifts a finished violin, tightens a peg, and plays a short bright phrase while the camera circles slowly around the bench. Keep her face, glasses and apron consistent with @Image1. Audio: the short violin phrase, a creaking floorboard, quiet street noise outside. No text, no logos, no watermark.",
"duration": 8,
"resolution": "720p",
"aspect_ratio": "16:9",
"reference_image_urls": [
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/reference-to-video/v1/01/input-01.webp",
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/reference-to-video/v1/01/input-02.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": "WV8ZE7C44UA7J6U4",
"status": "not_started",
"created_time": "2026-11-05T07:05:17"
}
}{
"code": 200,
"data": {
"task_id": "WV8ZE7C44UA7J6U4",
"status": "finished",
"files": [
{
"file_url": "https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/reference-to-video/v2/01/output-01.mp4",
"file_type": "video"
}
],
"created_time": "2026-11-05T07:05:17",
"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/reference-to-video",
"input": {
"prompt": "@Image1 is the character: a young violin maker with round glasses and a green work apron. @Image2 is the workshop: wooden benches, hanging violin bodies, a dusty window. In one continuous 8-second shot, she lifts a finished violin, tightens a peg, and plays a short bright phrase while the camera circles slowly around the bench. Keep her face, glasses and apron consistent with @Image1. Audio: the short violin phrase, a creaking floorboard, quiet street noise outside. No text, no logos, no watermark.",
"duration": 8,
"resolution": "720p",
"aspect_ratio": "16:9",
"reference_image_urls": [
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/reference-to-video/v1/01/input-01.webp",
"https://cdn.vidgo.ai/apis/models/kwaivgi/kling-v4.0/reference-to-video/v1/01/input-02.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/reference-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: at least one reference input and prompt or multi_prompt, plus optional start frame, duration, resolution and aspect_ratio. |
| 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.reference_image_urls | string[] | No | — | ≤10 image URLs (@Image1…). |
| input.reference_video_urls | string[] | No | — | ≤5 video URLs (@Video1…), 3–30 s each; billed as input video. |
| input.kling_elements | object[] | No | — | ≤7 elements, ≤3 video-based. Each: element_input_urls (2–4) or element_input_video_urls (1). |
| input.image_urls | string[] | No | — | ≤1 start-frame URL. |
| input.duration | integer | No | 5 | 3–30 s. |
| input.resolution | string | No | 720p | 720p or 1080p. |
| input.aspect_ratio | string | No | auto | auto, 16:9, 9:16, 1:1, 21:9. |
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 the reference counts (10 images, 5 videos, 7 elements, 15 in total) and input video lengths.
- 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/reference-to-video | Model identifier for reference-guided video generation. |
| Duration | 3–30 | Whole seconds; defaults to 5. |
| Resolution | 720p | 1080p | Defaults to 720p. |
| Aspect ratio | auto | 16:9 | 9:16 | 1:1 | 21:9 | Defaults to auto. |
| Pricing | 28.5 / 42.5 · 17 / 25.5 credits/s | Image references: 720p / 1080p per output second. With reference videos or video elements: the input-video rate per billed second. |
Related Models
Kling 4.0 Reference to Video API FAQ
What is the Kling 4.0 Reference to Video API?
Kling 4.0 Reference to Video is a Kuaishou model for generating video guided by reference media, released by Kling AI in October 2026. It turns up to 10 images, 5 reference videos and 7 elements into a 3–30 second 720p or 1080p clip with a stereo audio track. Its Omni Reference input lets the prompt cite each asset as @Image1, @Video1 or @Element1, so identity, setting and motion come from the references you choose. You can call it programmatically or try it from the playground above.
How do I cite references in a Kling 4.0 Reference to Video prompt?
Refer to each input by its position in its list: @Image1 for the first reference image, @Video2 for the second reference video, @Element1 for the first element. Say what each one contributes, for example "@Image1 is the character, @Video1 is the dance".
How are reference videos billed in Kling 4.0 Reference to Video?
When a reference video or video element is present, you pay a lower rate (17 credits/s at 720p, 25.5 at 1080p) on billed seconds: output seconds plus the longer of output seconds or total input video length, rounded up. A 10-second 720p clip with a 3-second reference video bills 20 seconds, 340 credits ($1.70).
What are elements in Kling 4.0 Reference to Video?
An element is a reusable subject defined by element_input_urls with 2–4 images of the same character or object, or by element_input_video_urls with exactly one video. A request can hold up to 7 elements, at most 3 of them video-based.
How many references can Kling 4.0 Reference to Video use?
Up to 15 assets in total: at most 10 images including the optional start frame, 5 reference videos and 7 elements. Input videos each run 3–30 seconds and together at most 30 seconds.
How much does Kling 4.0 Reference to Video cost with image references only?
With images and image elements only, it bills like text-to-video: 28.5 credits per output second at 720p and 42.5 at 1080p. An 8-second 720p clip is 228 credits ($1.14).
Can Kling 4.0 Reference to Video start on a specific frame?
Yes. Put one image in image_urls to open the clip on it, alongside your references. It counts toward the 10-image limit.















