APIMODELSAPIMODELS
Документация API

apimodels.app

Docs/Kling Lip Sync API
LS

Kling Lip Sync API

Advanced lip-sync for videos. Identify faces then sync them with custom audio tracks.

Quick Start

1
Get your API key from the Console
2
Call kling-identify-face to get sessionId and faceId
3
Call kling-lip-sync-video with sessionId, faceId and an audio track
4
Poll for the lip-synced video result

Authentication

Add Authorization header with Bearer token to all requests:

Authorization: Bearer YOUR_API_KEY

Available Models

ModelAPI NameFeaturesPrice (up to 60% off)
Face Recognitionkling-identify-faceDetect faces in video, returns sessionId + faceId$0.0100/call
Lip-Sync Videokling-lip-sync-videoLip-sync a video using sessionId + faceId + audio$0.0650/5s

Pricing (up to 60% off)

OperationPrice
Face Recognition (kling-identify-face)$0.0100/call
Lip-Sync Video (kling-lip-sync-video)$0.0650/5s

Endpoints

POST/api/v1/video/generations

Create a face recognition or lip sync task. Set model to "kling-identify-face" or "kling-lip-sync-video".

GET/api/v1/video/generations?task_id=xxx

Query 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.

modelrequiredstring
"kling-identify-face"
videoUrlstring
Video URL (MP4/MOV, <=100MB, 2-60s, 720p/1080p, 512-2160px). One of videoUrl/videoId required.
videoIdstring
Kling-generated video ID (within 30 days, <=60s). One of videoUrl/videoId required.
callback_urlstring
Webhook URL for completion notification

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).

modelrequiredstring
"kling-lip-sync-video"
sessionIdrequiredstring
Session ID returned by kling-identify-face
faceIdrequiredstring
Face ID returned by kling-identify-face (e.g. "0")
audioIdstring
Audio ID from kling-lip-sync-tts (2-60s, within 30 days). One of audioId/audioUrl required.
audioUrlstring
Audio URL (.mp3/.wav/.m4a, <=5MB, 2-60s). One of audioId/audioUrl required.
soundStartTimerequiredint
Audio crop start (ms). Trimmed audio must be >=2s.
soundEndTimerequiredint
Audio crop end (ms). Trimmed audio must be >=2s.
soundInsertTimerequiredint
Insert time (ms). Must overlap the face lip-syncable window by >=2s and stay within the video bounds.
soundVolumefloat
Audio volume [0, 2]. Default 1.
originalAudioVolumefloat
Original video volume [0, 2]. Default 1 (no effect if the video is silent).
callback_urlstring
Webhook URL for completion notification

Text-to-Speech (kling-lip-sync-tts)

Synthesize speech from text with a preset voice — used to drive lip-sync. Returns an audio result.

modelrequiredstring
"kling-lip-sync-tts"
textrequiredstring
Text to synthesize. Max 1000 characters.
voiceIdrequiredstring
Voice ID — one of 45 presets. Enum: genshin_vindi2, zhinen_xuesheng, tiyuxi_xuedi, ai_shatang, genshin_klee2, genshin_kirara, ai_kaiya, tiexin_nanyou, ai_chenjiahao_712, girlfriend_1_speech02, chat1_female_new-3, girlfriend_2_speech02, cartoon-boy-07, cartoon-girl-01, ai_huangyaoshi_712, you_pingjing, ai_laoguowang_712, chengshu_jiejie, zhuxi_speech02, uk_oldman3, laopopo_speech02, heainainai_speech02, dongbeilaotie_speech02, chongqingxiaohuo_speech02, chuanmeizi_speech02, chaoshandashu_speech02, ai_taiwan_man2_speech02, xianzhanggui_speech02, tianjinjiejie_speech02, diyinnansang_DB_CN_M_04-v2, yizhipiannan-v1, guanxiaofang-v2, tianmeixuemei-v1, daopianyansang-v1, mengwa-v1, AOT, oversea_male1, girlfriend_4_speech02, chat_0407_5-1, uk_boy1, PeppaPig_platform, ai_huangzhong_712, calm_story1, uk_man2, reader_en_m-v1, commercial_lady_en_f-v1
voiceLanguagerequiredstring
Voice language, must match the chosen voice. Enum: zh / en. Default: zh.
voiceSpeedfloat
Playback speed, 0.8–2.0 (1 decimal). Default: 1.0.

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 process
processingTask is being executed
completedTask completed successfully
failedTask failed

Error Codes

400Bad Request - Missing or invalid parameters
401Unauthorized - Invalid API key
402Payment Required - Insufficient credits
404Not Found - Task ID not found
500Internal Server Error

Important 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.