API 中文说明
TranscriptCore
这是一个面向音频 URL 的异步语音转写服务。你可以创建转写任务、轮询任务进度, 并在任务完成后获取标准化全文、分段时间戳,以及可选的逐词时间戳。
鉴权方式
仅 /v1/* 需要静态 token 固定为 WANGJI。只有创建任务和查询任务这类 /v1/* 业务接口,才必须通过 X-API-Key 或 Authorization: Bearer <token> 传入。 首页 /、/health、 /docs、/openapi.json、 /redoc 保持公开。
X-API-Key
X-API-Key: WANGJI
Bearer Token
Authorization: Bearer WANGJI
可以额外传入 X-Request-Id 作为链路追踪 ID;如果不传,服务会自动生成。
接口列表
共 3 个路由
GET /health
公共健康检查接口,返回服务状态、服务名和版本号。
POST /v1/transcription-jobs
提交新的音频转写任务,返回任务资源和当前进度。
GET /v1/transcription-jobs/{job_id}
根据任务 ID 轮询查询,直到任务成功或失败。
创建转写任务
POST
/v1/transcription-jobs
这个接口会启动一个异步转写任务。服务会先下载远程音频,再加载模型并执行转写, 最后把进度和结果都记录到任务资源中返回。
| 字段 | 类型 | 说明 |
|---|---|---|
| source.url | string | 必填,公开可访问的音频地址。 |
| language | string | null | 可选,语言提示,例如 zh、en。 |
| granularity | "segment" | "word" | 控制返回分段级时间戳,还是同时生成逐词时间戳。 |
| with_words | boolean | 当值为 true 且 granularity=word 时,返回每个词的时间戳。 |
| prompt | string | null | 可选,提示词,用于帮助模型识别语境、术语和专有名词。 |
| metadata | object | null | 可选,自定义元信息,会原样回传到任务结果中。 |
查询转写任务
GET
/v1/transcription-jobs/{job_id}
这个接口返回任务的最新状态。当状态变成 succeeded 时, 响应中会带上完整转写结果,包括全文、分段内容和可选的逐词时间戳。
| 状态 | 含义 | 备注 |
|---|---|---|
| queued | 已接受,等待执行 | 创建任务后的初始状态。 |
| running | 执行中 | 重点看 stage、progress_percent、processed_until_ms。 |
| succeeded | 转写成功 | 结果在 data.transcript 中。 |
| failed | 任务失败 | 失败原因在 data.failure 中。 |
统一响应结构
所有接口都使用统一顶层结构: ok 表示是否成功, data 是业务数据, error 是错误信息, meta 则包含版本和请求追踪信息。
请求体示例
JSON Body{
"source": {
"url": "https://example.com/audio.mp3"
},
"language": "zh",
"granularity": "word",
"with_words": true,
"prompt": "请尽量保留停顿、数字和专有名词。",
"metadata": {
"project": "launch-video",
"asset_id": "audio_001"
}
}
cURL 调用示例
带鉴权curl -X POST "http://localhost:8000/v1/transcription-jobs" -H "Content-Type: application/json" -H "X-API-Key: WANGJI" -d '{"source": {"url": "https://example.com/audio.mp3"}, "language": "zh", "granularity": "word", "with_words": true, "prompt": "请尽量保留停顿、数字和专有名词。", "metadata": {"project": "launch-video", "asset_id": "audio_001"}}'
创建任务响应
202 Accepted{
"ok": true,
"data": {
"job_id": "job_0123456789abcdef",
"status": "running",
"stage": "transcribing",
"progress_percent": 42,
"progress_message": "正在转写音频 18.4s",
"audio_duration_ms": 43852,
"processed_until_ms": 18400,
"source": {
"kind": "audio_url",
"url": "https://example.com/audio.mp3"
},
"language": "zh",
"created_at": "2026-06-02T08:00:00Z",
"updated_at": "2026-06-02T08:00:08Z",
"started_at": "2026-06-02T08:00:01Z",
"finished_at": null,
"transcript": null,
"failure": null,
"metadata": {
"project": "launch-video",
"asset_id": "audio_001"
}
},
"error": null,
"meta": {
"api_version": "v1",
"schema_version": "transcript.v1",
"request_id": "req_0123456789abcdef"
}
}
任务完成响应
200 OK{
"ok": true,
"data": {
"job_id": "job_0123456789abcdef",
"status": "succeeded",
"stage": "succeeded",
"progress_percent": 100,
"progress_message": "转写完成",
"audio_duration_ms": 43852,
"processed_until_ms": 43852,
"source": {
"kind": "audio_url",
"url": "https://example.com/audio.mp3"
},
"language": "zh",
"created_at": "2026-06-02T08:00:00Z",
"updated_at": "2026-06-02T08:00:21Z",
"started_at": "2026-06-02T08:00:01Z",
"finished_at": "2026-06-02T08:00:21Z",
"transcript": {
"transcript_id": "tr_abcdef0123456789",
"source": {
"kind": "audio_url",
"url": "https://example.com/audio.mp3"
},
"language": "zh",
"duration_ms": 43852,
"text": "你好世界。这是 TranscriptCore。",
"segments": [
{
"segment_index": 1,
"text": "你好世界。",
"start_ms": 0,
"end_ms": 1320,
"confidence": -0.21,
"speaker": null,
"words": [
{
"word_index": 1,
"text": "你好",
"start_ms": 0,
"end_ms": 530,
"confidence": null
},
{
"word_index": 2,
"text": "世界。",
"start_ms": 540,
"end_ms": 1320,
"confidence": null
}
]
}
],
"warnings": []
},
"failure": null,
"metadata": {
"project": "launch-video",
"asset_id": "audio_001"
}
},
"error": null,
"meta": {
"api_version": "v1",
"schema_version": "transcript.v1",
"request_id": "req_0123456789abcdef"
}
}
鉴权失败示例
401 Unauthorized{
"ok": false,
"data": null,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key",
"details": null
},
"meta": {
"api_version": "v1",
"schema_version": "transcript.v1",
"request_id": "req_0123456789abcdef"
}
}