创想去字幕 - 开放 API 文档

面向 API-Key 用户的视频去字幕开放接口说明

目录

认证方式

所有开放接口均需在请求头中携带 X-User-NoX-API-Key 进行认证。

同时兼容 Authorization: Bearer sk-cxcl-xxx 方式传递 API-Key。

请求头示例

POST /open/v1/vsr/submitTask HTTP/1.1
Host: vtool.tookit.cn
Content-Type: application/json
X-User-No: your_user_no
X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx
注意:每个用户同时只能拥有一个有效的 API-Key。重新生成后,旧 Key 立即失效。

认证失败响应格式

认证失败时,HTTP 状态码为 401,响应体格式与标准格式不同(使用 message 而非 msg,无 data 字段):

{
  "code": 401,
  "message": "API-Key 无效或已撤销"
}

基础信息

说明
协议HTTPS
Base URLhttps://vtool.tookit.cn(生产环境)
请求格式JSON(上传文件接口为 multipart/form-data)
响应格式统一包装:{ "code": 0, "msg": "...", "data": {...} }
字符编码UTF-8
code0 表示成功,非 0 表示失败,具体含义参考「错误码说明」。

全局说明

任务有效期

注意:建议在任务完成后立即下载结果视频,避免链接过期。如需长期保存,请将结果下载至自有存储服务。

并发与限流

积分退还

任务提交时即扣除积分。若任务处理失败(含提交失败和处理失败),已扣除的积分将自动退还至用户账户,无需人工介入。

视频限制

提交去字幕任务前,请确保视频满足以下条件:

限制项规则
格式MP4 / MOV
文件大小≤ 1GB
分辨率长边 ≤ 1920(即 ≤ 1080P)
时长≤ 10 分钟(600 秒)

服务端会自动探测视频的宽高和时长,无需客户端传入 durationwidthheight 参数;探测失败将返回错误。

计费规则

计费方式

积分消耗

分辨率档位积分倍率示例
width × height ≤ 921600 像素
(约 720P 及以下,如 1280×720)
1 积分/秒720P 30 秒 = ceil(30 × 1.0) = 30 积分
width × height > 921600 像素
(高于 720P,最高 1080P,如 1920×1080)
1.3 积分/秒1080P 30 秒 = ceil(30 × 1.3) = 39 积分

实际扣费公式:积分 = ceil(视频时长 × 倍率)(向上取整)

API-Key 调用仅从 付费积分purchasedCredits)中扣除。

积分套餐

积分可通过 Web 端充值页面购买,支持多种套餐。点击下方链接前往充值:

前往充值页面 →

说明:充值需登录创想视频去水印字幕账号。充值后积分即时到账,可通过 queryCredits 接口查询余额。

视频解析

GET /open/v1/parseVd?url=...

解析短视频分享链接,返回视频地址。

服务协议

使用视频解析接口即代表您同意以下视频解析服务协议:

  1. 作品归平台及作者所有,创想视频去水印字幕平台作为提供技术服务的中立工具,不存储任何作品,提供的功能仅限帮助用户提取视频自行学习、观看,降低视频、图片浏览障碍。
  2. 提示:用户请合法使用,若用户滥用该功能实施侵权或违法行为,用户自行承担由此产生的法律责任。平台倡导与用户共同营造良好的网络环境!

计费规则

请求参数

字段名类型必填说明
urlstring短视频分享链接(支持文本中包含链接,服务端会自动提取)

URL 编码说明

由于分享链接通常包含特殊字符(如 &=?、中文文案等),请求前必须对 url 参数值进行 URL 编码,否则可能导致参数解析失败或链接被截断。

响应字段

成功时 data 字段包含以下主要字段:

字段名类型说明
titlestring视频/图集标题或描述(可能为空)
cover_urlstring视频封面地址(可能为空)
video_urlstring无水印视频播放地址(视频类型时存在)
imagesarray[string]图集图片地址列表(图集类型时存在)
liveImagesarray[object]实况照片列表(实况类型时存在)
authorobject作者信息(可能为空),含 uidnameavatar

