REST API

Entries

概述

逐字稿條目(句子)編輯 API。提供使用者修正 STT 辨識錯誤的能力。


PATCH /api/v1/tasks/{taskId}/entries/{sid}

V1.4.1 命名統一:本端點同時提供以下兩條等價路徑,行為完全相同(同一 Controller、同一 UUID):

  • 推薦 PATCH /api/v1/tasks/{taskId}/entries/{sid}(V1.4.1 起新增)
  • Deprecated PATCH /api/v1/recordings/{recordingId}/entries/{sid}(V1.4.1 之前的舊路徑,將於 V1.6.0 移除)

新整合請使用 tasks 路徑;既有整合可繼續使用 recordings 路徑直到 V1.6.0。

為相容 expectedRevision 樂觀鎖等舊資料,下文範例仍同時保留兩種路徑形式。

功能說明

修改歷史錄音中單一句子的原文(original_text)。

設計重點:

  • 保留 STT 原始輸出:首次編輯時系統會自動把原始 STT 結果備份到 original_text_raw,可隨時回溯
  • 不自動重翻:本端點只改原文,翻譯需呼叫 GET /api/v1/sse/recordings/{taskId}/entries/{sid}/retranslate 觸發
  • 樂觀鎖:可帶 expected_revision 防止併發覆寫
  • TTS 快取自動失效:原文變更後該句所有語言的 TTS 快取會被清除

限制

  • 僅允許已完成處理processing_status === completed)的錄音;進行中的錄音會回 recording_not_completed
  • 只能編輯屬於該 API Key 持有者的錄音

認證方式

Header:X-API-Key(詳見 認證機制

請求參數

Path 參數

參數類型必填說明
taskIdstring任務 ID(UUID,與舊命名 recordingId 為同一值)
sidnumber句子 ID(1-based)

Body 參數(JSON)

參數類型必填說明
original_textstring修正後的原文,1–2000 字元
expected_revisionnumber樂觀鎖:當前 transcript revision;不符會回 transcript_revision_conflict

請求範例

# 直接覆寫(推薦:tasks 路徑)
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/{taskId}/entries/5" \
  -H "X-API-Key: vas_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "original_text": "修正後的文字" }'

# 帶樂觀鎖
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/{taskId}/entries/5" \
  -H "X-API-Key: vas_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "original_text": "修正後的文字", "expected_revision": 3 }'

成功回應

HTTP 200

{
  "data": {
    "sid": 5,
    "original_text": "修正後的文字",
    "original_text_raw": "原始 STT 輸出",
    "original_text_edited_at": "2026-05-06T10:30:00.000000Z",
    "translated_texts": {
      "en-US": "已過期的舊翻譯,待呼叫 retranslate 端點重做"
    },
    "revision": 4
  }
}
欄位類型說明
sidnumber句子 ID
original_textstring修正後的原文
original_text_rawstringSTT 原始輸出(首次編輯時備份)
original_text_edited_atstring編輯時間(ISO 8601)
translated_textsobject既有翻譯(不會自動更新,需另呼叫 SSE 重翻端點)
revisionnumber寫入後的新 revision,用於下次樂觀鎖

特有錯誤碼

錯誤碼HTTP說明
recording_not_found404錄音不存在或不屬於該使用者
recording_not_completed422錄音尚未完成處理
entry_not_found404找不到指定的句子
entry_text_empty422原文為空
entry_text_too_long422原文超過 2000 字元上限
transcript_revision_conflict409revision 不符(已被其他請求修改)
speaker_transcript_not_found404找不到 transcript blob

典型工作流:編輯 + 自動重翻

// 1. 從 historyTranscribe 取得當前 revision(透過 init_metadata 或自行讀取)
const currentRevision = 3;

// 2. 編輯原文
const editResp = await fetch(`/api/v1/recordings/${id}/entries/${sid}`, {
  method: 'PATCH',
  headers: { 'X-API-Key': key, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    original_text: '修正後文字',
    expected_revision: currentRevision,
  }),
});
const { data } = await editResp.json();
// data.revision 會是 4,後續操作以此為基準

// 3. 觸發單句重翻(會 emit progress / translated / done 事件)
const sse = new EventSource(
  `/api/v1/sse/recordings/${id}/entries/${sid}/retranslate`
    + `?expectedRevision=${data.revision}&api_key=${key}`
);
sse.addEventListener('translated', (e) => {
  const { lang, text } = JSON.parse(e.data);
  console.log(`${lang}: ${text}`);
});
sse.addEventListener('done', (e) => {
  const { revision } = JSON.parse(e.data);
  // revision 會是 5
  sse.close();
});

版本:V1.5.7 最後更新:2026-05-20

Copyright © 2026