Tasks
端點總覽
| 方法 | 端點 | 說明 |
|---|---|---|
| GET | /api/v1/tasks | 取得任務列表 |
| DELETE | /api/v1/tasks/{taskId} | 刪除任務 |
| PUT | /api/v1/tasks/{taskId}/pin | 更新釘選狀態 |
| PUT | /api/v1/tasks/{taskId}/read | 標記已讀 |
| PATCH | /api/v1/tasks/{taskId}/name | 更新任務名稱 |
| POST | /api/v1/tasks/{taskId}/force-fail | 手動強制將任務標記為失敗 |
| POST | /api/v1/tasks/{taskId}/retry | 重新處理已失敗的任務 |
| PUT | /api/v1/tasks/batch/pin | 批次更新釘選狀態 |
| DELETE | /api/v1/tasks/batch | 批次刪除任務 |
| GET | /api/v1/tasks/{taskId}/audio/export | 下載任務音檔 |
| GET | /api/v1/tasks/{taskId}/transcript/export | 下載逐字稿(TXT / SRT / SBV / VTT / CSV) |
GET /api/v1/tasks
功能說明
取得目前使用者的錄音任務列表。可透過 status 參數篩選不同處理階段的任務。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 預設值 | 說明 |
|---|---|---|---|---|---|
status | query | string | 否 | completed | 篩選條件:completed(已完成)/ active(進行中)/ all(全部) |
status 篩選說明
| 值 | 回傳任務 | 說明 |
|---|---|---|
completed | processing_status = completed | 預設值,向後相容。只回傳處理完成的任務 |
active | processing_status IN (recording, importing, uploading, processing) | 進行中的任務(即時錄音中、音檔匯入中、上傳中、處理中) |
all | 不篩選 | 回傳所有任務(含進行中和已完成) |
請求範例
# 預設:只回傳已完成的任務(向後相容)
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
# 查詢進行中的任務
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks?status=active" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
成功回應
HTTP 200
{
"data": {
"tasks": [
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"title": "會議記錄",
"type": "transcribe",
"type_source": "realtime",
"duration_ms": 60000,
"duration_formatted": "1:00",
"transcription_languages": ["zh-TW"],
"translation_languages": ["en-US"],
"created_at": "2026-02-25T10:00:00Z",
"processing_status": "completed",
"is_pinned": false,
"is_unread": true,
"summary_mode": "custom",
"summary_template": "acme-meeting-v2",
"summary_language": "zh-TW"
}
]
}
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
data.tasks | array | 任務列表 |
data.tasks[].task_id | string | 任務 ID(UUID) |
data.tasks[].title | string | 任務標題 |
data.tasks[].type | string | 錄音類型 |
data.tasks[].type_source | string | 來源類型(realtime / import / broadcast) |
data.tasks[].duration_ms | number | 錄音時長(毫秒) |
data.tasks[].duration_formatted | string | 格式化時長(分:秒) |
data.tasks[].transcription_languages | array | null | 轉錄語言列表(無轉錄語言時為 null) |
data.tasks[].translation_languages | array | null | 翻譯語言列表(無翻譯語言時為 null,例如 conversation 模式或 import 未設定翻譯語言) |
data.tasks[].created_at | string | 建立時間(ISO 8601) |
data.tasks[].processing_status | string | 處理狀態(見下方說明) |
data.tasks[].is_pinned | boolean | 是否已釘選 |
data.tasks[].is_unread | boolean | 是否未讀 |
data.tasks[].summary_mode | string | null | 摘要模式:"builtin" / "custom" / null(未生成摘要時為 null) |
data.tasks[].summary_template | string | null | effective slug — builtin → 內建模板 slug;custom → 客戶 slug(即 request 端的 prompt_slug,pass-through 追溯用) |
data.tasks[].summary_language | string | null | 摘要輸出語言 |
processing_status 狀態說明
Recording 的處理狀態會隨處理進程即時更新:
| 狀態 | 說明 | 場景 |
|---|---|---|
recording | 即時錄音進行中 | 即時錄音、廣播 |
importing | 音檔匯入處理中 | 音檔匯入 |
uploading | 上傳至雲端儲存中 | 錄音停止後、匯入完成後 |
pending | 待處理(保留向下相容) | 僅出現於舊資料;新建紀錄不會進入此狀態 |
processing | 語音辨識與翻譯處理中 | 上傳完成後 |
completed | 處理完成 | 最終狀態 |
failed | 處理失敗 | 最終狀態 |
狀態流轉:
即時錄音/廣播:recording → uploading → processing → completed / failed
音檔匯入: importing → uploading → processing → completed / failed
pending狀態說明:保留供舊資料相容,新建紀錄不會進入此狀態。force-fail仍接受處於pending的紀錄,以便清理歷史殘留資料。
特有錯誤碼
此端點無特有錯誤碼,僅可能回傳通用認證錯誤。
DELETE /api/v1/tasks/{taskId}
功能說明
刪除指定的任務(軟刪除)。刪除後任務將不會出現在列表中。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 說明 |
|---|---|---|---|---|
taskId | path | string | 是 | 任務 ID(UUID) |
請求範例
curl -X DELETE "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
成功回應
HTTP 200
{
"message": "任務已刪除"
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
message | string | 操作結果訊息 |
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音 | 確認 taskId 正確 |
recording_unauthorized | 403 | 無權限操作此錄音 | 確認任務屬於該用戶 |
PUT /api/v1/tasks/{taskId}/pin
功能說明
更新任務的釘選狀態。釘選的任務會在列表中優先顯示。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 說明 |
|---|---|---|---|---|
taskId | path | string | 是 | 任務 ID(UUID) |
is_pinned | body | boolean | 是 | 釘選狀態 |
請求範例
curl -X PUT "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/pin" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{"is_pinned": true}'
成功回應
HTTP 200
{
"data": {
"is_pinned": true
}
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
data.is_pinned | boolean | 更新後的釘選狀態 |
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音 | 確認 taskId 正確 |
validation_failed | 422 | 參數驗證失敗 | 確認 is_pinned 為布林值 |
PUT /api/v1/tasks/{taskId}/read
功能說明
將任務標記為已讀。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 說明 |
|---|---|---|---|---|
taskId | path | string | 是 | 任務 ID(UUID) |
請求範例
curl -X PUT "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/read" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
成功回應
HTTP 200
{
"data": {
"is_unread": false
}
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
data.is_unread | boolean | 更新後的未讀狀態(固定為 false) |
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音 | 確認 taskId 正確 |
PATCH /api/v1/tasks/{taskId}/name
功能說明
更新指定任務的名稱。名稱長度最大為 60 字元(由 RECORDING_NAME_MAX_LENGTH 環境變數控制)。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 說明 |
|---|---|---|---|---|
taskId | path | string | 是 | 任務 ID(UUID) |
name | body | string | 是 | 任務名稱(最大 60 字) |
請求範例
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/name" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{"name": "產品會議討論"}'
成功回應
HTTP 200
{
"message": "錄音名稱已更新",
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"name": "產品會議討論",
"name_source": "user"
}
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
message | string | 操作結果訊息 |
data.task_id | string | 任務 ID(UUID) |
data.name | string | 更新後的任務名稱 |
data.name_source | string | 名稱來源:default(系統預設)/ llm(AI 生成)/ user(使用者自訂) |
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音 | 確認 taskId 正確 |
recording_unauthorized | 403 | 無權限操作此錄音 | 確認任務屬於該用戶 |
validation_failed | 422 | 驗證失敗 | 確認 name 不為空且長度不超過 60 字元 |
PUT /api/v1/tasks/batch/pin
功能說明
批次更新多個任務的釘選狀態。單次請求最多可操作 100 筆任務。僅會影響屬於當前用戶的任務,不屬於該用戶的 ID 會被忽略。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 說明 |
|---|---|---|---|---|
task_ids | body | array | 是 | 任務 ID 陣列(每個元素為 UUID,最多 100 筆) |
is_pinned | body | boolean | 是 | 釘選狀態 |
請求範例
curl -X PUT "https://vas-poc.vurbo.ai/api/v1/tasks/batch/pin" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"task_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"is_pinned": true
}'
成功回應
HTTP 200
{
"data": {
"affected_count": 2
}
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
data.affected_count | number | 實際被更新的任務數量 |
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
validation_failed | 422 | 參數驗證失敗 | 確認 task_ids 為 UUID 陣列且不超過 100 筆,is_pinned 為布林值 |
DELETE /api/v1/tasks/batch
功能說明
批次刪除多個任務(軟刪除)。單次請求最多可操作 100 筆任務。僅會影響屬於當前用戶的任務,不屬於該用戶的 ID 會被忽略。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 說明 |
|---|---|---|---|---|
task_ids | body | array | 是 | 任務 ID 陣列(每個元素為 UUID,最多 100 筆) |
請求範例
curl -X DELETE "https://vas-poc.vurbo.ai/api/v1/tasks/batch" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"task_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
]
}'
成功回應
HTTP 200
{
"data": {
"affected_count": 2
}
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
data.affected_count | number | 實際被刪除的任務數量 |
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
validation_failed | 422 | 參數驗證失敗 | 確認 task_ids 為 UUID 陣列且不超過 100 筆 |
GET /api/v1/tasks/{taskId}/audio/export
功能說明
下載指定任務的原始錄音音檔。回應為二進位音訊流並附加 Content-Disposition: attachment 標頭,瀏覽器或下載工具會直接將內容儲存為檔案。檔名會優先使用錄音名稱(經清洗過的檔名),若名稱為空則退回 audio。
與 音訊串流 API(
GET /api/v1/sse/audio/{taskId})的差異:
- 本端點:離線下載用途;回應附
Content-Disposition: attachment標頭;不支援 Range Request。- 音訊串流:播放用途;支援 HTTP Range Request 以便拖曳快進;回應不強制下載。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 說明 |
|---|---|---|---|---|
taskId | path | string | 是 | 任務 ID(UUID) |
請求範例
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/audio/export" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-OJ
提示:
curl -OJ會讓 curl 依伺服器回應的Content-Disposition自動命名儲存檔名。
成功回應
HTTP 200
HTTP/1.1 200 OK
Content-Type: audio/mp4
Content-Length: 1234567
Content-Disposition: attachment; filename="audio.m4a"; filename*=UTF-8''%E6%9C%83%E8%AD%B0%E8%A8%98%E9%8C%84.m4a
Cache-Control: no-cache
注意:絕大多數錄音以 M4A 容器(AAC 編碼)回傳,
Content-Type為audio/mp4、副檔名為.m4a。實際Content-Type依錄音儲存格式而定(少數歷史 / 廣播錄音可能為audio/webm或audio/wav),請以 Response Header 為準。
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音,或音檔在雲端儲存中不存在 | 確認 taskId 正確且錄音未被刪除 |
recording_audio_not_ready | 422 | 音檔尚未上傳完成或處理中 | 稍後重試;可先透過 GET /api/v1/tasks 確認 processing_status 為 completed |
storage_download_failed | 500 | 儲存服務下載失敗 | 稍後重試;若持續失敗請聯絡支援 |
前端範例
async function downloadAudio(taskId, apiKey) {
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/tasks/${taskId}/audio/export`,
{
headers: { 'X-API-Key': apiKey },
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Download failed: ${error.data?.message}`);
}
// 解析 Content-Disposition 取得建議檔名
const disposition = response.headers.get('Content-Disposition') || '';
const match = disposition.match(/filename\*=UTF-8''([^;]+)/);
const filename = match ? decodeURIComponent(match[1]) : `audio-${taskId}`;
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
GET /api/v1/tasks/{taskId}/transcript/export
功能說明
下載指定任務的逐字稿,支援五種格式:純文字、SubRip 字幕、YouTube SBV 字幕、WebVTT 字幕、CSV 試算表。回應內容包含原文與所有翻譯語言;回應附 Content-Disposition: attachment 標頭以供直接下載。檔名會優先使用錄音名稱(經清洗後的檔名),若名稱為空則退回 transcript,並統一加上 -transcript.{ext} 後綴。
與 歷史逐字稿 SSE API(
GET /api/v1/sse/history/transcribe/{taskId})的差異:
- 本端點:離線下載用途;一次回傳完整檔案;可直接交給字幕軟體或試算表開啟。
- SSE 歷史 API:漸進式載入用途;以 event stream 逐句推送原始結構資料(JSON 片段),供前端 UI 漸進渲染。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 預設值 | 說明 |
|---|---|---|---|---|---|
taskId | path | string | 是 | — | 任務 ID(UUID) |
format | query | string | 否 | txt | 格式:txt / srt / sbv / vtt / csv |
format 格式說明
| 格式 | 時間格式 | 內容結構 | 典型用途 |
|---|---|---|---|
txt | — | 每段一行 [說話者] 原文,翻譯以 4 個空白縮排為 [語言碼] 譯文 | 閱讀、紀錄保存 |
srt | HH:MM:SS,mmm | 含序號,每段時間軸後原文與翻譯各占一行 | SubRip 字幕(DaVinci Resolve、VLC 等) |
sbv | H:MM:SS.mmm | 無序號;時間軸以 , 分隔;原文與翻譯以 | 串接為單行(換行符會被替換為空白) | YouTube 字幕上傳 |
vtt | HH:MM:SS.mmm | 以 WEBVTT 作為表頭,每段時間軸後原文與翻譯各占一行 | HTML5 <track> 字幕、Web 播放器 |
csv | HH:MM:SS(無毫秒) | UTF-8 BOM 開頭;欄位 index,start,end,speaker,text,<每個翻譯語言一欄> | Excel、資料分析 |
請求範例
# 預設 TXT 格式
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/transcript/export" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-OJ
# 指定 SRT 格式
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/transcript/export?format=srt" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-OJ
# CSV(Excel 可直接開啟,UTF-8 BOM 確保中文不亂碼)
curl -X GET "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/transcript/export?format=csv" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-OJ
提示:
curl -OJ會讓 curl 依伺服器回應的Content-Disposition自動命名儲存檔名。
成功回應
HTTP 200
HTTP/1.1 200 OK
Content-Type: text/csv; charset=UTF-8
Content-Length: 2048
Content-Disposition: attachment; filename="transcript.csv"; filename*=UTF-8''%E6%9C%83%E8%AD%B0%E8%A8%98%E9%8C%84-transcript.csv
Cache-Control: no-cache
注意:
Content-Type會依format參數動態決定:
格式 Content-Type txttext/plain; charset=UTF-8srtapplication/x-subripsbvtext/plain; charset=UTF-8vtttext/vtt; charset=UTF-8csvtext/csv; charset=UTF-8
輸出範例
假設逐字稿包含兩段中文錄音(zh-TW)及兩種翻譯(en-US、ja-JP):
TXT
[Alice] 你好,早安
[en-US] Hello, good morning
[ja-JP] おはよう
[Bob] 多謝
[en-US] Thanks
[ja-JP] ありがとう
SRT
1
00:00:00,500 --> 00:00:03,000
你好,早安
Hello, good morning
おはよう
2
00:00:03,000 --> 00:00:04,200
多謝
Thanks
ありがとう
SBV
0:00:00.500,0:00:03.000
你好,早安 | Hello, good morning | おはよう
0:00:03.000,0:00:04.200
多謝 | Thanks | ありがとう
VTT
WEBVTT
00:00:00.500 --> 00:00:03.000
你好,早安
Hello, good morning
おはよう
00:00:03.000 --> 00:00:04.200
多謝
Thanks
ありがとう
CSV(檔案開頭含 UTF-8 BOM EF BB BF)
index,start,end,speaker,text,en-US,ja-JP
1,00:00:00,00:00:03,Alice,你好,早安,"Hello, good morning",おはよう
2,00:00:03,00:00:04,Bob,多謝,Thanks,ありがとう
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音 | 確認 taskId 正確且錄音未被刪除 |
recording_transcript_not_ready | 422 | 逐字稿尚未產生完成或為空 | 先透過 GET /api/v1/tasks 確認 processing_status = completed 後再呼叫 |
validation_failed | 422 | 參數驗證失敗 | 確認 format 為允許值之一(txt / srt / sbv / vtt / csv) |
storage_download_failed | 500 | 儲存服務下載失敗 | 稍後重試;若持續失敗請聯絡支援 |
前端範例
async function downloadTranscript(taskId, apiKey, format = 'srt') {
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/tasks/${taskId}/transcript/export?format=${format}`,
{
headers: { 'X-API-Key': apiKey },
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Download failed: ${error.data?.message}`);
}
// 解析 Content-Disposition 取得建議檔名
const disposition = response.headers.get('Content-Disposition') || '';
const match = disposition.match(/filename\*=UTF-8''([^;]+)/);
const filename = match
? decodeURIComponent(match[1])
: `transcript-${taskId}.${format}`;
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
POST /api/v1/tasks/{taskId}/force-fail
功能說明
將卡在非終態(recording / importing / uploading / pending / processing)的任務強制標記為失敗。使用情境:Go WebSocket 上游異常中斷但後續狀態通知未送達、或使用者主動放棄仍在上傳的錄音,不想再等 CheckStaleRecordings 排程(最長 30 分鐘)清理。
操作成功後:
processing_status變為failed,processing_error寫入使用者提供的原因- 觸發
recording.failedwebhook,payload.failure_source為user_forced,訂閱者可據此與「Job 執行失敗」「自動 stale 掃描」區分來源 - 後續若再推送
uploading/processing狀態會被回應 409,終態保護生效
注意:已是終態(
completed/failed)的任務呼叫此端點會得到 422。若想清除已完成的任務請改用DELETE /api/v1/tasks/{taskId}。
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 預設值 | 說明 |
|---|---|---|---|---|---|
taskId | path | string | 是 | — | 任務 ID(UUID) |
reason | body | string | null | 否 | null | 失敗原因描述,最長 500 字元。留空時系統自動產生 User-forced failure (previous status: xxx) |
請求範例
# 不帶原因
curl -X POST "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/force-fail" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
# 帶原因
curl -X POST "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/force-fail" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{"reason": "錄音端斷線太久,放棄等待"}'
成功回應
HTTP 200
{
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"processing_status": "failed",
"processing_error": "User-forced failure: 錄音端斷線太久,放棄等待 (previous status: recording)"
}
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
data.task_id | string | 任務 ID(UUID) |
data.processing_status | string | 強制失敗後一律為 failed |
data.processing_error | string | 寫入 DB 的完整失敗原因(含前一個狀態) |
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | 處理建議 |
|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音,或錄音不屬於此使用者 | 確認 taskId 正確且錄音未被刪除 |
invalid_processing_status | 422 | 任務已是終態(completed / failed),不能強制失敗 | 已完成的任務請改用 DELETE;已失敗的任務無需再次強制失敗 |
validation_failed | 422 | reason 超過 500 字元或 taskId 格式錯誤 | 檢查 reason 長度與 taskId UUID 格式 |
前端範例
async function forceFailTask(taskId, apiKey, reason = null) {
const body = reason ? JSON.stringify({ reason }) : undefined;
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/tasks/${taskId}/force-fail`,
{
method: 'POST',
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json',
},
body,
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Force-fail failed: ${error.data?.message}`);
}
return await response.json();
}
POST /api/v1/tasks/{taskId}/retry
功能說明
將處於 failed 狀態的任務重新排入處理佇列(ProcessRecordingJob),用於暫時性的後端服務失效(如 LLM 被速率限制、摘要服務短暫中斷)導致 Job 失敗,使用者想重試的情境。
前置條件
| 條件 | 必須值 |
|---|---|
processing_status | failed |
audio_status | success |
transcript_status | success |
任一條件不符會回 422 invalid_processing_status。若音檔或逐字稿尚未上傳完成,重新 dispatch 會立即再次失敗(因為處理器找不到來源),因此此端點會提前擋下避免 retry loop。
操作成功後:
processing_status變為processing,processing_error清空ProcessRecordingJob以afterCommit()模式派送到recordingsqueue,確保 queue worker 不會在 DB 交易 commit 前讀到舊值- 不會觸發 webhook(僅在 Job 完成時才觸發
recording.completed/recording.failed)
認證方式
Header:X-API-Key(詳見 認證機制)
請求參數
| 參數 | 位置 | 類型 | 必填 | 預設值 | 說明 |
|---|---|---|---|---|---|
taskId | path | string | 是 | — | 任務 ID(UUID) |
請求範例
curl -X POST "https://vas-poc.vurbo.ai/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000/retry" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
成功回應
HTTP 200
{
"data": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"processing_status": "processing"
}
}
特有錯誤碼
| 錯誤碼 | HTTP 狀態碼 | 說明 | details 欄位 | 處理建議 |
|---|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音,或錄音不屬於此使用者 | — | 確認 taskId 正確 |
invalid_processing_status | 422 | 任務不在 failed 狀態 | details.current_status | 只有 failed 的任務可 retry |
invalid_processing_status | 422 | 音檔 / 逐字稿未完整上傳 | details.audio_status、details.transcript_status | 請先確認來源是否完整;若錄音源頭已毀損,建議改用 force-fail 收尾後重新錄製 |
前端範例
async function retryTask(taskId, apiKey) {
const response = await fetch(
`https://vas-poc.vurbo.ai/api/v1/tasks/${taskId}/retry`,
{
method: 'POST',
headers: { 'X-API-Key': apiKey },
}
);
if (!response.ok) {
const error = await response.json();
const details = error.data?.details;
if (details?.audio_status && details.audio_status !== 'success') {
throw new Error(`Cannot retry: audio not ready (${details.audio_status})`);
}
throw new Error(`Retry failed: ${error.data?.message}`);
}
return await response.json();
}
版本:V1.5.7 最後更新:2026-05-20