Kling O3
Kling O3 API. Reference-driven AI video: image references, first/last frame, or a reference video to restyle or continue, 3-15 seconds.
Pricing, live playground and model overview: Kling O3 API on YepAPI
/v1/media/queueOverview
Kling O3 — reference-driven video generation. Steer a clip with reference images, pin its first and last frames, or pass a reference video to restyle or continue. Async operation — submit a job, poll for completion.
| Property | Value |
|---|---|
| Model ID | kwaivgi/kling-o3 |
| Alias | kling-o3 |
| Provider | Kling |
| Inputs | text-to-video, reference images, first/last frame, reference video |
| Aspect Ratios | 16:9, 9:16, 1:1 |
| Duration | 3–15 seconds (3–10 seconds in reference-video mode) |
| Audio Generation | Supported (off by default) |
| Billing | Per job — priced when queued, charged only on success |
| Pricing | from $0.143/second |
Usage
All media models use the async job queue. Submit a job, then poll for the result.
Step 1: Submit Job
Text-to-Video
options.params passes this model's own parameters (see Model parameters).
const res = await fetch('https://api.yepapi.com/v1/media/queue', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'kwaivgi/kling-o3',
prompt: 'A cinematic drone shot over a rugged coastline at golden hour',
options: {
aspectRatio: '16:9',
duration: '5',
generateAudio: true,
params: {
mode: 'pro',
},
},
}),
});
const { data } = await res.json();
// data.jobId — use this to poll for resultscurl -X POST https://api.yepapi.com/v1/media/queue \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "kwaivgi/kling-o3", "prompt": "A cinematic drone shot over a rugged coastline", "options": {"aspectRatio": "16:9", "duration": "5", "generateAudio": true, "params": {"mode": "pro"}}}'Reference Images
Pass an image via imageData (without imageRole) to use it as a reference for the subject, style or setting.
const res = await fetch('https://api.yepapi.com/v1/media/queue', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'kwaivgi/kling-o3',
prompt: 'The character from the reference image walks through a neon-lit night market',
options: {
duration: '5',
generateAudio: true,
},
imageData: {
mimeType: 'image/jpeg',
base64: '...', // Base64-encoded image
},
}),
});curl -X POST https://api.yepapi.com/v1/media/queue \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "kwaivgi/kling-o3", "prompt": "The character from the reference image walks through a neon-lit night market", "options": {"duration": "5", "generateAudio": true}, "imageData": {"mimeType": "image/jpeg", "base64": "..."}}'First / Last Frame
Set options.imageRole to first_frame to switch to first/last-frame mode: imageData becomes the opening frame, and an optional closing frame goes in options.params.last_frame_url as a public image URL.
const res = await fetch('https://api.yepapi.com/v1/media/queue', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'kwaivgi/kling-o3',
prompt: 'Smooth transition from the opening frame to the closing frame, slow push-in',
options: {
aspectRatio: '16:9',
duration: '5',
imageRole: 'first_frame',
params: {
last_frame_url: 'https://example.com/last-frame.jpg',
},
},
imageData: {
mimeType: 'image/jpeg',
base64: '...', // Base64-encoded image
},
}),
});curl -X POST https://api.yepapi.com/v1/media/queue \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "kwaivgi/kling-o3", "prompt": "Smooth transition from the opening frame to the closing frame, slow push-in", "options": {"aspectRatio": "16:9", "duration": "5", "imageRole": "first_frame", "params": {"last_frame_url": "https://example.com/last-frame.jpg"}}, "imageData": {"mimeType": "image/jpeg", "base64": "..."}}'Reference Video
Pass a public MP4 or MOV URL in options.referenceVideoUrl to restyle, edit or continue an existing clip.
const res = await fetch('https://api.yepapi.com/v1/media/queue', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'kwaivgi/kling-o3',
prompt: 'Restyle this clip as a hand-drawn watercolor animation',
options: {
aspectRatio: '16:9',
duration: '5',
referenceVideoUrl: 'https://example.com/reference.mp4', // public MP4 or MOV URL
},
}),
});curl -X POST https://api.yepapi.com/v1/media/queue \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "kwaivgi/kling-o3", "prompt": "Restyle this clip as a hand-drawn watercolor animation", "options": {"aspectRatio": "16:9", "duration": "5", "referenceVideoUrl": "https://example.com/reference.mp4"}}'Step 2: Poll for Result
const status = await fetch(`https://api.yepapi.com/v1/media/status/${data.jobId}`, {
headers: { 'x-api-key': 'YOUR_API_KEY' },
});
const { data: job } = await status.json();
// job.status — "pending" | "processing" | "completed" | "failed"
// job.result.video — { mimeType, base64 } when completedcurl https://api.yepapi.com/v1/media/status/JOB_ID \
-H "x-api-key: YOUR_API_KEY"Request Body
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
model | string | Yes | kwaivgi/kling-o3 or alias kling-o3 | — |
prompt | string | Yes | Text description of the video to generate | — |
options.aspectRatio | string | No | One of: 16:9, 9:16, 1:1 | model default |
options.duration | string or number | No | 3 to 15 (seconds); 3 to 10 (seconds) in reference-video mode | 5 |
options.generateAudio | boolean | No | Generate an audio track for the video (not in reference-video mode) | false |
options.imageRole | string | No | first_frame switches to first/last-frame mode (imageData = first frame); omit to use imageData as a reference image | — |
options.referenceVideoUrl | string | No | Public MP4 or MOV URL of a reference video to restyle, edit or continue | — |
options.params | object | No | Model-specific parameters under their own names: elements, last_frame_url, mode, multi_prompt, multi_shots, shot_type. Unknown names return 400 | — |
imageData.mimeType | string | No | MIME type of input image (image/png, image/jpeg, image/webp) | — |
imageData.base64 | string | No | Base64-encoded reference image, or the first frame with imageRole | — |
Options are validated when you submit: an unsupported duration, resolution or value returns 400 naming the allowed values.
Model parameters
Pass these inside options.params.
| Parameter | Type | Allowed | Description | Default |
|---|---|---|---|---|
elements | array | — | Kling element IDs to keep consistent across the clip (only image input, text-to-video, reference-video mode) | — |
mode | string | std, pro, 4k | Quality mode | pro (first/last-frame mode, reference-video mode); std (image input, text-to-video) |
multi_prompt | array | up to 6 shots | Multi-shot script: list of { prompt, duration } shots (only first/last-frame mode, image input, text-to-video) | — |
multi_shots | boolean | — | Generate a multi-shot sequence (only first/last-frame mode, image input, text-to-video) | false |
shot_type | string | customize, intelligent | Multi-shot planning: your shots (customize) or the model's (intelligent) (only image input, text-to-video) | customize |
last_frame_url | string | public image URL | Public URL of the last frame (first/last-frame mode) | — |
Features
- Text-to-video and reference-image video
- First/last-frame mode (
imageRole: 'first_frame'+options.params.last_frame_url) - Reference video via
options.referenceVideoUrl - Optional native audio (off by default)
- Multi-shot sequences via
options.params.multi_shots/multi_prompt
Pricing
| Tier | ≈ Cost/sec | 5-second video |
|---|---|---|
| Without audio | $0.143 | $0.72 |
| With audio | $0.19 | $0.96 |
Prices shown are for a 5-second clip at the default settings; longer clips cost proportionally more. The mode parameter (std/pro/4k) changes the price. Each job is priced when it's queued — the exact quote for your duration, resolution and options — and charged only if it succeeds. Failed or moderated jobs are free.
Video jobs can take several minutes to complete. When capacity is busy, jobs wait in the queue (status stays pending or processing) — no action needed. Results retained for 1 hour.
Powered by Kling's Kling O3 via our AI provider.