開發者 API

Lipsync API 平台

使用我們強大的 REST API 以程式化方式生成對口型影片

API 金鑰

管理你的 API 驗證金鑰

為你的 API 金鑰取一個容易記住的名稱(可選)

需要登入

請登入以建立並管理 API 金鑰。

適合你的定價

以彈性且具競爭力的價格開始使用

API 定價

按量計費

注意:API 點數與使用者點數相互獨立,不能互相轉換。

價格
點數

注意:

每次生成至少扣費:5 秒
480p 解析度:每秒 2 點
720p 解析度:每秒 4 點
lipsync-image/video/multi 1080p:每秒 6 點,最低 30 點
lipsync-image/video/multi 2k:每秒 7 點,最低 35 點
lipsync-image/video/multi 4k:每秒 8 點,最低 40 點
talking-avatar:720p/1080p/2k/4k 依向上取整後的音訊秒數計費,分別為 4/6/8/9 點每秒
lipsync-video:若影片長於音訊將被裁切;若音訊長於影片將自動延長。計費在裁切時依音訊長度、延長時依影片長度計算。
lipsync-image-multi:當 order 為「meanwhile」時,按兩段音訊的最大長度計費;否則按「left_audio」與「right_audio」總長度計費。
範例 1:
3 秒音訊,720p = 5 秒 × 4 = 20 點
(適用最少扣費)
範例 2:
10 秒音訊,480p = 10 × 2 = 20 點

驗證

保護你的 API 請求

在所有請求中將 API 金鑰放入 Authorization 標頭:

Authorization: Bearer sk_XXXX_YYYY

可用端點

RESTful API 端點

POST/api/v1/lipsync-video

影片替換音訊並保持對口型同步

POST/api/v1/lipsync-image

圖片 + 音訊 → 單人說話頭像

POST/api/v1/talking-avatar

圖片 + 音訊 + 提示詞 → 可控制表情與動作的說話頭像

POST/api/v1/lipsync-image-multi

圖片 + 雙音訊 → 多說話人頭像(對話/談話)

GET/api/v1/jobs/{requestId}

查詢任務狀態並取得結果

目前 API 範圍

輸入、隱私、模型涵蓋範圍與正式使用說明

輸入採用 URL

公開 API 目前透過 JSON 接收媒體 URL,暫不支援直接 multipart 檔案上傳或素材上傳端點。只要我們的 worker 與生成服務在任務執行期間可以存取,簽名 URL 或臨時 URL 都可以使用。

API 輸出為私有

API 任務會以私有可見性儲存。網頁端的 Public 切換不適用於 API 請求,目前也沒有用於發布生成結果的 API 參數。

模型選擇

透過端點選擇工作流程:lipsync-image、lipsync-video 或 lipsync-image-multi。需要表情與動作控制的圖片模型時,請使用 talking-avatar。

尚未提供 OpenAPI 檔案

此頁面是目前的 API 參考文件。尚未發布機器可讀的 OpenAPI/Swagger 規格。

尚未支援的控制項

目前唇形同步端點尚未開放寬高比、guidance scale 與 audio guidance 參數。

批次任務

每次生成請提交一個 API 請求。大型正式批次請保持輸入 URL 在完成前有效,並在執行非常高併發之前聯絡支援團隊。

詳細參數

完整端點規格

所有端點共用相同結構:可選的 webhook 參數與各模型的 formState 參數。

POST /api/v1/lipsync-video

在維持對口型的同時,以新音訊替換既有影片中的音訊

頂層參數:
webhook選填

你的回呼 URL(HTTPS)。完成後我們會在此 POST 結果。

formState必填

包含所有生成參數的物件(見下)。

formState 參數:
video必填

來源影片的公開 URL(MP4、MOV 等)

audio必填

語音/替換音訊的公開 URL(MP3、WAV 等)

resolution必填

"360p"、"480p"、"720p"、"1080p"、"2k" 或 "4k"

mask_image選填

遮罩圖片的公開 URL(僅在遮罩區域內進行口型)

prompt選填

風格指引文字

seed選填

用於可重現的整數隨機種子

非同步流程

選擇接收結果的方式

所有 API 呼叫都是非同步的。你有兩種方式取得結果:

對於 1080p、2k 和 4k 任務,webhook 與輪詢回應只會返回最終放大後的影片結果。

選項 1:Webhook(推薦)

在 JSON 內提供 webhook URL。任務完成後我們會向你的端點 POST 結果。

Webhook URL 必須是公開 HTTPS URL。如果傳送失敗,我們會以指數退避最多重試 5 次。

