Kling Lip Sync API
Advanced lip-sync for videos. Identify faces then sync them with custom audio tracks.
Quick Start
Authentication
Add Authorization header with Bearer token to all requests:
Authorization: Bearer YOUR_API_KEY
Available Models
| Model | API Name | Features | Price (up to 60% off) |
|---|---|---|---|
| Face Recognition | kling-identify-face | Detect faces in video, returns sessionId + faceId | $0.0100/call |
| Lip-Sync Video | kling-lip-sync-video | Lip-sync a video using sessionId + faceId + audio | $0.0650/5s |
Pricing (up to 60% off)
| Operation | Price |
|---|---|
| Face Recognition (kling-identify-face) | $0.0100/call |
| Lip-Sync Video (kling-lip-sync-video) | $0.0650/5s |
Endpoints
/api/v1/video/generationsCreate a face recognition or lip sync task. Set model to "kling-identify-face" or "kling-lip-sync-video".
/api/v1/video/generations?task_id=xxxQuery task status and retrieve results
Two-Step Workflow
Lip sync requires two API calls. First, submit your video to "kling-identify-face" — this returns a session_id and a list of detected faces with their face_id values. Then, submit a second request to "kling-lip-sync-video" with the session_id, the face_id(s) you want to sync, and the corresponding audio source.
Request Parameters
Step 1 — Face Recognition (kling-identify-face)
Submit a video to identify faces. Returns a sessionId and faceId in resultJson, used by Step 2. $0.01 per call.
Step 2 — Lip-Sync Video (kling-lip-sync-video)
Use the sessionId and faceId from Step 1 to lip-sync the video with an audio track (audioId from kling-lip-sync-tts, or a direct audioUrl).
Text-to-Speech (kling-lip-sync-tts)
Synthesize speech from text with a preset voice — used to drive lip-sync. Returns an audio result.
Code Examples
# Step 1: Identify faces in the video
curl -X POST https://api.apimodels.app/v1/video/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-identify-face",
"video_url": "https://example.com/video.mp4"
}'Response Format
Create Task Response
{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "pending",
"model": "kling-identify-face"
}
}Face Recognition — Success
{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "completed",
"model": "kling-identify-face",
"resultUrls": [],
"resultJson": "{ \"resultUrls\": [], \"sessionId\": \"891032747618619461\", \"faceId\": \"0\", \"faces\": [{ \"face_id\": \"0\", \"start_time\": 0, \"end_time\": 13500 }] }"
}
}JSON.parse(data.resultJson) → use sessionId and faceId for kling-lip-sync-video. faces[] also carries the start_time / end_time window per face.
Lip Sync — Success
{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "completed",
"model": "kling-lip-sync-video",
"resultUrls": ["https://...lip_synced_video.mp4"]
}
}Failed Response
{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "failed",
"failMsg": "Face detection failed: no faces found"
}
}Webhook Callback (callback_url)
Pass callback_url in the create request. When the task reaches the completed or failed terminal state, our server sends a single HTTP POST to that URL with Content-Type: application/json (no signing header). Delivery is retried up to 3 times (exponential backoff 1s/2s/4s, 10s per attempt); if still unsuccessful, a background job keeps retrying for up to 30 minutes until your endpoint returns 2xx.
Payload Structure
POST {your callback_url}
Content-Type: application/json
{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"model": "kling-lip-sync-video",
"state": "completed" | "failed",
"param": "<JSON string>", // request params, JSON.parse once
"resultJson": "<JSON string> | null", // result object, JSON.parse once
"failCode": null | "CONTENT_MODERATION | INVALID_INPUT | INSUFFICIENT_BALANCE | UPSTREAM_BUSY | UPSTREAM_FAILED | TIMEOUT | INTERNAL_ERROR | OTHER",
"failMsg": null | "string",
"retryable": true | false, // present when state=failed: safe to retry/fallback
"costTime": 12345, // duration in ms
"completeTime": 1705123500000, // ms epoch
"createTime": 1705123450000 // ms epoch
}
}Note: data.param and data.resultJson are both JSON strings — call JSON.parse once on each.
Lip-sync (video) task: shape after JSON.parse(data.resultJson)
{
"resultUrls": ["https://r2.apimodels.app/videos/lip_synced.mp4"],
"videoDuration": 8 // optional, seconds
}Lip-sync produces a video file. resultUrls is always present (length 1 in success, [] on failure). videoDuration may be present on some upstream branches. When state=failed, resultJson is typically null or {"resultUrls":[]}.
Node.js receiver example
app.post('/webhook/kling-lip-sync', express.json(), (req, res) => {
const { taskId, state, resultJson, failMsg } = req.body.data
if (state === 'completed') {
const r = JSON.parse(resultJson)
console.log('lip-sync ready', taskId, r.resultUrls[0])
} else {
console.warn('lip-sync failed', taskId, failMsg)
}
res.status(200).end() // must be 2xx, otherwise we retry
})Notes
- -A task stops retrying only after a 2xx response — once delivered it is never pushed again.
- -Callbacks are not signed today. Embed a random token in your callback_url path and verify it on receipt.
- -For the kling-identify-face step the callback fires once face_list is ready — read it from JSON.parse(param) or from the GET poll response, not from resultJson.
- -Use a public HTTPS endpoint that responds within 10 seconds (per-attempt timeout).
Task States
pendingTask queued, waiting to processprocessingTask is being executedcompletedTask completed successfullyfailedTask failedError Codes
400Bad Request - Missing or invalid parameters401Unauthorized - Invalid API key402Payment Required - Insufficient credits404Not Found - Task ID not found500Internal Server ErrorImportant Notes
- *Two-step process: always run kling-identify-face first to get sessionId
- *sessionId and faceId from step 1 are required for step 2
- *Provide the audio as audioId (from kling-lip-sync-tts) or a direct audioUrl, plus soundStartTime/soundEndTime/soundInsertTime (ms)
- *Results are stored for 30 days, download the video promptly
- *Lip sync pricing is $0.0650 per 5s segment of the output video
- *Poll every 5-10 seconds to check task status
FAQ
How do I make a talking-face video with Kling lip sync?
Provide a face image/video plus audio (or text to synthesize); the API returns a video where the face speaks in sync. One key, charged only on success.