API v1 参考 / Reference
用 API 提交和查询 YouTube 视频翻译任务(专业计划)。 Submit and check YouTube translation tasks with the API (Pro plan).
概览 / Overview
VideoLingo API 让你在自己的代码里提交 YouTube 视频翻译任务并查询进度。API 提交的任务就是普通任务:会出现在网页工作台的任务列表里(默认名称以 API · 开头),计费与网页提交相同。
The VideoLingo API lets you submit YouTube translation tasks and check their progress from your own code. API tasks are regular tasks: they show up in your dashboard task list (default name starts with API · ) and are billed the same way as tasks started on the website.
- 仅限专业计划 / Pro plan only:有效期内的专业计划(到期后有 1 天宽限)。免费和入门计划调用会返回
403。 An active Pro subscription is required (with a 1-day grace period after the paid period ends). Free and Starter plans get403. - 基址 / Base URL:
https://videolingo.io/api/v1 - 只接受 YouTube / YouTube only:
youtube_url必须是 https 链接,主机为youtube.com、www.youtube.com、m.youtube.com或youtu.be。支持watch?v=…、youtu.be/…、/shorts/…、/embed/…、/live/…、/v/…格式。youtube_urlmust be an https URL on one of those hosts, in one of those formats. - 只有两个端点 / Two endpoints:
POST /tasks提交、GET /tasks/{id}查询。暂无列表、取消和回调(webhook)接口。 There is no list, cancel or webhook endpoint yet. - 所有响应都是 JSON,带
Cache-Control: no-store。响应不带 CORS 头,所以请从服务端调用,不要在浏览器前端里直接调用(也避免泄露 Key)。 All responses are JSON withCache-Control: no-store. No CORS headers are sent: call the API from a server, never from browser code (which would also leak your key).
获取 API Key / Get your API key
登录后打开 工作台 → 账户 → API,也可以从右上角头像菜单进入「API Key」。有效期内的专业用户会自动获得一把 Key(以 vl_live_ 开头),可以显示、复制或重新生成。
Sign in and open Dashboard → Account → API, or pick "API Key" from the avatar menu in the top right. Active Pro users get a key automatically (it starts with vl_live_); you can show, copy or regenerate it there.
Key 等同密码:不要提交到代码仓库、不要截图分享。建议放在环境变量里(下面的示例都使用 $VL_API_KEY)。
Treat the key like a password: never commit it or share screenshots of it. Keep it in an environment variable (the examples below read $VL_API_KEY).
鉴权 / Authentication
每个请求都要带请求头:
Send this header with every request:
Authorization: Bearer vl_live_xxxxxxxxxxxxxxxx只认这个请求头:不读 Cookie,也不接受 URL 查询参数里的 Key。缺少 Key、格式不对或 Key 无效都返回 401 invalid_api_key;Key 有效但专业计划已失效返回 403 subscription_inactive。
Only this header is accepted: cookies and query-string keys are ignored. A missing, malformed or unknown key returns 401 invalid_api_key; a valid key without an active Pro subscription returns 403 subscription_inactive.
提交任务 / Create a task
POST /tasks
请求头 / Headers
| 请求头 / Header | 说明 / Description |
|---|---|
Authorization | 必填。Bearer 加你的 Key。 Required. Bearer followed by your key. |
Content-Type | application/json |
Idempotency-Key | 可选,但强烈建议带上。8–128 个字符。 Optional but strongly recommended. 8–128 characters. |
为什么要带 Idempotency-Key:网络超时后重试时,如果没有这个请求头,可能会创建两个任务、扣两次费。带上后,同一个 Key 的重复提交总是指向同一个任务:任务已开始时直接返回 202 和它的当前状态,不会重复创建或重复扣费。每个新视频用一个新的值(例如你自己系统里的订单号或 UUID)。
Why Idempotency-Key: without it, retrying after a network timeout can create two tasks and charge you twice. With it, every repeat of the same key resolves to the same task: once the task has started, the call just returns 202 with its current state, with no second task and no second charge. Use a fresh value per new video (for example an id from your own system, or a UUID).
同一个 Idempotency-Key 如果属于已删除的任务,返回 422 invalid_request,请换一个新值。
If the Idempotency-Key belongs to a task you deleted, the call returns 422 invalid_request; use a new value.
请求体 / Body
JSON 对象,字段都在顶层。除 youtube_url 外都可选。出现未列出的字段(包括 user_plan、watermark、prod 等由服务端决定的字段)会返回 422 invalid_request。
A flat JSON object. Everything except youtube_url is optional. Any field not listed here (including server-controlled ones such as user_plan, watermark, prod) is rejected with 422 invalid_request.
| 字段 / Field | 类型 / Type | 默认 / Default | 说明 / Description |
|---|---|---|---|
youtube_url | string | 必填 / required | YouTube 视频链接,最长 2048 字符,规则见概览。 YouTube video URL, at most 2048 characters (see Overview). |
name | string | API · <视频 ID / video id> | 任务名称,1–200 字符(会去掉首尾空格)。 Task name, 1–200 characters (trimmed). |
target_language | string | 简体中文 | 目标语言,见下方取值。 Target language, see values below. |
source_language | string | en | 视频原语言:en zh zh-TW fr de it es ru ja。 Spoken language of the video. |
dubbing | boolean | false | 是否生成配音。 Generate a dubbed audio track. |
tts_method | string | azure_xiaochen | 配音音色,见下方取值与限制。 Dubbing voice, see values and rules below. |
target_height | string | "1080" | 下载 YouTube 视频的分辨率:"480" "720" "1080"(字符串)。 YouTube download resolution, as a string. |
demucs | boolean | true | 是否先做人声分离(Demucs)。 Separate vocals with Demucs first. |
glossary | string | — | 术语表文本,最多 250 字符。 Glossary text, at most 250 characters. |
target_language 取值 / values:English Français Deutsch Italiano Español Русский 한국어 日本語 简体中文 繁體中文 粤语
tts_method 取值 / values:
| 值 / Value | 限制 / Restriction |
|---|---|
azure_xiaochen | — |
azure_yunjian | — |
fish_ad | 仅当 target_language 为 简体中文。 Only with target_language 简体中文. |
fish_dingzhen | 仅当 target_language 为 简体中文。 Only with target_language 简体中文. |
f5_tts | 仅当 target_language 为 简体中文 或 English。 Only with target_language 简体中文 or English. |
处理过程 / What happens
- 校验 Key 和请求体。 The key and body are validated.
- 读取视频时长(最多约 20 秒)。读不到返回
422 duration_unavailable;超过 4 小时(14400 秒)返回422 invalid_request。 The video duration is read (up to about 20 s). If it cannot be read you get422 duration_unavailable; videos longer than 4 hours (14400 s) get422 invalid_request. - 检查在途任务数和余额,然后开始处理。 The in-progress limit and your balance are checked, then the task starts.
成功返回 202 Accepted,响应体是下文的任务对象,status 为 queued 或 processing。
On success the response is 202 Accepted with the task object below; status is queued or processing.
查询任务 / Get a task
GET /tasks/{id}
id 是提交时返回的 id。网页上创建的任务也能用它的 id 查询。任务不存在、已删除、不属于你,或 id 不是 UUID,都返回 404 not_found。任务在排队或处理中时,这个接口会同时刷新处理进度。
id is the id returned when you created the task. Tasks created on the website can be queried too. Unknown, deleted or someone else's tasks, and ids that are not UUIDs, return 404 not_found. While a task is queued or processing, this call also refreshes its progress.
成功返回 200 OK 和任务对象。建议每 15–30 秒轮询一次,直到 status 变成 completed、failed 或 cancelled。
On success it returns 200 OK with the task object. Poll every 15–30 seconds until status is completed, failed or cancelled.
任务对象 / Task object
POST /tasks 和 GET /tasks/{id} 返回同一种结构:
POST /tasks and GET /tasks/{id} return the same shape:
{
"id": "3f2c7a1e-5b8d-4c6f-9a0b-1d2e3f4a5b6c",
"name": "API · dQw4w9WgXcQ",
"status": "processing",
"youtube_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"video_duration_seconds": 212,
"cost_usd": 0.29468,
"step": "Translating text",
"step_index": 6,
"error": null,
"result": null,
"created_at": "2026-09-24T08:00:00.000Z",
"updated_at": "2026-09-24T08:03:12.000Z"
}| 字段 / Field | 类型 / Type | 说明 / Description |
|---|---|---|
id | string (UUID) | 任务 id。 Task id. |
name | string | 任务名称。 Task name. |
status | string | 见下表。 See the table below. |
youtube_url | string | null | 视频链接(网页上传的本地视频为 null)。 Video URL (null for local uploads made on the website). |
video_duration_seconds | number | null | 视频时长(秒)。 Video duration in seconds. |
cost_usd | number | null | 本任务费用(美元)= 时长秒数 × 0.00139。 Cost of this task in USD = duration in seconds × 0.00139. |
step | string | null | 当前处理步骤名称,处理中时才有值。 Current processing step while the task is running, otherwise usually null. |
step_index | number | null | 当前步骤序号 0–10。 Current step number, 0–10. |
error | string | null | 失败原因,仅 status 为 failed 时有值。 Failure reason, only when status is failed. |
result | object | null | 下载链接,仅 status 为 completed 时有值。 Download links, only when status is completed. |
created_at | string | 创建时间(ISO 8601,UTC)。 Creation time (ISO 8601, UTC). |
updated_at | string | 最后更新时间(ISO 8601,UTC)。 Last update time (ISO 8601, UTC). |
status
| 值 / Value | 含义 / Meaning |
|---|---|
queued | 已受理,排队等待处理。 Accepted and waiting to be processed. |
processing | 处理中,看 step / step_index 了解进度。 Being processed; see step / step_index. |
completed | 已完成,result 里有下载链接。 Done; download links are in result. |
failed | 失败,原因见 error。 Failed; see error. |
cancelled | 已停止。 Stopped. |
draft | 尚未开始:网页上的草稿,或提交时遇到 503 dispatch_failed 的任务(用同一个 Idempotency-Key 重试即可)。 Not started: a website draft, or a task whose submit returned 503 dispatch_failed (retry with the same Idempotency-Key). |
step / step_index
step_index | step |
|---|---|
| 0 | Preparing input video |
| 1 | Extracting audio using Demucs |
| 2 | Transcribing using Whisper |
| 3 | Splitting sentences using spaCy |
| 4 | Splitting sentences by meaning |
| 5 | Summarizing content |
| 6 | Translating text |
| 7 | Splitting for subtitles |
| 8 | Aligning timestamps |
| 9 | Merging subtitles |
| 10 | Uploading results |
result
任务完成后,result 包含四个可直接下载的链接:
When the task is completed, result holds four direct download links:
| 字段 / Field | 内容 / Content |
|---|---|
video | 成品视频(MP4)。 Final video (MP4). |
subtitles_zip | 全部字幕文件(ZIP)。 All subtitle files (ZIP). |
translated_srt | 译文字幕(SRT)。 Translated subtitles (SRT). |
source_srt | 原文字幕(SRT)。 Source-language subtitles (SRT). |
"result": {
"video": "https://cloud.videolingo.io/tasks/3f2c7a1e-…/output.mp4",
"subtitles_zip": "https://cloud.videolingo.io/tasks/3f2c7a1e-…/srt.zip",
"translated_srt": "https://cloud.videolingo.io/tasks/3f2c7a1e-…/trans.srt",
"source_srt": "https://cloud.videolingo.io/tasks/3f2c7a1e-…/src.srt"
}错误 / Errors
出错时响应体格式固定,error.code 适合在代码里判断,error.message 是给人看的说明。部分错误带附加字段。
Errors always use this shape. Branch on error.code; error.message is a human-readable explanation. Some errors carry extra fields.
{
"error": {
"code": "concurrency_limit",
"message": "At most 3 tasks can be queued or processing at once",
"active": 3,
"limit": 3
}
}| HTTP | error.code | 场景 / When | 附加字段 / Extra fields |
|---|---|---|---|
| 401 | invalid_api_key | 缺少 Key、格式不对或 Key 无效(例如已重新生成)。 Missing, malformed or unknown key (e.g. regenerated). | — |
| 403 | subscription_inactive | 不是专业计划,或已过期超过 1 天。 Not on Pro, or more than 1 day past the end of the paid period. | — |
| 404 | not_found | 任务不存在、已删除或不属于你。 Task does not exist, was deleted, or is not yours. | — |
| 422 | invalid_request | 请求体不是 JSON、字段不合法、不是 YouTube 链接、视频超过 4 小时、带了未知字段、Idempotency-Key 长度不对或属于已删除任务。 Body is not JSON, a field is invalid, not a YouTube URL, video over 4 hours, unknown field, bad Idempotency-Key length, or the key belongs to a deleted task. | — |
| 422 | duration_unavailable | 读取视频时长失败(视频私有、不存在或暂时无法访问)。 The video duration could not be read (private, missing or temporarily unreachable video). | — |
| 402 | insufficient_balance | 可用余额不足以支付本任务。 Available balance is lower than the cost of this task. | balance, cost(美元 / USD) |
| 429 | concurrency_limit | 在途任务已满 3 个。 Already 3 tasks queued or processing. | active, limit |
| 503 | dispatch_failed | 处理服务暂时拒绝接收。任务保留为 draft,用同一个 Idempotency-Key 重试即可。 The processing backend refused the task. It stays as draft; retry with the same Idempotency-Key. | task_id |
| 500 | internal_error | 其它服务器错误,请稍后重试。 Unexpected server error; retry later. | — |
遇到 402 或 429 时不会创建新任务,也不会扣费;稍后可以用同一个 Idempotency-Key 重新提交。
A 402 or 429 creates no new task and charges nothing; you can resubmit later with the same Idempotency-Key.
限制与计费 / Limits and billing
- 并发 / Concurrency:同一账户最多 3 个在途任务(
queued+processing),网页上提交的任务也算在内。超出返回429 concurrency_limit,等已有任务完成后再提交。 At most 3 tasks queued or processing per account, including tasks started on the website. Over the limit you get429 concurrency_limit; wait for a task to finish. - 时长 / Duration:单个视频最长 4 小时(14400 秒)。 Videos can be at most 4 hours (14400 seconds) long.
- 计费 / Billing:与网页提交相同,按视频时长计费,每秒 0.00139 美元(约每小时 5 美元),从账户余额中扣除;开始处理时按
cost_usd预留。余额不足返回402 insufficient_balance。 Same as the website: billed by video duration at USD 0.00139 per second (about USD 5 per hour), from your account balance;cost_usdis reserved when processing starts. Without enough balance you get402 insufficient_balance. - 暂无按分钟的速率限制,但请合理轮询(15–30 秒一次)。 There is no per-minute rate limit, but please poll reasonably (every 15–30 seconds).
完整示例 / Full example
下面的脚本提交一个任务,然后每 30 秒查询一次,直到结束。需要 curl 和 jq。
This script submits a task, then checks it every 30 seconds until it finishes. It needs curl and jq.
#!/usr/bin/env bash
set -euo pipefail
# 从 https://videolingo.io/zh/dashboard/account/api 复制 Key
# Copy your key from https://videolingo.io/en/dashboard/account/api
: "${VL_API_KEY:?Set VL_API_KEY first}"
API=https://videolingo.io/api/v1
# 1. 提交 / Submit
RESP=$(curl -sS -X POST "$API/tasks" \
-H "Authorization: Bearer $VL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: my-video-0001" \
-d '{
"youtube_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"target_language": "简体中文",
"source_language": "en",
"dubbing": false
}')
TASK_ID=$(echo "$RESP" | jq -r '.id // empty')
if [ -z "$TASK_ID" ]; then
echo "Submit failed: $RESP" >&2
exit 1
fi
echo "Task: $TASK_ID"
# 2. 轮询 / Poll
while true; do
RESP=$(curl -sS "$API/tasks/$TASK_ID" \
-H "Authorization: Bearer $VL_API_KEY")
STATUS=$(echo "$RESP" | jq -r '.status')
echo "$STATUS $(echo "$RESP" | jq -r '.step // ""')"
case "$STATUS" in
completed) echo "$RESP" | jq '.result'; break ;;
failed|cancelled) echo "$RESP" | jq '.error'; exit 1 ;;
esac
sleep 30
done网络超时后重试时,保持同一个 Idempotency-Key,不会重复创建任务。
When retrying after a network timeout, keep the same Idempotency-Key so no duplicate task is created.
Key 轮换 / Rotating your key
- 在 工作台 → 账户 → API 点「重新生成 Key」。旧 Key 立即失效(之后返回
401),正在处理的任务不受影响。拿到新 Key 后记得更新所有用到它的地方。 Click "Regenerate Key" on Dashboard → Account → API. The old key stops working immediately (it gets401from then on); tasks already running are not affected. Update every place that uses the key. - 怀疑 Key 泄露时请立即重新生成。 Regenerate right away if you think the key has leaked.
- 专业计划过期后 Key 会返回
403;续费后原来的 Key 自动恢复,无需更换。 When Pro lapses the key returns403; renew and the same key works again, no change needed. - 每个账户同一时间只有一把 Key。 Each account has one key at a time.