实况照片字段说明(目前只支持特定平台的实况图解析)

当作品类型为实况照片时,liveImages 数组中的每个对象包含以下字段:

字段名类型说明
imageUrlstring实况照片的封面图片地址
videoUrlstring实况照片的视频片段地址

成功响应示例

{
  "code": 0,
  "msg": "解析成功",
  "data": {
    "title": "示例视频标题",
    "cover_url": "https://example.com/cover.jpg",
    "video_url": "https://example.com/video.mp4",
    "author": {
      "uid": "123456",
      "name": "作者名",
      "avatar": "https://example.com/avatar.jpg"
    }
  }
}

上传视频文件 可选

POST /open/v1/vsr/uploadVideo

上传视频文件并获取视频 URL 和封面 URL。适用于无自有存储服务的场景。

建议用户自备文件上传和存储服务,本接口为便捷方案。对接方也可自行将视频上传至自有存储(COS 或 VOD 均可),将视频 URL 直接传入 submitTask

请求格式

Content-Type: multipart/form-data(区别于其他接口的 application/json

请求参数

字段名类型必填说明
filefile视频文件,最大 1GB,支持 mp4、mov 格式
userNoapiKey 通过请求头 X-User-No / X-API-Key 传递,无需放在表单中。

业务限制

限制项规则
文件大小上限1GB
支持的视频格式mp4、mov
分辨率上限1920 × 1080(约 2,073,600 像素)
时长上限600 秒(10 分钟)
位深上限8bit(不支持 10bit 及以上)
HDR 格式不支持 HDR 格式视频

请求示例

curl -X POST https://vtool.tookit.cn/open/v1/vsr/uploadVideo \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@/path/to/video.mp4"

响应字段

字段名类型说明
codenumber状态码,200 表示成功
messagestring提示信息
videoUrlstring视频访问 URL(有效期 2 天)
coverUrlstring封面图访问 URL(有效期 24 小时)
widthnumber视频宽度(像素)
heightnumber视频高度(像素)
durationnumber视频时长(秒,向上取整)

响应示例

{
  "code": 200,
  "msg": "上传成功",
  "data": {
    "videoUrl": "https://video.tookit.cn/file-xxxxxxxx.mp4",
    "coverUrl": "https://video.tookit.cn/img-xxxxxxxx.jpg",
    "width": 1920,
    "height": 1080,
    "duration": 59
  }
}

接口特有错误

HTTP 状态码含义说明
401鉴权失败userNo 或 apiKey 不正确
400参数不合法文件为空、格式不支持、大小超过 1GB、分辨率超过 1080P、时长超过 10 分钟、位深超过 8bit、HDR 格式、无法解析视频文件
500服务内部异常文件保存或封面截取失败,建议稍后重试

提交单任务

POST /open/v1/vsr/submitTask

提交一个视频去字幕任务,任务提交成功后将立即扣除对应积分。

请求参数

字段类型必填说明
videoUrlstring待处理视频的可下载 URL,需保证服务端可直接访问
fileNamestring文件名(含扩展名),用于结果文件命名
fileSizestring文件大小,例如 "15.2MB"
durationnumber视频时长(秒),不传则由服务端自动探测,传入值也会被服务端探测结果覆盖
widthint视频宽度(像素),不传则由服务端自动探测,传入值也会被服务端探测结果覆盖
heightint视频高度(像素),不传则由服务端自动探测,传入值也会被服务端探测结果覆盖
modestring去字幕模式:"1" 通用 / "2" 裁剪 / "3" AI;默认 "1"
fixedModebool是否固定模式处理,默认 false
isMutebool处理后是否静音,默认 false
regionsarray框选区域数组,最多 5 个;裁剪模式(mode=2)和 AI 模式(mode=3)下必填,通用模式(mode=1)可省略
protectAreaarray保护区域 [ymin, ymax, xmin, xmax]
callbackUrlstringWebhook 回调地址,以 http://https:// 开头,长度 ≤ 2048。传入后任务完成或失败时系统主动 POST 通知该地址,无需轮询
memberTagstring团队成员标识,用于区分同一 API-Key 下不同成员提交的任务,长度 ≤ 64
coverUrlstring封面图 URL,由 uploadVideo 接口返回的 coverUrl 传入

regions 区域对象

字段类型说明
lint左上角 x 坐标
tint左上角 y 坐标
wint区域宽度
hint区域高度

Webhook 回调通知

当传入 callbackUrl 参数时,任务完成后系统会向该地址发送 POST 请求,Content-Type 为 application/json,请求体格式如下:

{
  "taskId": "vsr_xxxxxxxxxxxx",
  "status": "completed",
  "videoUrl": "https://cdn.tookit.cn/result/xxx.mp4",
  "originUrl": "https://example.com/video.mp4",
  "coverUrl": "https://video.tookit.cn/img-xxxxxxxx.jpg",
  "duration": "0分钟58秒",
  "resolution": "1920x1080"
}
字段类型说明
taskIdstring任务 ID
statusstring任务状态:"completed""failed"
videoUrlstring处理结果视频 URL(仅 completed 时有值)
originUrlstring原始视频 URL
coverUrlstring封面图 URL
durationstring视频时长
resolutionstring视频分辨率
注意:Webhook 通知为异步发送,最多重试 5 次,采用指数退避策略。每次请求超时时间为 10 秒。建议回调接口收到请求后立即返回 2xx 状态码,耗时操作异步处理。若回调地址格式不合法或网络不可达,系统将静默忽略,仅记录日志。

重试策略

第 N 次尝试12345
延迟0s(首次)2s4s8s16s

5 次全部失败后不再重试,仅记录错误日志。建议回调方做好幂等处理,因为 5 次重试可能发送重复请求。

请求示例

{
  "videoUrl": "https://example.com/video.mp4",
  "fileName": "video.mp4",
  "mode": "1",
  "isMute": false,
  "regions": [
    { "l": 100, "t": 900, "w": 1720, "h": 120 }
  ],
  "callbackUrl": "https://your-server.com/webhook/vsr"
}

说明:durationwidthheight 无需传入,服务端会自动探测视频元信息。

响应示例(720P 30 秒视频)

{
  "code": 0,
  "msg": "任务提交成功",
  "data": {
    "taskId": "vsr_xxxxxxxxxxxx",
    "status": "processing",
    "duration": 30,
    "pointCost": 30
  }
}

查询任务详情

GET /open/v1/vsr/taskDetail/:taskId

根据任务 ID 查询去字幕任务的处理状态与结果。

路径参数

字段类型说明
taskIdstring提交任务时返回的任务 ID

响应示例

{
  "code": 0,
  "msg": "成功",
  "data": {
    "taskId": "vsr_xxxxxxxxxxxx",
    "status": "completed",
    "videoUrl": "https://cdn.tookit.cn/result/xxx.mp4",
    "originUrl": "https://example.com/video.mp4",
    "coverUrl": "https://video.tookit.cn/img-xxxxxxxx.jpg",
    "duration": "0分钟58秒",
    "resolution": "1920x1080",
    "createdAt": "2026-06-24 10:00:00",
    "completedAt": "2026-06-24 10:02:30"
  }
}

status 取值

含义说明
processing排队中 / 处理中任务已提交,正在等待处理或正在处理中
completed已完成任务处理成功,结果视频可通过 videoUrl 下载
failed处理失败任务处理失败,已扣除积分自动退还
blocked处理失败(拦截)视频内容不符合处理要求,被系统拦截,已扣除积分自动退还
任务完成前建议采用轮询方式查询,间隔建议 ≥ 3 秒。也支持传入 callbackUrl 参数,任务完成或失败时系统主动 POST 通知,无需轮询。

查询任务列表

GET /open/v1/vsr/taskList

查询当前 API-Key 所属用户的去字幕任务列表。

查询参数

字段类型默认值说明
pageint1页码,从 1 开始
pageSizeint20每页数量,最大 100
memberTagstring按团队成员标识筛选,仅返回该成员提交的任务

响应示例

{
  "code": 0,
  "msg": "成功",
  "data": {
    "total": 128,
    "page": 1,
    "pageSize": 20,
    "items": [
      {
        "taskId": "vsr_xxxxxxxxxxxx",
        "status": "completed",
        "videoUrl": "https://cdn.tookit.cn/result/xxx.mp4",
        "originUrl": "https://example.com/video.mp4",
        "coverUrl": "https://video.tookit.cn/img-xxxxxxxx.jpg",
        "duration": "0分钟58秒",
        "fileSize": "15.2MB",
        "resolution": "1920x1080",
        "memberTag": "member-a",
        "createdAt": "2026-06-24 10:00:00"
      }
    ]
  }
}

查询积分余额

GET /open/v1/vsr/queryCredits

查询当前 API-Key 所属用户的积分余额。

响应示例

{
  "code": 0,
  "msg": "成功",
  "data": {
    "totalCredits": 5000,
    "freeCredits": 200,
    "purchasedCredits": 4800,
    "userLevel": 1
  }
}
说明:API-Key 调用仅从付费积分(purchasedCredits)中扣除,不消耗免费积分。若付费积分不足,任务提交将返回积分不足错误(code=111002)。

团队去字幕

团队去字幕功能允许多人共用同一个 API-Key 的积分额度,同时按成员标识(memberTag)区分每个成员提交的任务,便于团队管理员进行用量统计与成本分摊。

使用流程

  1. 管理员生成 API-Key:在「API 开放」页面生成 API-Key,并将 userNoapiKey 分发给团队成员。
  2. 成员配置凭证:每位成员在客户端输入 userNoapiKey 以及自定义的 memberTag(用于标识自己)。
  3. 成员提交任务:成员提交去字幕任务时,请求体中携带 memberTag,系统会将该任务归属到对应成员。
  4. 管理员查看统计:管理员通过团队概览、成员统计、使用趋势接口查看团队整体及每个成员的用量。

数据隔离说明

团队概览统计

GET /open/v1/vsr/teamOverview

查询团队去字幕整体数据,包括总任务数、团队成员数、近 7 天任务数、近 7 天积分消耗及剩余积分。

响应字段

字段类型说明
totalTasksint64团队累计去字幕任务总数
totalMembersint64团队累计成员数(按 memberTag 去重)
weekTasksint64近 7 天任务数(含当天)
weekPointsint64近 7 天累计积分消耗
remainPointsint64当前账户剩余积分(免费 + 付费)
weekStartDatestring近 7 天统计起始日期,格式 2006-01-02

响应示例

{
  "code": 0,
  "msg": "成功",
  "data": {
    "totalTasks": 128,
    "totalMembers": 5,
    "weekTasks": 32,
    "weekPoints": 1840,
    "remainPoints": 5000,
    "weekStartDate": "2026-06-21"
  }
}

团队成员统计

GET /open/v1/vsr/teamMemberStats

查询近 7 天每个团队成员的任务数与积分消耗,按 memberTag 聚合。

响应字段

字段类型说明
itemsarray成员统计列表
weekStartDatestring近 7 天统计起始日期,格式 2006-01-02

items 成员对象

字段类型说明
memberTagstring团队成员标识
taskCountint64近 7 天任务数
pointCostint64近 7 天积分消耗

响应示例

{
  "code": 0,
  "msg": "成功",
  "data": {
    "items": [
      { "memberTag": "member-a", "taskCount": 12, "pointCost": 720 },
      { "memberTag": "member-b", "taskCount": 8, "pointCost": 480 }
    ],
    "weekStartDate": "2026-06-21"
  }
}

团队使用趋势

GET /open/v1/vsr/teamUsageStats

按日期范围查询团队每日任务数与积分消耗,默认返回最近 7 天数据。

查询参数

字段类型默认值说明
startDatestring7 天前开始日期,格式 2006-01-02
endDatestring今天结束日期,格式 2006-01-02

响应字段

字段类型说明
itemsarray每日统计列表
startDatestring实际查询开始日期
endDatestring实际查询结束日期

items 日统计对象

字段类型说明
datestring日期,格式 2006-01-02
taskCountint64当日任务数
pointCostint64当日积分消耗

响应示例

{
  "code": 0,
  "msg": "成功",
  "data": {
    "items": [
      { "date": "2026-06-21", "taskCount": 2, "pointCost": 120 },
      { "date": "2026-06-22", "taskCount": 5, "pointCost": 310 },
      { "date": "2026-06-23", "taskCount": 3, "pointCost": 180 }
    ],
    "startDate": "2026-06-21",
    "endDate": "2026-06-27"
  }
}

调用示例

cURL

视频解析

curl -X GET "https://vtool.tookit.cn/open/v1/parseVd?url=https%3A%2F%2Fv.douyin.com%2Fxxxxxxxx" \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx"

1. 上传视频

curl -X POST https://vtool.tookit.cn/open/v1/vsr/uploadVideo \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@/path/to/video.mp4"

2. 提交去字幕任务

curl -X POST https://vtool.tookit.cn/open/v1/vsr/submitTask \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "videoUrl": "https://video.tookit.cn/file-xxxxxxxx.mp4",
    "fileName": "video.mp4",
    "mode": "1",
    "regions": [
      { "l": 100, "t": 900, "w": 1720, "h": 120 }
    ],
    "callbackUrl": "https://your-server.com/webhook/vsr"
  }'

