Advanced lip-sync for videos. Identify faces then sync them with custom audio tracks.
Add Authorization header with Bearer token to all requests:
Authorization: Bearer YOUR_API_KEY
| Model | API Name | Features | Price (85% off) |
|---|---|---|---|
| Face Recognition | kling-identify-face | Detect faces in video, returns session_id + face_id | $0.0007/call |
| Advanced Lip Sync | kling-advanced-lip-sync | Sync faces with audio, multi-face support | $0.0063/5s |
| Operation | Price |
|---|---|
| Face Recognition (kling-identify-face) | $0.0007/call |
| Advanced Lip Sync (kling-advanced-lip-sync) | $0.0063/5s |
/api/v1/audio/generationsCreate a face recognition or lip sync task. Set model to "kling-identify-face" or "kling-advanced-lip-sync".
/api/v1/audio/generations?task_id=xxxQuery task status and retrieve results
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-advanced-lip-sync" with the session_id, the face_id(s) you want to sync, and the corresponding audio source.
Submit a video to identify faces. Returns a session_id and list of face objects with face_id values.
Use the session_id and face_id values from step 1 to apply lip sync with custom audio.
# Step 1: Identify faces in the video
curl -X POST https://apimodels.app/api/v1/audio/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-identify-face",
"video_url": "https://example.com/video.mp4"
}'{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "pending",
"model": "kling-identify-face"
}
}{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "completed",
"model": "kling-identify-face",
"faceData": {
"session_id": "session_abc123",
"face_list": [
{
"face_id": "face_001",
"face_reference": "https://...face_thumbnail.jpg"
}
]
}
}
}{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "completed",
"model": "kling-advanced-lip-sync",
"resultUrls": ["https://...lip_synced_video.mp4"]
}
}{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "failed",
"failMsg": "Face detection failed: no faces found"
}
}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.
POST {your callback_url}
Content-Type: application/json
{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"model": "kling-video/kling-advanced-lip-sync",
"state": "completed" | "failed",
"param": "<JSON string>", // request params, JSON.parse once
"resultJson": "<JSON string> | null", // result object, JSON.parse once
"failCode": null | "string",
"failMsg": null | "string",
"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.
{
"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":[]}.
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
})pendingTask queued, waiting to processprocessingTask is being executedcompletedTask completed successfullyfailedTask failed400Bad Request - Missing or invalid parameters401Unauthorized - Invalid API key402Payment Required - Insufficient credits404Not Found - Task ID not found500Internal Server Error