字庫驗證 API
POST /api/v1/glossary/validate
功能說明
在存檔前檢查一份字庫(術語庫、模糊詞校正、翻譯字典)有沒有格式問題或內部衝突。
字庫的多數設定問題不會產生錯誤訊息,只會在錄音或翻譯時安靜地產生非預期結果——例如某個錯誤變體同時是另一條規則的正確詞,正常說出來的詞就會被改成別的詞。此端點把這類問題在使用者按下儲存的當下就指出來,並附上是第幾筆,讓管理介面能直接標記到出問題的條目。
適用時機:貴方的字庫管理介面在儲存前呼叫。不需要在每次建立錄音或匯入音檔前呼叫。
注意:本端點驗的是字庫本身。通過驗證不代表音檔匯入一定會接受同一份字庫——匯入另有更嚴格的規則。
主機
請使用您建立 WebSocket 連線的同一個網域,將協定由 wss:// 換成 https://。此端點由即時服務提供,與其他 REST 端點可能位於不同網域,請以貴方實際取得的連線設定為準。
# 若 WebSocket 連線為 wss://<即時服務網域>/ws
curl -X POST "https://<即時服務網域>/api/v1/glossary/validate"
認證方式
Header:X-API-Key(詳見 認證機制)
計費
免費。不扣點、不建立任何任務或錄音、不寫入任何字庫設定——純檢查。
頻率限制
每把 API Key 每分鐘 120 次,為獨立配額,與其他 REST 端點的限制分開計算。
通過認證後的回應一律帶下列標頭(配額以 API Key 為單位,認證失敗時尚未知道是哪一把金鑰,故 401/403 不帶);超過時回 HTTP 429 並附 Retry-After:
| 標頭 | 說明 |
|---|---|
X-RateLimit-Limit | 每分鐘允許次數 |
X-RateLimit-Remaining | 本視窗剩餘次數 |
X-RateLimit-Reset | 距本視窗結束的秒數 |
Retry-After | 僅 429 時提供,建議等待秒數 |
請求大小上限
單次請求本體預設上限為 2 MB(2,097,152 位元組)。超過時回 HTTP 413 config_payload_too_large,details.max_bytes 帶當下生效的上限。
本上限可能調整,請一律以回應中的
details.max_bytes為準,不要在程式中寫死。
若整份字庫超過上限,可以分兩次送,但不能任意拆:
| 批次 | 內容 | 說明 |
|---|---|---|
| 第一批 | terminology + fuzzy_correction | 必須同批。跨這兩個區塊的衝突(variant_shadows_term、homophone_conflict)只有在兩者同時送出時才驗得到 |
| 第二批 | translation_dict | 可單獨送。翻譯字典不參與任何跨區塊衝突偵測 |
注意:把
terminology與fuzzy_correction拆開送,variant_shadows_term與homophone_conflict不會被偵測到,且回應不會有任何提示——has_conflicts一樣是false。若貴方以本端點作為存檔閘門,請確保這兩個區塊永遠在同一次請求中。
請求參數
所有欄位皆為選填,給什麼就驗什麼。
| 參數 | 類型 | 必填 | 說明 |
|---|---|---|---|
terminology | object | 否 | 術語庫,格式與 config 相同(語言代碼 → 術語陣列) |
fuzzy_correction | object | 否 | 模糊詞校正,格式與 config 相同 |
translation_dict | object | 否 | 翻譯字典,格式與 config 相同(語言代碼為目標語言) |
check_homophones | boolean | 否 | 是否檢查同音衝突,預設 true。見下方說明 |
transcription_languages | array | 否 | 指定要檢查的來源語言。不給時由字庫自己的語言代碼推導 |
translation_languages | array | 否 | 保留欄位,目前不影響檢查結果(仍受語言代碼數量上限保護) |
上表以外的欄位一律忽略。字庫管理介面若持有整包
config物件,可以原樣送出,不必先剔除多餘欄位。
三個字庫區塊的詳細格式見 字庫使用指南。
check_homophones:編輯中與存檔時分開
八種衝突裡只有同音衝突(homophone_conflict)需要額外的讀音比對,其餘七種是純字串比對、毫秒級完成。
- 編輯過程中的即時檢查 → 傳
false,可頻繁呼叫 - 真正按下儲存時 → 不傳或傳
true,做完整檢查
重要:同音檢查只對中文有效,且在服務忙碌時可能來不及完成。回應的
homophones_checked就是用來區分這兩件事的:
homophones_checked: true→ 同音衝突已檢查完畢homophones_checked: false→ 沒有檢查完,不代表沒有衝突存檔閘門若只看
has_conflicts就放行,在homophones_checked: false時等於放行一份未經檢查的字庫。
請求範例
curl -X POST "https://<即時服務網域>/api/v1/glossary/validate" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW" \
-H "Content-Type: application/json" \
-d '{
"fuzzy_correction": {
"zh-TW": [
{ "correct": "報價", "incorrect": ["抱歉"] },
{ "correct": "抱歉" }
]
}
}'
成功回應
HTTP 200
HTTP 200 代表請求本身合法,不代表字庫沒問題。字庫的檢查結果一律在
data裡,看valid與has_conflicts。
{
"type": "glossary_validation",
"data": {
"valid": false,
"has_conflicts": true,
"homophones_checked": false,
"exceeds_runtime_limits": false,
"checked": ["fuzzy_correction"],
"languages_used": ["zh-TW"],
"limits": {
"terminology_max": 500,
"fuzzy_rules_max": 6000,
"dict_entries_max": 4500
},
"conflicts": [
{
"code": "variant_shadows_term",
"severity": "error",
"variant": "抱歉",
"occurrences": [
{ "language": "zh-TW", "index": 0, "variant_index": 0, "term": "報價" }
],
"shadows": [
{ "language": "zh-TW", "index": 1, "term": "抱歉", "kind": "fuzzy_correct" }
]
}
],
"errors": [],
"warnings": { "unknown_languages": [] }
}
}
回應欄位說明
| 欄位 | 類型 | 說明 |
|---|---|---|
valid | boolean | 存檔紅綠燈。有任何格式錯誤或 severity: "error" 的衝突時為 false |
has_conflicts | boolean | 是否有任何衝突(含警告等級)。注意:見下方「數量超標時不做衝突分析」 |
homophones_checked | boolean | 同音衝突是否已檢查完畢。見上方說明 |
exceeds_runtime_limits | boolean | 字庫存得下,但整份送進錄音會超過上限。見下方說明 |
checked | array | 本次實際檢查了哪些區塊 |
languages_used | array | 本次走訪到的語言代碼(三個區塊的聯集) |
limits | object | 本端點採用的數量上限 |
conflicts | array | 衝突清單。見下節 |
errors | array | 格式與數量問題,形狀與 config 的錯誤回應相同 |
warnings | object | 目前僅 unknown_languages:無法辨識的語言代碼 |
truncated | boolean | 內容因超過回報上限而被截斷時才出現(衝突或格式問題皆可能) |
totals | object | 僅在衝突被截斷時出現,conflicts 為截斷前的衝突總數。格式問題被截斷時不提供總數 |
data的頂層陣列欄位在沒有內容時一律回[],不會回null。衝突物件內的選填欄位(occurrences/shadows/languages/terms等)沒有內容時直接省略,不會出現空陣列。
數量超標時不做衝突分析
字庫的筆數超過上限時,本端點只回數量問題本身,不再逐條檢查內容、也不做衝突偵測與同音檢查。此時回應會是:
valid: false、errors帶數量問題has_conflicts: false、conflicts: []、homophones_checked: false
這種情況不代表字庫沒有衝突——只代表還沒檢查。請先依 errors 把數量調整到上限之內,再重新驗證一次取得完整的衝突清單。
存檔閘門若只看
has_conflicts,這裡會誤判成「沒問題」。請一律先看valid。
exceeds_runtime_limits
本端點允許的字庫略大於錄音時實際可用的量,讓管理介面在編輯過程中不會因為暫時超量而卡住。
exceeds_runtime_limits: true 代表這份字庫可以存,但整份送進錄音會被拒絕。請提示使用者精簡,或分成多份使用。
衝突類型
每筆衝突都帶 code、severity 與出問題的位置(index 為該語言陣列中的第幾筆,從 0 起算),讓管理介面能直接標到條目。
回應不含人語文案,由貴方依 code 與欄位自行組句,語言與用詞完全由貴方決定。
code | severity | 意義 |
|---|---|---|
variant_shadows_term | error | 某個錯誤變體同時是另一條規則的正確詞,或是術語庫的術語 |
dict_duplicate_source | error | 同一目標語言下,同一個 source 登記了多筆 |
variant_ambiguous | warning | 同一個錯誤變體對應到不同的正確詞 |
case_flag_conflict | warning | 同一個錯誤變體在多條規則的 case_insensitive 設定不一致 |
variant_equals_term | warning | 錯誤變體與自己那條規則的正確詞相同 |
duplicate_term | warning | 同一語族下重複登記同一個術語 |
boost_out_of_range | warning | 術語的 boost 超出有效範圍,會被自動調整 |
homophone_conflict | warning | 兩個正確詞或術語讀音相同 |
共通欄位
| 欄位 | 出現時機 | 說明 |
|---|---|---|
code | 一律 | 衝突類型 |
severity | 一律 | error/warning |
variant | 變體類衝突 | 出問題的錯誤變體 |
term | 術語類衝突 | 出問題的術語 |
source | 字典類衝突 | 出問題的來源詞 |
at | 單點衝突 | 出問題的那一筆位置 |
occurrences | 多點衝突 | 所有相關位置 |
occurrences_total | 位置過多被截斷時 | 截斷前的總數 |
位置物件(at 與 occurrences 的元素):
| 欄位 | 說明 |
|---|---|
language | 語言代碼 |
index | 該語言陣列中的第幾筆(0 起算) |
variant_index | 該筆的 incorrect 陣列中的第幾個(0 起算),僅變體類衝突提供 |
term | 該位置對應的結果:規則的正確詞/術語本身/字典的譯法 |
kind | 該位置的來源:fuzzy_correct(模糊詞的正確詞)/terminology_term(術語庫的術語)/dict_source(翻譯字典的條目) |
variant_shadows_term(錯誤)
錯誤變體同時是別處的正確詞。使用者正常說出那個詞,也會被改成別的詞。
shadows 陣列列出被這個變體遮蔽的所有位置(過多時截斷,並附 shadows_total)。
{
"code": "variant_shadows_term",
"severity": "error",
"variant": "抱歉",
"occurrences": [
{ "language": "zh-TW", "index": 0, "variant_index": 0, "term": "報價" }
],
"shadows": [
{ "language": "zh-TW", "index": 1, "term": "抱歉", "kind": "fuzzy_correct" }
]
}
上例:第 0 條規則把「抱歉」當成「報價」的錯字,但第 1 條規則登記「抱歉」是正確詞。結果是使用者說「抱歉」會變成「報價」。
dict_duplicate_source(錯誤)
同一目標語言下,同一個來源詞登記了多個譯法。只有一個會生效,其餘無提示地被忽略。
effective_index 指出 occurrences 裡實際生效的是第幾個(陣列中最後一筆勝)。
{
"code": "dict_duplicate_source",
"severity": "error",
"source": "報價",
"occurrences": [
{ "language": "en-US", "index": 0, "term": "quotation", "kind": "dict_source" },
{ "language": "en-US", "index": 1, "term": "quote", "kind": "dict_source" }
],
"effective_index": 1
}
variant_ambiguous(警告)
同一個錯誤變體對應到不同的正確詞,只有一條會生效。
不提供「哪一條會贏」——先後順序不保證,跨語言尤其不保證。請視為必須擇一修正。
當歧義是由
case_insensitive造成的(例如ALFA與Alfa在忽略大小寫下是同一個變體),variant會是小寫形式,可能與您字庫裡的任何一種寫法都不完全相同。原始寫法請看occurrences[]——每一筆都指向確切的位置。
case_flag_conflict(警告)
同一個錯誤變體在多條規則的 case_insensitive 設定不一致。
effective_case_insensitive 恆為 false:只要有任一條未開啟,該變體即以嚴格比對處理。
variant_equals_term(警告)
錯誤變體與自己那條規則的正確詞相同(開啟 case_insensitive 時,僅大小寫不同也算)。
不會造成任何錯誤結果,但這一筆完全不會產生作用,且佔用數量額度。
duplicate_term(警告)
同一語族下重複登記同一個術語。校正行為不受影響,但重複的條目仍各自佔用術語庫額度。
語族指語言代碼第一個連字號之前的部分:zh-TW 與 zh-CN 屬同一語族,其中一方登記的術語對另一方同樣生效,因此兩邊各登記一次就是重複。zh-TW 與 ja-JP 則不是。occurrences 可能橫跨多個語言代碼。
boost_out_of_range(警告)
value 是您送出的值,clamped_to 是實際生效的值。
{
"code": "boost_out_of_range",
"severity": "warning",
"term": "語者分離",
"at": { "language": "zh-TW", "index": 0, "term": "語者分離" },
"value": 99,
"clamped_to": 5
}
homophone_conflict(警告)
兩個正確詞或術語讀音相同。已登記的詞本身不受影響,但未登記的第三種同音寫法歸給哪一個並不確定。
languages 與 terms 的形狀與即時服務的 config_updated 事件相同,可共用同一套顯示邏輯。
本衝突同時帶 occurrences,反查這些詞登記在字庫的哪些位置(kind 為 terminology_term 或 fuzzy_correct),讓管理介面能直接標到條目;位置過多時帶 occurrences_total。
{
"code": "homophone_conflict",
"severity": "warning",
"languages": ["zh-TW"],
"terms": ["公事包", "公式包"],
"occurrences": [
{ "language": "zh-TW", "index": 0, "term": "公事包", "kind": "terminology_term" },
{ "language": "zh-TW", "index": 1, "term": "公式包", "kind": "terminology_term" }
]
}
此檢查僅對中文有效,且僅在 check_homophones 未關閉時執行。
錯誤回應
| HTTP | error_code | 說明 |
|---|---|---|
| 400 | invalid_json | 請求本體不是合法 JSON |
| 400 | config_too_many_languages | 語言代碼數量超過上限(details 帶 field/count/max)。三個字庫區塊與 transcription_languages/translation_languages 都受此上限保護 |
| 401 | auth_missing_api_key | 未提供 X-API-Key |
| 401 | auth_invalid_key_format | API Key 格式不正確 |
| 401 | auth_invalid_api_key | API Key 無效 |
| 401 | auth_key_expired | API Key 已過期 |
| 401 | auth_key_disabled | API Key 已停用 |
| 403 | auth_ip_not_allowed | 來源 IP 不在白名單內 |
| 403 | auth_user_disabled | 帳戶已停用 |
| 403 | auth_account_blocked | 帳戶已封鎖 |
| 405 | invalid_action | 方法不是 POST。回應帶 Allow 標頭列出支援的方法 |
| 413 | config_payload_too_large | 請求本體超過大小上限(預設 2 MB。details.max_bytes 為目前生效的上限位元組數,見「請求大小上限」) |
| 429 | too_many_requests | 超過頻率限制 |
| 500 | auth_service_error | 認證服務暫時不可用 |
注意:
auth_service_error請重試,不要換金鑰。 它代表我方的認證服務暫時不可用, 與金鑰本身無關;其餘 401 才是金鑰的問題。
字庫本身的問題不會回 4xx——那些一律在 HTTP 200 的 conflicts 與 errors 裡。
跨來源請求
本端點支援瀏覽器直接呼叫:允許 OPTIONS 預檢,回應帶齊跨來源標頭(含 Access-Control-Expose-Headers,讓瀏覽器讀得到限流標頭與 Retry-After);錯誤回應同樣帶跨來源標頭,瀏覽器讀得到 401/413/429 的內容。
重要:從瀏覽器呼叫代表您的 API Key 會出現在瀏覽器端。
本端點與其他端點使用同一把 API Key,那把金鑰同時可以建立錄音、匯入音檔與消耗點數。任何能開啟該頁面的人都能取得它。
因此:
- 若您的字庫管理介面是內部後台(僅自家管理員登入後可見),風險可控,可直接從瀏覽器呼叫
- 若是公開頁面,請改由您的後端轉呼叫,不要把 API Key 放進瀏覽器
從後端呼叫不受跨來源限制影響。
版本:V1.24.1 最後更新:2026-09-28