3. 查询任务详情

curl -X GET "https://vtool.tookit.cn/open/v1/vsr/taskDetail/vsr_xxxxxxxxxxxx" \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx"

4. 查询任务列表

curl -X GET "https://vtool.tookit.cn/open/v1/vsr/taskList?page=1&pageSize=20" \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx"

5. 查询积分余额

curl -X GET https://vtool.tookit.cn/open/v1/vsr/queryCredits \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx"

7. 查询团队概览(团队去字幕)

curl -X GET https://vtool.tookit.cn/open/v1/vsr/teamOverview \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx"

8. 查询团队成员统计(团队去字幕)

curl -X GET https://vtool.tookit.cn/open/v1/vsr/teamMemberStats \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx"

9. 查询团队使用趋势(团队去字幕)

curl -X GET "https://vtool.tookit.cn/open/v1/vsr/teamUsageStats?startDate=2026-06-21&endDate=2026-06-27" \
  -H "X-User-No: your_user_no" \
  -H "X-API-Key: sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx"

Python

import urllib.parse

import requests

BASE_URL = "https://vtool.tookit.cn"
HEADERS = {
    "X-User-No": "your_user_no",
    "X-API-Key": "sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx",
}

# 视频解析(必须对 url 进行 URL 编码)
share_url = "https://v.douyin.com/xxxxxxxx"
encoded_url = urllib.parse.quote(share_url, safe="")
parse_resp = requests.get(
    f"{BASE_URL}/open/v1/parseVd?url={encoded_url}",
    headers=HEADERS,
)
parse_data = parse_resp.json()["data"]
print("视频标题:", parse_data.get("title"))
print("视频地址:", parse_data.get("video_url"))
print("图集地址:", parse_data.get("images", []))

