curl --request POST 'https://api.voicecheap.ai/v1/actions/captions_transcribe' \
--header "x-api-key: $VOICECHEAP_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"fileKey":"uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav","fileName":"interview.wav","keyterms":["VoiceCheap"],"requestId":"13579bdf-2468-4ace-8bdf-0123456789ab"}'
const input = {
fileKey: 'uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav',
fileName: 'interview.wav',
keyterms: ['VoiceCheap'],
requestId: '13579bdf-2468-4ace-8bdf-0123456789ab',
};
const response = await fetch('https://api.voicecheap.ai/v1/actions/captions_transcribe', {
method: 'POST',
headers: {
'x-api-key': process.env.VOICECHEAP_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
});
const body = await response.json();
if (!response.ok) throw new Error(body.code + ': ' + body.message);
console.log(body);
import os
import requests
response = requests.post(
"https://api.voicecheap.ai/v1/actions/captions_transcribe",
headers={"x-api-key": os.environ["VOICECHEAP_API_KEY"]},
json={"fileKey": "uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav", "fileName": "interview.wav", "keyterms": ["VoiceCheap"], "requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"},
timeout=120,
)
body = response.json()
if not response.ok:
raise RuntimeError(f"{body.get('code')}: {body.get('message')}")
print(body)
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"status": "running",
"pollAction": "action_request_get",
"pollAfterSeconds": 5
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"resultId": "b3caf96f-5f2a-4619-832c-a12c0d57f78b",
"operation": "captions_transcribe",
"createdAt": 1792152000000,
"fileName": "voicecheap-captions_transcribe-b3caf96f-5f2a-4619-832c-a12c0d57f78b.json",
"byteLength": 190,
"contentType": "application/json; charset=utf-8",
"status": "completed",
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"getAction": "subtitles_result_get",
"downloadAction": "subtitles_result_download",
"listAction": "subtitles_result_list"
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"operation": "captions_transcribe",
"createdAt": 1792144800000,
"updatedAt": 1792144820000,
"status": "running",
"pollAfterSeconds": 5
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"operation": "captions_transcribe",
"createdAt": 1792144800000,
"updatedAt": 1792144820000,
"status": "completed",
"resultStored": false,
"message": "The action completed. Retrieve its output from the corresponding history or resource action."
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
字幕
创建带时间戳的字幕词语
将上传的音轨转写为带时间戳的词语,用于字幕编辑。此操作不提供动画视频渲染或本地浏览器编辑会话。返回精简的已保存结果引用;使用其中的 getAction 或 downloadAction 获取完整输出。
POST
/
v1
/
actions
/
captions_transcribe
curl --request POST 'https://api.voicecheap.ai/v1/actions/captions_transcribe' \
--header "x-api-key: $VOICECHEAP_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"fileKey":"uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav","fileName":"interview.wav","keyterms":["VoiceCheap"],"requestId":"13579bdf-2468-4ace-8bdf-0123456789ab"}'
const input = {
fileKey: 'uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav',
fileName: 'interview.wav',
keyterms: ['VoiceCheap'],
requestId: '13579bdf-2468-4ace-8bdf-0123456789ab',
};
const response = await fetch('https://api.voicecheap.ai/v1/actions/captions_transcribe', {
method: 'POST',
headers: {
'x-api-key': process.env.VOICECHEAP_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
});
const body = await response.json();
if (!response.ok) throw new Error(body.code + ': ' + body.message);
console.log(body);
import os
import requests
response = requests.post(
"https://api.voicecheap.ai/v1/actions/captions_transcribe",
headers={"x-api-key": os.environ["VOICECHEAP_API_KEY"]},
json={"fileKey": "uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav", "fileName": "interview.wav", "keyterms": ["VoiceCheap"], "requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"},
timeout=120,
)
body = response.json()
if not response.ok:
raise RuntimeError(f"{body.get('code')}: {body.get('message')}")
print(body)
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"status": "running",
"pollAction": "action_request_get",
"pollAfterSeconds": 5
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"resultId": "b3caf96f-5f2a-4619-832c-a12c0d57f78b",
"operation": "captions_transcribe",
"createdAt": 1792152000000,
"fileName": "voicecheap-captions_transcribe-b3caf96f-5f2a-4619-832c-a12c0d57f78b.json",
"byteLength": 190,
"contentType": "application/json; charset=utf-8",
"status": "completed",
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"getAction": "subtitles_result_get",
"downloadAction": "subtitles_result_download",
"listAction": "subtitles_result_list"
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"operation": "captions_transcribe",
"createdAt": 1792144800000,
"updatedAt": 1792144820000,
"status": "running",
"pollAfterSeconds": 5
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"operation": "captions_transcribe",
"createdAt": 1792144800000,
"updatedAt": 1792144820000,
"status": "completed",
"resultStored": false,
"message": "The action completed. Retrieve its output from the corresponding history or resource action."
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
将上传的音轨转写为带时间戳的词语,用于字幕编辑。此操作不提供动画视频渲染或本地浏览器编辑会话。返回精简的已保存结果引用;使用其中的 getAction 或 downloadAction 获取完整输出。
所需权限:
POST https://api.voicecheap.ai/v1/actions/captions_transcribe
身份验证和权限
string
必填
在此请求头中发送 VoiceCheap API 密钥。也支持通过 Authorization: Bearer 发送同一 API 密钥。OAuth 访问令牌仅适用于 MCP,此 REST 端点不接受 OAuth
访问令牌。
subtitles:write.
需要有效的付费订阅。权限不会改变团队角色、资源归属、媒体额度或套餐限制。
参数
string
必填
已完成上传或媒体导入返回的、当前账户拥有的 fileKey。每次生成都会消耗其上传源文件。最小长度: 1. 最大长度: 1024.
string
文本值。最小长度: 1. 最大长度: 255. 匹配模式:
^[^/\\\r\n\0]+$.array
值列表。项目结构请参阅完整输入架构。最多项目数: 100.
string
在传输层可选:如果省略,服务器会在验证前注入标识符。请自行提供稳定的 UUID v4,以便在响应丢失后安全恢复。格式: “uuid”. 匹配模式:
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$.完整输入架构
完整输入架构
以下 JSON Schema 保留了发现接口公开的确切字段名、嵌套类型、默认值、范围和可接受值。其他跨字段规则列于操作说明中。
{
"type": "object",
"properties": {
"fileKey": {
"type": "string",
"minLength": 1,
"maxLength": 1024,
"description": "An owned fileKey returned by a completed upload or media import. Each generation consumes its uploaded source."
},
"fileName": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"pattern": "^[^/\\\\\\r\\n\\0]+$"
},
"keyterms": {
"maxItems": 100,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 120
}
},
"requestId": {
"description": "UUID v4 for this action. Reuse the same ID with identical arguments on retries.",
"type": "string",
"format": "uuid",
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
}
},
"required": ["fileKey"],
"additionalProperties": false
}
幂等性
为每次修改操作在 requestId 或 Idempotency-Key HTTP 请求头中提供 UUID v4。网络故障后,请使用相同标识符和完全相同的参数重试。如果同时提供这两个值,它们必须一致。重放已保存的请求不会重复执行操作,也不会再次扣除月度调用次数。失败或中断的请求不会自动重新执行。 对于每次修改操作,如果重试时发现同一请求仍在运行,即使首次执行通常为同步操作,也可能返回 HTTP 202。如果执行已完成但 resultStored 为 false,重试会返回 HTTP 200 和已保存的请求状态,而非原始结果。请通过对应领域的历史记录、结果或下载操作获取输出。请求示例
请将示例资源标识符和媒体键替换为账户返回的值。重试同一次修改操作时,请保持请求标识符不变。curl --request POST 'https://api.voicecheap.ai/v1/actions/captions_transcribe' \
--header "x-api-key: $VOICECHEAP_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"fileKey":"uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav","fileName":"interview.wav","keyterms":["VoiceCheap"],"requestId":"13579bdf-2468-4ace-8bdf-0123456789ab"}'
const input = {
fileKey: 'uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav',
fileName: 'interview.wav',
keyterms: ['VoiceCheap'],
requestId: '13579bdf-2468-4ace-8bdf-0123456789ab',
};
const response = await fetch('https://api.voicecheap.ai/v1/actions/captions_transcribe', {
method: 'POST',
headers: {
'x-api-key': process.env.VOICECHEAP_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
});
const body = await response.json();
if (!response.ok) throw new Error(body.code + ': ' + body.message);
console.log(body);
import os
import requests
response = requests.post(
"https://api.voicecheap.ai/v1/actions/captions_transcribe",
headers={"x-api-key": os.environ["VOICECHEAP_API_KEY"]},
json={"fileKey": "uploads/account-user/a1b2c3d4-e5f6-4789-8abc-def012345678-interview.wav", "fileName": "interview.wav", "keyterms": ["VoiceCheap"], "requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"},
timeout=120,
)
body = response.json()
if not response.ok:
raise RuntimeError(f"{body.get('code')}: {body.get('message')}")
print(body)
响应
此操作在运行期间返回 HTTP 202。请保存 requestId,并使用该标识符和原始操作名称轮询 action_request_get。轮询状态包括 running、completed、failed 和 interrupted。已完成的结果可能指向独立的媒体任务;请继续使用该操作对应的状态或输出操作。 已保存的字幕词级数据引用。完整 JSON 包含 words、durationSeconds 和可选的 detectedLanguage。每个词包含 text、startMs、endMs 和可为 null 的 speakerId。{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"status": "running",
"pollAction": "action_request_get",
"pollAfterSeconds": 5
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"resultId": "b3caf96f-5f2a-4619-832c-a12c0d57f78b",
"operation": "captions_transcribe",
"createdAt": 1792152000000,
"fileName": "voicecheap-captions_transcribe-b3caf96f-5f2a-4619-832c-a12c0d57f78b.json",
"byteLength": 190,
"contentType": "application/json; charset=utf-8",
"status": "completed",
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"getAction": "subtitles_result_get",
"downloadAction": "subtitles_result_download",
"listAction": "subtitles_result_list"
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"operation": "captions_transcribe",
"createdAt": 1792144800000,
"updatedAt": 1792144820000,
"status": "running",
"pollAfterSeconds": 5
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"operation": "captions_transcribe",
"createdAt": 1792144800000,
"updatedAt": 1792144820000,
"status": "completed",
"resultStored": false,
"message": "The action completed. Retrieve its output from the corresponding history or resource action."
},
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab"
}
结果字段
| 字段 | 说明 |
|---|---|
data.resultId | 当前账户拥有的已保存输出的 UUID。将其用于 getAction 或 downloadAction;它不同于 requestId 和任何 historyId。 |
data.operation | 生成此已保存 JSON 的生成操作。 |
data.createdAt | 已保存的输出准备完成时的 Unix 毫秒时间戳。 |
data.fileName | JSON 导出的建议文件名。 |
data.byteLength | 完整序列化输出的 UTF-8 字节,不是精简元数据。 |
data.contentType | application/json; charset=utf-8。 |
data.status | 生成成功时为 completed。结果历史记录也可能显示待恢复条目。 |
data.requestId | 已记录时,为原始操作请求 UUID。 |
data.getAction | 检索当前账户拥有的内容的操作;includeContent 默认为 false,获取完整结构化输出时必须为 true。 |
data.downloadAction | 需要认证的导出操作,以内容字符串形式返回完整 JSON。 |
data.listAction | 此权限领域中用于列出当前账户拥有的已保存输出的操作。 |
恢复并轮询此请求
即使连接丢失,也应使用同一标识符。如果 resultStored 为 false,请通过相应的历史记录、结果或下载操作获取输出。切勿仅为查看进度而启动第二次生成。curl --request POST 'https://api.voicecheap.ai/v1/actions/action_request_get' \
--header "x-api-key: $VOICECHEAP_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"requestId":"13579bdf-2468-4ace-8bdf-0123456789ab","operation":"captions_transcribe"}'
HTTP 200
{
"data": {
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"operation": "captions_transcribe",
"status": "completed",
"createdAt": 1792144800000,
"updatedAt": 1792144820000,
"resultStored": true,
"result": {
"resultId": "b3caf96f-5f2a-4619-832c-a12c0d57f78b",
"operation": "captions_transcribe",
"createdAt": 1792152000000,
"fileName": "voicecheap-captions_transcribe-b3caf96f-5f2a-4619-832c-a12c0d57f78b.json",
"byteLength": 190,
"contentType": "application/json; charset=utf-8",
"status": "completed",
"requestId": "13579bdf-2468-4ace-8bdf-0123456789ab",
"getAction": "subtitles_result_get",
"downloadAction": "subtitles_result_download",
"listAction": "subtitles_result_list"
}
}
}
操作说明
- 需要付费订阅和操作权限。执行时会重新检查调用者的个人工具套餐;已保存的工具和上传引用均属于该调用者,包括凭据与团队关联时。
- 成功操作会消耗一次 API/MCP 共用的每月调用次数。Beginner 每月 500 次、Starter 5,000 次、Creator 25,000 次;Pro、Scale 和 Enterprise 无每月上限。每分钟限制仍然适用,分别为 30、60、120、180、300 和 600 次。工具生成限额单独计算。
- 使用 UUID v4 格式的 requestId,或值与其相同的 Idempotency-Key 请求头,并在重试时保持操作、ID 和参数不变。返回缓存结果不会再次消耗每月调用次数。
- 这是一个异步操作。初始传输结果是带有 pollAction 的 running 请求;使用此操作名称和原始 requestId 轮询 action_request_get。此处显示的已完成操作结果是精简的已保存输出引用,不是生成的正文。
- 完整输出会按照经过身份验证的归属关系保存到加密存储中,独立于有界的操作轮询缓存。使用 resultId 和 includeContent: true 调用返回的 getAction,以获取结构化 JSON;或使用 resultId 调用 downloadAction,以获取 JSON 文本。若仅知道原始请求,可通过 listAction 找回结果。
- 已保存的 JSON 最大为 32 MiB。元数据绝不会公开其存储加密密钥或无需身份验证的转写文本下载 URL。
- 生成成功后会结算一次个人工具限额。生成失败通常会释放工具预留额度。如果无法确定输出是否已保存,请在再次生成前检查同一请求和已保存结果的历史记录;服务器会保留预留额度以防止重复使用。
- 没有每月集成调用上限的高级套餐仍受以下工具每日限额和媒体限制约束。这些独立操作消耗相应工具限额,而不是配音分钟数或 TTS 字符数。
- 请使用归属于当前账户且已完成上传或导入的 fileKey,并将其视为一次性资源。媒体处理开始后,无论处理成功还是失败,清理流程都会删除源文件。处理开始前的验证失败或限额拒绝可能会保留源文件。在启动另一次生成前,请复用原始 requestId,恢复已受理的生成请求。
- 仅上传提取的音轨:WAV、MP3、M4A、AAC、OGG、Opus 或 FLAC,最大 250 MiB。包含视频流的文件会被拒绝,即使其文件名使用音频扩展名。
- Beginner 最长支持 30 分钟;Starter、Creator、Pro、Scale 和 Enterprise 最长支持 60 分钟,另加 2 秒的容器时长容差。
- 每日字幕转写限额:Beginner 10、Starter 15、Creator 30、Pro 60、Scale 100、Enterprise 100;与网页字幕工具共享。
- 词语偏移量的单位为毫秒;durationSeconds 的单位为秒。服务器返回带时间信息的词语,不返回渲染后的动态视频。本地浏览器中的字幕编辑和渲染不在此操作范围内。
- 字幕转写没有独立的网页历史记录操作系列。请使用 subtitles_result_list/get/download 恢复其完整的集成输出。
用量
每次成功调用消耗一次月度 API/MCP 调用额度。媒体额度和操作本身的生成限额也适用。错误
| HTTP 状态 | 代码 | 含义或恢复方式 |
|---|---|---|
| 400 | CREDENTIAL_IN_QUERY | 凭证通过 access_token 或 api_key 查询参数提供。请在标头中发送凭证。 |
| 400 | DURATION_TOO_LONG | 媒体超出了该操作的时长限制。 |
| 400 | DURATION_UNKNOWN | 执行步骤无法确定正的媒体时长。 |
| 400 | FILE_TOO_LARGE | 已存储的源文件超过此操作的专用字节限额。 |
| 400 | IDEMPOTENCY_CONFLICT | 标头与请求体中的请求 ID 不同。 |
| 400 | INVALID_FILE_TYPE | 此操作不支持该文件名扩展名。 |
| 400 | INVALID_MEDIA_DURATION | 探测到的源文件时长缺失、无效或超出了套餐时长限制。 |
| 400 | INVALID_MEDIA_STREAM | 源文件没有可用于转写的音轨。 |
| 400 | INVALID_REQUEST_ID | requestId 或 Idempotency-Key 不是 UUID v4。 |
| 400 | VALIDATION_ERROR | 参数不符合操作架构,或提供了未知参数。 |
| 401 | API_KEY_EXPIRED | API 密钥已过期。 |
| 401 | INVALID_API_KEY | 请提供有效且未过期的 API 密钥。 |
| 401 | INVALID_CREDENTIAL | Authorization 标头格式错误或与 x-api-key 冲突。 |
| 401 | MISSING_CREDENTIAL | 未提供可用的请求头凭据,或其长度超过 4096 个字符。 |
| 401 | USER_NOT_FOUND | 该凭据对应的账户已不存在。 |
| 403 | ACCOUNT_UNAVAILABLE | 调用者账户或计费账户不可用,或正在删除。 |
| 403 | AMBIGUOUS_TEAM_API_KEY | 此凭据对应的用户属于多个团队,因此计费上下文不明确。 |
| 403 | INSUFFICIENT_SCOPE | API 密钥或 MCP 连接缺少所需的操作权限。 |
| 403 | INTEGRATION_PLAN_UNSUPPORTED | 无法验证该账户的集成限制。 |
| 403 | INVALID_FILE_REFERENCE | fileKey 不是属于调用者的有效已完成上传引用。 |
| 403 | PAID_SUBSCRIPTION_REQUIRED | 此工具操作执行时,已认证的调用者已无付费订阅。 |
| 403 | SUBSCRIPTION_REQUIRED | 请使用有效的付费订阅。 |
| 403 | TEAM_OWNER_NOT_FOUND | 找不到实际生效的团队所有者账户。 |
| 404 | MEDIA_NOT_FOUND | 已完成的源文件上传不存在或为空;它可能已被先前的生成消耗。 |
| 409 | CONCURRENT_ACTION_LIMIT_REACHED | 此账户已有 10 个集成操作正在运行。请先轮询现有请求,再启动另一个操作。 |
| 409 | IDEMPOTENCY_CONFLICT | 只有操作和参数完全相同时,才能复用标识符。 |
| 410 | TOOL_RESULT_ACCOUNT_UNAVAILABLE | 调用者正在删除或已不存在,因此无法保存持久化结果。 |
| 413 | TOOL_RESULT_TOO_LARGE | 生成的完整 JSON 超过 32 MiB,无法保存为集成结果。 |
| 422 | TRANSCRIPTION_EMPTY | 音频中没有识别到口语词语。 |
| 429 | ANIMATED_CAPTIONS_TOOL_DAILY_LIMIT_REACHED | 调用者的动态字幕转写限额已用尽。 |
| 429 | INTEGRATION_MONTHLY_LIMIT_REACHED | 已使用和待处理的调用次数已达到共享的每月 API/MCP 限额。 |
| 429 | INTEGRATION_RATE_LIMIT_REACHED | 该账户已达到每分钟集成调用上限;请检查 retryAfterSeconds。 |
| 500 | INTERNAL_ERROR | 在决定是否重试修改操作前,请检查已保存的请求状态和资源历史记录。 |
| 502 | INTERNAL_ERROR | 生成或输出保存失败。启动另一次生成前,请检查原始请求和已保存的结果历史记录。 |
| 503 | ACTION_RESULT_UNAVAILABLE | 操作已执行,但无法确认请求结果是否已持久化。开始另一次写入前,请使用相同操作和 requestId 轮询,并检查资源历史记录。 |
| 503 | INTERNAL_ERROR | 生成情况或已保存的结果的持久化情况不确定,或暂时不可用;再次生成前,请先通过认证后的结果恢复功能获取结果。 |
| 503 | SERVER_RESTARTING | 服务器正在重启。请稍后重试;对于修改操作,请保持请求标识符不变。 |
{
"code": "INSUFFICIENT_SCOPE",
"message": "This credential does not permit the requested action.",
"status": 403,
"details": {
"requiredScopes": ["subtitles:write"]
}
}
此页面对您有帮助吗?

