开发者 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 的总时长计费。
示例一:
3 秒音频,720p = 5 秒 × 4 = 20 点
(适用最低计费)
示例二:
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 与轮询响应只返回最终放大后的视频结果。

选项一:Webhook(推荐)

在 JSON 体内提供 webhook URL。任务完成后我们会向你的端点发送结果。

Webhook URL 必须是公网 HTTPS URL。如果投递失败,我们会以指数退避最多重试 5 次。

优势:
  • 无需频繁轮询
  • 任务完成即时通知
  • 更适合 30–120 秒的长任务

选项二:轮询

不提供 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();