# 1. 上传视频
with open("video.mp4", "rb") as f:
    resp = requests.post(
        f"{BASE_URL}/open/v1/vsr/uploadVideo",
        headers=HEADERS,
        files={"file": f},
    )
video_url = resp.json()["data"]["videoUrl"]

# 2. 提交去字幕任务
resp = requests.post(
    f"{BASE_URL}/open/v1/vsr/submitTask",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "videoUrl": video_url,
        "fileName": "video.mp4",
        "mode": "1",
        "regions": [{"l": 100, "t": 900, "w": 1720, "h": 120}],
        "callbackUrl": "https://your-server.com/webhook/vsr",  # 可选:任务完成后主动通知
    },
)
task_id = resp.json()["data"]["taskId"]

# 3. 查询任务状态(二选一)
import time
while True:
    resp = requests.get(
        f"{BASE_URL}/open/v1/vsr/taskDetail/{task_id}",
        headers=HEADERS,
    )
    status = resp.json()["data"]["status"]
    if status in ("completed", "failed"):
        break
    time.sleep(3)

print("任务状态:", status)
if status == "completed":
    print("结果视频:", resp.json()["data"]["videoUrl"])

# 4. 查询任务列表
task_list = requests.get(
    f"{BASE_URL}/open/v1/vsr/taskList",
    headers=HEADERS,
    params={"page": 1, "pageSize": 20},
).json()["data"]
print("任务列表:", task_list)

