使用我們強大的 REST API 以程式化方式生成對口型影片
管理你的 API 驗證金鑰
為你的 API 金鑰取一個容易記住的名稱(可選)
需要登入
請登入以建立並管理 API 金鑰。
以彈性且具競爭力的價格開始使用
注意:API 點數與使用者點數相互獨立,不能互相轉換。
保護你的 API 請求
在所有請求中將 API 金鑰放入 Authorization 標頭:
Authorization: Bearer sk_XXXX_YYYY
RESTful API 端點
/api/v1/lipsync-video影片替換音訊並保持對口型同步
/api/v1/lipsync-image圖片 + 音訊 → 單人說話頭像
/api/v1/talking-avatar圖片 + 音訊 + 提示詞 → 可控制表情與動作的說話頭像
/api/v1/lipsync-image-multi圖片 + 雙音訊 → 多說話人頭像(對話/談話)
/api/v1/jobs/{requestId}查詢任務狀態並取得結果
輸入、隱私、模型涵蓋範圍與正式使用說明
公開 API 目前透過 JSON 接收媒體 URL,暫不支援直接 multipart 檔案上傳或素材上傳端點。只要我們的 worker 與生成服務在任務執行期間可以存取,簽名 URL 或臨時 URL 都可以使用。
API 任務會以私有可見性儲存。網頁端的 Public 切換不適用於 API 請求,目前也沒有用於發布生成結果的 API 參數。
透過端點選擇工作流程:lipsync-image、lipsync-video 或 lipsync-image-multi。需要表情與動作控制的圖片模型時,請使用 talking-avatar。
此頁面是目前的 API 參考文件。尚未發布機器可讀的 OpenAPI/Swagger 規格。
目前唇形同步端點尚未開放寬高比、guidance scale 與 audio guidance 參數。
每次生成請提交一個 API 請求。大型正式批次請保持輸入 URL 在完成前有效,並在執行非常高併發之前聯絡支援團隊。
完整端點規格
所有端點共用相同結構:可選的 webhook 參數與各模型的 formState 參數。
在維持對口型的同時,以新音訊替換既有影片中的音訊
webhook選填你的回呼 URL(HTTPS)。完成後我們會在此 POST 結果。
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 與輪詢回應只會返回最終放大後的影片結果。
在 JSON 內提供 webhook URL。任務完成後我們會向你的端點 POST 結果。
Webhook URL 必須是公開 HTTPS URL。如果傳送失敗,我們會以指數退避最多重試 5 次。
省略 webhook 參數,使用回傳的 requestId 每 5–10 秒輪詢 GET /api/v1/jobs/{requestId},直到狀態為「completed」。
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
}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
}// 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
}可直接使用的整合範例
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();