優點:
  • 無需反覆輪詢
  • 任務完成即時通知
  • 更適合耗時較長的任務(通常 30–120 秒)

選項 2:輪詢

省略 webhook 參數,使用回傳的 requestId 每 5–10 秒輪詢 GET /api/v1/jobs/{requestId},直到狀態為「completed」。

適用於:
  • 無法暴露公開的 Webhook 端點
  • 測試或除錯

Webhook 範例:

POST /api/v1/lipsync-image
Authorization: Bearer sk_XXXX_YYYY
Content-Type: application/json

{
  "webhook": "https://your-app.example.com/webhooks/lipsync",
  "formState": {
    "image": "https://.../face.png",
    "audio": "https://.../voice.mp3",
    "resolution": "720p",
    "seed": 42
  }
}

// Immediate Response:
{
  "requestId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "processing",
  "message": "Task submitted successfully. Use requestId to query job status."
}

// Later, when job completes, we POST to your webhook:
POST https://your-app.example.com/webhooks/lipsync
Content-Type: application/json

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "model": "lipsync-image",
  "status": "completed",
  "output": "https://.../result.mp4",
  "error": "",
  "executionTime": 12345,
  "timings": null
}

Talking Avatar 請求範例:

POST /api/v1/talking-avatar
Authorization: Bearer sk_XXXX_YYYY
Content-Type: application/json

{
  "webhook": "https://your-app.example.com/webhooks/lipsync",
  "formState": {
    "image": "https://.../character.png",
    "audio": "https://.../speech.mp3",
    "prompt": "Warm presentation style, natural facial expression, subtle head motion",
    "resolution": "1080p"
  }
}

// Completed webhook or polling response:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "model": "talking-avatar",
  "status": "completed",
  "output": "https://.../result.mp4",
  "error": "",
  "executionTime": 12345,
  "timings": null
}

無 Webhook 範例(輪詢):

// Step 1: Submit job (no webhook parameter)
POST /api/v1/lipsync-image
Authorization: Bearer sk_XXXX_YYYY
Content-Type: application/json

{
  "formState": {
    "image": "https://.../face.png",
    "audio": "https://.../voice.mp3",
    "resolution": "720p"
  }
}

// Immediate Response:
{
  "requestId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "processing",
  "message": "Task submitted successfully. Use requestId to query job status."
}

// Step 2: Poll for status (repeat every 5-10 seconds)
GET /api/v1/jobs/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer sk_XXXX_YYYY

// Response while processing:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "model": "lipsync-image",
  "status": "processing",
  "output": null,
  "error": "",
  "executionTime": null,
  "timings": null
}

// Response when completed:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "model": "lipsync-image",
  "status": "completed",
  "output": "https://.../result.mp4",
  "error": "",
  "executionTime": 12345,
  "timings": null
}

// Response if failed:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "model": "lipsync-image",
  "status": "failed",
  "output": null,
  "error": "Generation failed. Please try again later.",
  "executionTime": null,
  "timings": null
}

完整程式碼範例

可直接使用的整合範例

01Node.js(Webhook,推薦)

import fetch from 'node-fetch';
import express from 'express';

const API_KEY = 'Bearer sk_XXXX_YYYY';
const BASE_URL = 'https://lipsync.studio/api/v1';

// Set up webhook server to receive results
const app = express();
app.use(express.json());

app.post('/webhooks/lipsync', (req, res) => {
  const { id, status, output, error, model } = req.body;
  
  console.log('Job update received.');
  console.log('Job ID:', id);
  console.log('Model:', model);
  console.log('Status:', status);
  if (status === 'completed') {
    console.log('Video URL:', output);
  } else if (status === 'failed') {
    console.error('Error:', error);
  }
  
  // TODO: Save output URL to your database, send notification, etc.
  
  res.status(200).json({ received: true });
});

app.listen(3000, () => {
  console.log('Webhook server listening on port 3000');
});

// Submit job with webhook
async function submitJobWithWebhook() {
  const webhookUrl = 'https://your-public-domain.com/webhooks/lipsync';
  
  const res = await fetch(`${BASE_URL}/lipsync-image`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': API_KEY
    },
    body: JSON.stringify({
      webhook: webhookUrl,
      formState: {
        image: 'https://example.com/portrait.jpg',
        audio: 'https://example.com/speech.mp3',
        resolution: '720p'
      }
    })
  });
  
  const data = await res.json();
  console.log('Job submitted:', data.requestId);
  console.log('Waiting for webhook callback...');
  
  // You don't need to poll! The result will be POSTed to your webhook.
}

submitJobWithWebhook();