# 5. 查询积分余额
credits = requests.get(
    f"{BASE_URL}/open/v1/vsr/queryCredits", headers=HEADERS
).json()["data"]
print("付费积分:", credits["purchasedCredits"])

# 6. 查询团队统计(团队去字幕)
team_overview = requests.get(
    f"{BASE_URL}/open/v1/vsr/teamOverview", headers=HEADERS
).json()["data"]
print("团队总任务数:", team_overview["totalTasks"])

member_stats = requests.get(
    f"{BASE_URL}/open/v1/vsr/teamMemberStats", headers=HEADERS
).json()["data"]["items"]
print("成员统计:", member_stats)

usage_stats = requests.get(
    f"{BASE_URL}/open/v1/vsr/teamUsageStats",
    headers=HEADERS,
    params={"startDate": "2026-06-21", "endDate": "2026-06-27"},
).json()["data"]["items"]
print("使用趋势:", usage_stats)

Node.js

const axios = require("axios");
const FormData = require("form-data");
const fs = require("fs");

const BASE_URL = "https://vtool.tookit.cn";
const headers = {
  "X-User-No": "your_user_no",
  "X-API-Key": "sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx",
};

// 视频解析
const parseResp = await axios.get(
  `${BASE_URL}/open/v1/parseVd`,
  {
    headers,
    params: { url: "https://v.douyin.com/xxxxxxxx" },
  },
);
const parseData = parseResp.data.data;
console.log("视频标题:", parseData.title);
console.log("视频地址:", parseData.video_url);
console.log("图集地址:", parseData.images || []);

// 1. 上传视频
const form = new FormData();
form.append("file", fs.createReadStream("video.mp4"));
const uploadResp = await axios.post(`${BASE_URL}/open/v1/vsr/uploadVideo`, form, {
  headers: { ...headers, ...form.getHeaders() },
});
const videoUrl = uploadResp.data.data.videoUrl;

// 2. 提交去字幕任务
const taskResp = await axios.post(
  `${BASE_URL}/open/v1/vsr/submitTask`,
  {
    videoUrl,
    fileName: "video.mp4",
    mode: "1",
    regions: [{ l: 100, t: 900, w: 1720, h: 120 }],
    callbackUrl: "https://your-server.com/webhook/vsr",  // 可选:任务完成后主动通知
  },
  { headers: { ...headers, "Content-Type": "application/json" } },
);
const taskId = taskResp.data.data.taskId;

// 3. 轮询任务状态
const delay = (ms) => new Promise((r) => setTimeout(r, ms));
let status = "processing";
while (status === "processing") {
  await delay(3000);
  const detailResp = await axios.get(
    `${BASE_URL}/open/v1/vsr/taskDetail/${taskId}`,
    { headers },
  );
  status = detailResp.data.data.status;
}

console.log("任务状态:", status);

// 4. 查询任务列表
const taskListResp = await axios.get(
  `${BASE_URL}/open/v1/vsr/taskList`,
  { headers, params: { page: 1, pageSize: 20 } },
);
console.log("任务列表:", taskListResp.data.data);

// 5. 查询积分余额
const creditsResp = await axios.get(
  `${BASE_URL}/open/v1/vsr/queryCredits`,
  { headers },
);
console.log("付费积分:", creditsResp.data.data.purchasedCredits);

// 6. 查询团队统计(团队去字幕)
const teamOverviewResp = await axios.get(
  `${BASE_URL}/open/v1/vsr/teamOverview`,
  { headers },
);
console.log("团队总任务数:", teamOverviewResp.data.data.totalTasks);

const memberStatsResp = await axios.get(
  `${BASE_URL}/open/v1/vsr/teamMemberStats`,
  { headers },
);
console.log("成员统计:", memberStatsResp.data.data.items);

const usageStatsResp = await axios.get(
  `${BASE_URL}/open/v1/vsr/teamUsageStats`,
  { headers, params: { startDate: "2026-06-21", endDate: "2026-06-27" } },
);
console.log("使用趋势:", usageStatsResp.data.data.items);

PHP

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

$baseUrl = 'https://vtool.tookit.cn';
$headers = [
    'X-User-No' => 'your_user_no',
    'X-API-Key' => 'sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx',
];
$client = new Client(['base_uri' => $baseUrl, 'headers' => $headers, 'verify' => false]);

// 视频解析(必须对 url 进行 urlencode)
$shareUrl = 'https://v.douyin.com/xxxxxxxx';
$parseResp = $client->get('/open/v1/parseVd', ['query' => ['url' => urlencode($shareUrl)]]);
$parseData = json_decode($parseResp->getBody(), true)['data'];
echo '视频标题: ' . ($parseData['title'] ?? '') . "\n";
echo '视频地址: ' . ($parseData['video_url'] ?? '') . "\n";

// 1. 上传视频
$videoPath = '/path/to/video.mp4';
$uploadResp = $client->post('/open/v1/vsr/uploadVideo', [
    'multipart' => [
        ['name' => 'file', 'contents' => fopen($videoPath, 'rb'), 'filename' => basename($videoPath)],
    ],
]);
$videoUrl = json_decode($uploadResp->getBody(), true)['data']['videoUrl'];

// 2. 提交去字幕任务
$submitResp = $client->post('/open/v1/vsr/submitTask', [
    'json' => [
        'videoUrl' => $videoUrl,
        'fileName' => 'video.mp4',
        'mode' => '1',
        'regions' => [['l' => 100, 't' => 900, 'w' => 1720, 'h' => 120]],
        'callbackUrl' => 'https://your-server.com/webhook/vsr',
    ],
]);
$taskId = json_decode($submitResp->getBody(), true)['data']['taskId'];

// 3. 查询任务详情
$detailResp = $client->get("/open/v1/vsr/taskDetail/{$taskId}");
$status = json_decode($detailResp->getBody(), true)['data']['status'];
echo '任务状态: ' . $status . "\n";

// 4. 查询任务列表
$taskListResp = $client->get('/open/v1/vsr/taskList', ['query' => ['page' => 1, 'pageSize' => 20]]);
echo '任务列表: ' . $taskListResp->getBody() . "\n";

// 5. 查询积分余额
$creditsResp = $client->get('/open/v1/vsr/queryCredits');
echo '积分余额: ' . $creditsResp->getBody() . "\n";

// 6. 查询团队统计
$teamOverviewResp = $client->get('/open/v1/vsr/teamOverview');
echo '团队概览: ' . $teamOverviewResp->getBody() . "\n";

$memberStatsResp = $client->get('/open/v1/vsr/teamMemberStats');
echo '成员统计: ' . $memberStatsResp->getBody() . "\n";

$usageStatsResp = $client->get('/open/v1/vsr/teamUsageStats', [
    'query' => ['startDate' => '2026-06-21', 'endDate' => '2026-06-27'],
]);
echo '使用趋势: ' . $usageStatsResp->getBody() . "\n";
?>

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "net/url"
    "os"
    "time"
)

const (
    baseURL = "https://vtool.tookit.cn"
    userNo  = "your_user_no"
    apiKey  = "sk-cxcl-xxxxxxxxxxxxxxxxxxxxxxxx"
)

func newRequest(method, path string, body io.Reader) (*http.Request, error) {
    req, err := http.NewRequest(method, baseURL+path, body)
    if err != nil {
        return nil, err
    }
    req.Header.Set("X-User-No", userNo)
    req.Header.Set("X-API-Key", apiKey)
    return req, nil
}

func doRequest(req *http.Request) map[string]interface{} {
    client := &http.Client{Timeout: 30 * time.Second}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    var result map[string]interface{}
    if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
        panic(err)
    }
    return result
}

func main() {
    // 视频解析(必须对 url 进行 QueryEscape)
    shareUrl := "https://v.douyin.com/xxxxxxxx"
    req, _ := newRequest("GET", "/open/v1/parseVd?url="+url.QueryEscape(shareUrl), nil)
    parseData := doRequest(req)["data"].(map[string]interface{})
    fmt.Println("视频标题:", parseData["title"])
    fmt.Println("视频地址:", parseData["video_url"])

    // 1. 上传视频
    videoPath := "/path/to/video.mp4"
    file, _ := os.Open(videoPath)
    defer file.Close()
    var b bytes.Buffer
    writer := multipart.NewWriter(&b)
    part, _ := writer.CreateFormFile("file", videoPath)
    io.Copy(part, file)
    writer.Close()
    uploadReq, _ := newRequest("POST", "/open/v1/vsr/uploadVideo", &b)
    uploadReq.Header.Set("Content-Type", writer.FormDataContentType())
    videoUrl := doRequest(uploadReq)["data"].(map[string]interface{})["videoUrl"].(string)

    // 2. 提交去字幕任务
    submitBody, _ := json.Marshal(map[string]interface{}{
        "videoUrl":    videoUrl,
        "fileName":    "video.mp4",
        "mode":        "1",
        "regions":     []map[string]int{{"l": 100, "t": 900, "w": 1720, "h": 120}},
        "callbackUrl": "https://your-server.com/webhook/vsr",
    })
    submitReq, _ := newRequest("POST", "/open/v1/vsr/submitTask", bytes.NewReader(submitBody))
    submitReq.Header.Set("Content-Type", "application/json")
    taskId := doRequest(submitReq)["data"].(map[string]interface{})["taskId"].(string)

    // 3. 查询任务详情
    detailReq, _ := newRequest("GET", "/open/v1/vsr/taskDetail/"+taskId, nil)
    status := doRequest(detailReq)["data"].(map[string]interface{})["status"].(string)
    fmt.Println("任务状态:", status)

    // 4. 查询任务列表
    listReq, _ := newRequest("GET", "/open/v1/vsr/taskList?page=1&pageSize=20", nil)
    fmt.Println("任务列表:", doRequest(listReq)["data"])

    // 5. 查询积分余额
    creditsReq, _ := newRequest("GET", "/open/v1/vsr/queryCredits", nil)
    fmt.Println("积分余额:", doRequest(creditsReq)["data"])

    // 6. 查询团队统计
    overviewReq, _ := newRequest("GET", "/open/v1/vsr/teamOverview", nil)
    fmt.Println("团队概览:", doRequest(overviewReq)["data"])

    memberReq, _ := newRequest("GET", "/open/v1/vsr/teamMemberStats", nil)
    fmt.Println("成员统计:", doRequest(memberReq)["data"])

    usageReq, _ := newRequest("GET", "/open/v1/vsr/teamUsageStats?startDate=2026-06-21&endDate=2026-06-27", nil)
    fmt.Println("使用趋势:", doRequest(usageReq)["data"])
}

错误码说明

HTTP 状态码含义处理建议
200请求成功(部分业务错误也返回 200,需判断 code 字段)检查响应体 code 是否为 0
400请求参数错误或业务校验失败检查请求参数,参考响应体 msg
401认证失败(缺少参数、Key 无效或已撤销、userNo 不匹配)检查 X-User-No 与 X-API-Key 是否正确,必要时重新生成
403无权访问确认任务属于当前用户
429请求过于频繁降低请求频率
500/502/503服务异常稍后重试

业务错误码(响应体 code 字段)

错误码HTTP 状态码含义
0200成功
111002200付费积分不足(注意:HTTP 状态码为 200,需判断 code 字段)
112602400视频去字幕失败(任务提交异常)
112608400视频尺寸超出 1080P 限制(长边 > 1920)
112610400视频时长超出 10 分钟限制
112611400同一用户最多同时提交 5 个去字幕任务
100101500数据库错误
100401500视频信息获取失败(远程探测失败)
遇到具体业务错误时,优先以响应体中的 msg 为准。