廣東話優化嘅語音 API — 文字轉語音+語音轉文字
v1最後更新 OpenAPIllms.txt純文字版API Reference
廣東話語音,一個 API — 講得出,又聽得懂
Canto-Gen(港嘢)將廣東話文字轉化為自然、母語水平的語音 — 九聲六調完整保留,語氣詞讀音準確;同一把金鑰亦可將廣東話音訊轉回文字 — 文件轉寫與實時聽寫。附 OpenAPI 3.1 規格。
MCP/Agent 接入
港嘢提供本地 stdio MCP 伺服器(npm 套件 `cantogen-mcp`),零託管成本,為 AI Agent 提供聲線管理與廣東話 TTS 生成能力。註冊後透過 `tools/list` 取得即時工具清單;API key 由使用者自行填入設定檔(如需聲線管理,請勾選 `voices:manage` scope),Agent 全程不會接觸憑證。點擊下方按鈕即可複製設定指示,交由你的 Agent 執行。
支援的 AI 用戶端 / 開發工具
雲端 agent(Manus、Zo Computer 等網頁平台)一樣支援 — 指示會自動轉用 REST API 模式
Codex
AiderMCP tools 一覽
| 工具 | 說明 | 認證要求 | 所需 Scope |
|---|---|---|---|
| get_api_docs | 即場抓最新 API 規格(GET /v1/skill.md,零憑證) | none | |
| list_gallery | 列出官方預設聲線(唯讀) | sk_ key | tts:generate |
| list_my_voices | 列出個人聲線 | sk_ key | voices:manage |
| create_my_voice | 上載本地音頻建立個人聲線(需 plan 支援) | sk_ key | voices:manage |
| delete_my_voice | 刪除個人聲線(即時失效,不可再用於生成;參考音頻 30 日內永久清除;歷史記錄保留聲線名稱) | sk_ key | voices:manage |
| tts_generate | preset 模式生成(指定聲線 slug) | sk_ key | tts:generate |
| generate_design | design 模式生成(gender + age) | sk_ key | tts:generatetts:design |
| generate_clone | clone 模式生成(本地參考音頻;需 plan 支援) | sk_ key | tts:generatetts:clone |
| check_job | 輪詢非同步生成任務狀態至完成(跟進 /v1/audio/jobs 非同步生成流程) | sk_ key | tts:generatetts:design |
| cancel_job | 取消生成任務(未開始 → 全額退款;生成中 → 收尾後取消,已完成部分仍會計費;已終態 → 刪走該生成紀錄) | sk_ key | tts:generatetts:design |
| asr_transcribe | 文件轉寫(batch,按音頻時長計費;長音檔自動轉非同步並 poll 到完成) | sk_ key | tts:generate |
| get_balance | 查預付 HK$ 餘額+ASR 費率+自動儲值設定(零成本查詢) | sk_ key | tts:generate |
| get_usage | 審數:錢包 ledger 明細(游標分頁;零成本查詢) | sk_ key | tts:generate |
| get_asr_vocabulary | 讀取本帳戶儲存的 ASR 關鍵詞詞庫(terms + updated_at;需帳戶開通 asr_vocabulary 功能) | sk_ key | |
| set_asr_vocabulary | 覆寫本帳戶儲存的 ASR 關鍵詞詞庫(整本替換;空陣列 = 清空;需帳戶開通 asr_vocabulary 功能) | sk_ key | |
| delete_transcription | 刪除一條 ASR 轉錄紀錄(連上載嘅音檔;即時失效、唔設復原) | sk_ key | |
| list_generation_jobs | 列出自己嘅生成紀錄(GET /v1/audio/jobs;id/status/created_at/voice_slug/duration_ms/text_preview;游標分頁) | sk_ key | tts:generatetts:design |
| set_telemetry_opt_out | 開/關匿名使用統計(PUT /v1/account/telemetry;關咗就唔會再收自動行為遙測,主動評分/回報照收) | sk_ key |
AI agent 適用 MCP
取得 API 金鑰
API 請求以 Bearer 方式驗證你的金鑰。金鑰只在建立時顯示一次 — 伺服器端僅儲存 SHA-256 hash,遺失的金鑰只能撤銷後重新建立。
金鑰前綴
| sk_live_… | 唯一的金鑰格式。免費方案金鑰受每日生成上限約束;付費方案用量計入該金鑰的每月 credits 上限。 |
Scopes
| tts:generate | 預設。開放 voice 及 design 生成,以及所有讀取 endpoint(聲線目錄、任務查詢)。 |
| tts:clone | clone 模式(以參考樣本複製聲音)必須使用此 scope。 |
| tts:design | design 模式(gender + age 合成聲線)的細粒度 scope — 已由 tts:generate 涵蓋,兩者其一即可。 |
| voices:manage | 個人聲線管理(MCP 的 list / create / delete my voices)必須使用此 scope。 |
每把金鑰附帶的限制
GET /v1/voices(公開聲線目錄,可匿名存取)外,所有 REST endpoint 均以 Authorization: Bearer $CANTOGEN_API_KEY 驗證。定價
API 存取為付費方案(輕量/入門/專業/工作室)專屬,全速無每日上限。免費方案用戶亦可以建立 API 金鑰試用(每日上限 50 個生成請求;輪詢與下載不計入),升級即解鎖全速存取。
非同步 1 字 = 1 credit,無附加費
POST /v1/audio/speech)按 1.3 倍計量。credits 池用完可購買 Credit Pack。每個請求的 X-Credits-Charged 回應 header 顯示實扣 credits 數(已含倍數)。商用授權 — 邊啲音頻可以商用?
詞彙表
- 每日生成上限 — 免費方案金鑰每日 50 個生成請求(輪詢與下載不計);付費方案無每日上限。
- 金鑰每月 credits 上限 — 每把金鑰本月(UTC)累計計費 credits 的上限,超出回 403 monthly_cap_reached;預設不設上限。
- 帳戶 credits 池 — 帳戶層級的 credits 餘額,網頁 Playground 與 API 共用,按帳單週期重置;不足時回 402 character_limit_reached。
- Credit Pack — 為帳戶 credits 池一次性增值,永不過期。
- 待處理任務上限 — 同一帳戶可同時 pending 的任務數,按方案分級(3/4/5/10/20/20);超限回 429 in_flight_limit_reached。
方案詳情及價錢見/pricing。
快速入門
三分鐘完成第一次生成:列出聲線目錄 → 提交語音任務 → 輪詢結果。
列出聲線目錄(GET /v1/voices)
curl https://canto-gen.com/v1/voices \
-H "Authorization: Bearer $CANTOGEN_API_KEY"{
"voices": [
{
"slug": "sum",
"name": "心妍",
"gender": "female",
"age": "adult",
"styles": [],
"preview_url": "https://canto-gen.com/api/voice-clip?slug=sum"
}
]
}聲線目錄為即時資料 — 請務必從你自己的回應中挑選 slug。此處的 "sum"(心妍)僅為文件示例,或在Playground 圖庫親耳試聽。
提交語音任務(POST /v1/audio/jobs)
# Async by design — submit returns 202 with a job_id, then poll.
export CANTOGEN_API_KEY="sk_live_…"
curl -X POST https://canto-gen.com/v1/audio/jobs \
-H "Authorization: Bearer $CANTOGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "cantogen-tts",
"voice": "sum",
"text": "你好,歡迎使用港嘢!",
"response_format": "mp3"
}'回應 — 202 Accepted:
HTTP/1.1 202 Accepted
Content-Type: application/json
{
"job_id": "b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
"status": "queued",
"poll_url": "/v1/audio/jobs/b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
"srt_requested": false
}非同步為本 — 附同步快捷方式
job_id / status / poll_url / srt_requested。無需長連接,長文字不會逾時 — 按自身節奏輪詢即可。短文字(≤300 credits、voice/design)可用 POST /v1/audio/speech 直接取得音訊 bytes(200);同步隊列忙時回傳 503 pool_cold(不扣費;等待超過約 45 秒會 cancel+退款並回 503 sync_timeout)。聲線目錄
以下聲線與風格 preset 全部由資料庫自動同步 — 新增聲線或風格後,本頁自動更新。每個聲線均可在 Playground 試聽。
| slug | 名稱 | 性別 | 年齡 | 場景 | 試聽 |
|---|---|---|---|---|---|
| 暫時未有聲線。 | |||||
生成參數 presets(節奏・情緒・音色)
presets 係生成參數,配任何 slug 都得 — 同樣由資料庫同步。
聲音模式
選用圖庫聲線、以文字描述一個新聲線、或由樣本複製。每次請求只可使用其中一種模式。
三種模式互斥
voicedefault圖庫聲線
以 slug 直接選用廣東話優化圖庫中的現成聲線。
- 瀏覽 GET /v1/voices — 所有預設聲線均以廣東話為母語,附試聽片段。
- 將 slug 作為 voice 參數傳入。文件示例為 sum(心妍)— 請務必從你自己的回應中挑選 slug。slug 為 ASCII 穩定識別符(行業標準做法),中文名作介面顯示之用。
# Async by design — submit returns 202 with a job_id, then poll.
export CANTOGEN_API_KEY="sk_live_…"
curl -X POST https://canto-gen.com/v1/audio/jobs \
-H "Authorization: Bearer $CANTOGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "cantogen-tts",
"voice": "sum",
"text": "你好,歡迎使用港嘢!",
"response_format": "mp3"
}'designzero audio設計聲線
以純文字描述一個合成聲線 — 指定 gender 與 age,無需上載任何音訊檔。
- gender: male | female · age: child | teenage | adult | midage | elder — 兩項均必填。
- 適合產品人設;可自由搭配 emotion 及 srt 參數。
curl -X POST https://canto-gen.com/v1/audio/jobs \
-H "Authorization: Bearer $CANTOGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "cantogen-tts",
"design": { "gender": "female", "age": "adult" },
"text": "今日天氣幾好,一齊去行山啦。",
"style": "brisk",
"emotion": "happy",
"srt": true
}'clonetts:clone scope複製聲線
上載參考樣本 — 平台在內部轉錄(ASR)並自動套用逐字稿,客戶端無需額外呼叫。
- reference_audio: data URL 或 raw base64 — 支援 audio/mpeg、wav、webm、mp4/m4a、ogg。單一請求上限 4.4 MB(base64 編碼後音訊約 ≤3 MB)。
- 樣本至少 8 秒(不足會被拒絕);處理時按句界自動裁至約 15–20 秒、上限 30 秒 — 乾淨樣本效果最佳。
- 只需 reference_audio;舊版 prompt_text 欄位已退役(送出會被忽略)。
- 需要具備 tts:clone scope 的 API 金鑰。
B64=$(base64 -w0 sample.wav)
curl -X POST https://canto-gen.com/v1/audio/jobs \
-H "Authorization: Bearer $CANTOGEN_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"cantogen-tts\",
\"clone\": {
\"reference_audio\": \"data:audio/wav;base64,$B64\"
},
\"text\": \"用我把聲講呢句嘢。\"
}"生成參數(所有模式共用)
| style | 演繹風格 — 建議使用英文 slug:節奏 steady(平穩) / composed(從容) / rapid(急促) / slow(慢板) / drawl(拖長) / brisk(明快) / dynamic(起伏) / staccato(頓挫);音色 mellow(圓潤) / cute(奶音) / sharp(尖細) / lazy(懶音) / breathy(氣聲) / hoarse(沙啞) / deep(洪厚) / crisp(清脆) / feeble(無力) / trembling(顫音);場景/角色 slug 同樣接受(corporate/promo/…/storytelling(講古)/sports 等)。原有中文 preset 值(明快/圓潤 等)仍作別名接受 — 兩者內部會正規化到同一 canonical 值;其他自由文字原樣接受。 |
| emotion | 9 個支援值其中之一(見下方 chips)。注意:API enum 使用英文值(happy/excited 等),並以英文原樣傳入引擎;與 Playground 介面的中文情緒 preset(雀躍/冷靜 等)屬兩套不同體系 — 中文情緒 preset 僅限 Playground 使用,API emotion 參數不接受中文值。 |
| instruction | 自由文字演繹指示,上限 500 字。優先次序:style → emotion → instruction — instruction 有最終決定權。 |
| pitch | 已棄用(2026-09-20):原音交付下不生效(接受參數但忽略其值)。歷史範圍 −12…+12 半音,預設 0。 |
| volume | 已棄用(2026-09-20):原音交付下不生效(接受參數但忽略其值)。歷史範圍 0–10,預設 1。 |
| response_format | mp3(預設)/ wav。 |
| srt | true → 完成後的任務附帶 srt 欄位(以較高 credits 費率計費)。全方案適用。 |
參數上限
text (async)— POST /v1/audio/jobs 文字上限 500 字;超出回 400 text_too_long,不會截斷。text (sync)— POST /v1/audio/speech 上限 300 計費 credits(voice/design);超出請改用非同步。instruction— 自由文字演繹指示上限 500 字;超出回 400 invalid_instruction。style— 英文 slug(節奏/音色/場景/角色);原有中文 preset 值作別名接受,兩者正規化到同一 canonical 值;其他自由文字原樣接受。emotion— 9 個英文封閉 enum 值之一(見 chips);不接受中文值。synthesis order— style → emotion → instruction;instruction 有最終決定權。clone.reference_audio— base64 data URL 或 raw,單一請求 ≤4.4 MB(音頻約 ≤3 MB);只需 reference_audio — 舊版 prompt_text 已退役(送出會被忽略)。design— gender(male/female)+ age(child/teenage/adult/midage/elder;legacy teen/young 照收)。speed— 已移除(2026-10-14)— 送入會被靜默忽略;語速可透過 clone `control` 描述表達(慢/正常/快)。transcription(文件轉寫)— POST /v1/asr/transcribe — 同步 route 單檔實際上限 4.5 MB(平台 body 上限;Opus 16k 壓縮後單檔約載 33–40 分鐘音頻);同步交付上限 8 分鐘(480 秒),超過回 400 audio_too_long(零扣費)— 長音檔改用 POST /v1/asr/jobs(上限 4 小時);冇每日音訊上限(所有 plan 一視同仁,用量只由預付餘額 bound);response_format 支援 json/text(srt/verbose_json 暫不支援)。usage(用量明細)— GET /v1/usage — 預付錢包 ledger 明細(kind/金額/餘額/單位/用量/費率),游標分頁;另附 `summary` 用量摘要(本期 period start/已用 credits/配額/剩餘/credit 池/預付餘額),唔使人肉逐筆加總就可以對帳。asr jobs(非同步提交)— POST /v1/asr/jobs — upfront async:提交即 202 queued,poll GET /v1/asr/transcriptions/{id} 收文字;multipart(≤4.5MB)、audio_url(server 下載,繞過 4.5MB)或 storage_path(browser session 限定,至 500MB/4 小時)。
輪詢與 SRT
短文字任務通常數秒內完成。以 2–5 秒退避輪詢至任務完成,然後下載預簽名音訊。
POST /v1/audio/jobs202 · job_idGET /v1/audio/jobs/{id}輪詢 · 2–5 秒退避status: completedaudio_url 就緒GET audio_url預簽名 · 無需驗證查詢任務狀態
curl https://canto-gen.com/v1/audio/jobs/b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b \
-H "Authorization: Bearer $CANTOGEN_API_KEY"完成後的回應
{
"job_id": "b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
"status": "completed",
"poll_url": "/v1/audio/jobs/b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
"srt_requested": true,
"srt": "1\n00:00:00,000 --> 00:00:02,400\n你好,歡迎使用港嘢!",
"audio_url": "https://canto-gen.com/storage/v1/object/sign/audio_history/..."
}// Poll until completed — back off 2–5 s between attempts.
async function pollJob(jobId, maxAttempts = 60) {
for (let i = 0; i < maxAttempts; i++) {
const res = await fetch(`https://canto-gen.com/v1/audio/jobs/${jobId}`, {
headers: { Authorization: `Bearer ${process.env.CANTOGEN_API_KEY}` },
});
const job = await res.json();
if (job.status === "completed") return job; // job.audio_url is ready
if (job.status === "failed" || job.status === "cancelled") {
throw new Error(`job ${job.status}`);
}
await new Promise((r) => setTimeout(r, Math.min(2000 + i * 500, 5000)));
}
throw new Error("poll timeout");
}audio_url 會過期 — 請盡早下載
字幕(SRT)
提交時傳入 "srt": true,完成後任務的查詢回應會附上 srt 欄位,內容為字幕(如上方完成回應所示)。srt_requested 欄位必定存在;srt 只在已要求且已就緒時出現。SRT 字幕輸出全方案適用。
計費細節
Rate limit 與上限
| 回應 header | 說明 |
|---|---|
| X-RateLimit-Limit | 此金鑰的每分鐘請求上限(預設 60;可在建立金鑰時設定)。 |
| X-RateLimit-Remaining | 目前 60 秒滑動視窗內剩餘的請求次數。 |
| X-RateLimit-Reset | 視窗重設時間(Unix epoch 秒)。 |
| Retry-After | 附於 429 回應;請等候指定秒數再重試。 |
每月 credits 上限 — 金鑰本月至今(UTC)的計費 credits 數必須低於其上限(null = 無限制)。超限會回傳 403 monthly_cap_reached 並附 used 數字,直至該月重設。X-RateLimit-* headers 附於 POST /v1/audio/jobs 的 202 及 429 回應、以及 POST /v1/audio/speech 的 429 回應(200 回應附帶 X-Credits-Charged 等 usage headers);讀取 endpoint(GET /v1/audio/jobs/{id}、GET /v1/voices)不受 rate limit 限制。兩個計量器均以「故障時放行」為設計原則 — 計量系統故障絕不會令請求被拒。
文件轉寫(ASR)
上載音檔,同一請求內同步回傳文字 — sync-first,超長音頻自動升格非同步。以廣東話為本。
同步交付 — 一個 curl 搞定
文件轉寫 — 上載音檔,同一請求內同步回傳文字。Canonical path:POST /v1/asr/transcribe;以 multipart/form-data 傳送。欄位:file(必填)、model(必填)、language(選填,ISO-639-1)、response_format(json 預設/text)。srt/verbose_json 需要段級時間標記,暫不支援(回 400 unsupported_response_format)。可選 vocabulary(上限 50 詞,關鍵詞偏置,asr_vocabulary 權限限定;無權限靜默忽略)— 冇帶呢個欄位時(API key 請求)自動套用你帳戶儲存嘅詞庫(PUT /v1/asr/vocabulary),帶咗(包括空陣列)就以請求為準。現階段轉寫以廣東話為本。
curl -X POST https://canto-gen.com/v1/asr/transcribe \
-H "Authorization: Bearer \$CANTOGEN_API_KEY" \
-F file=@sample.wav \
-F model=cantogen-asr \
-F response_format=json200 回應
{
"id": "b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
"object": "transcription",
"text": "今日天氣幾好,一齊去行山啦。",
"duration_seconds": 1830,
"charged_hkd": 0.4067
}超過同步交付上限(480 秒)→ 400 audio_too_long
400 audio_too_long(帶 duration_seconds+async_endpoint,處理前拒、零扣費)— 同一 route 只有一種成功形狀,行為由檔案時長話事、唔受伺服器負載影響。長音檔正路:POST /v1/asr/jobs(非同步,上限 4 小時/500MB)— 提交即 202 queued,GET /v1/asr/transcriptions/{id} poll 文字;同一錢包計費語義。計費
按音頻時長計費(預付 HK$ 餘額;1 HK$ = 1,000 credits)— 文件轉寫 800 credits/小時(HK$0.80/小時)、實時聽寫 1,400 credits/小時(HK$1.40/小時,1.75 倍),按秒計費、不進位。請求受理前先按偵測到的時長預扣,完成後按實際時長結算;失敗、超時或服務不可用一律全額退回(只扣成功)。餘額不足回 402 insufficient_balance — 請前往 /account/billing 儲值後重試。費率與餘額(credits/HKD 兩版)可用 GET /v1/balance 查詢。
上限
file size— 同步 route 單檔實際上限 4.5 MB(平台 request body 上限;超出回平台層 413 — 建議先壓縮:ffmpeg -i in.* -vn -ac 1 -ar 16000 -c:a libopus -b:a 16k out.ogg,16kHz mono Opus 16k 單檔約載 33–40 分鐘)。audio duration— 同步交付上限 8 分鐘(480 秒):probe 到超過 →400 audio_too_long(帶duration_seconds+async_endpoint,處理前拒、零扣費)— 長音檔改用POST /v1/asr/jobs(非同步,上限 4 小時/500MB)。單請求音頻政策上限 4 小時(超出回 413)。daily cap— 冇每日音訊上限(2026-10-30 起對所有 plan 一視同仁,包括免費)— 用量只由預付餘額 bound(credit 池 + 錢包 hold)。
查詢餘額與費率
查詢預付餘額(HKD;1 HK$ = 1,000 credits — 回應同時帶 balance_credits credits 版餘額)、文件轉寫/實時聽寫費率(credits/HKD 兩版:800/1,400 credits 每音頻小時)與自動儲值設定。測試金鑰期間回傳測試環境餘額(與正式環境互相隔離)。餘額不足請前往 /account/billing 儲值(可開啟自動儲值 — 餘額跌低門檻時自動增值)。
curl https://canto-gen.com/v1/balance \
-H "Authorization: Bearer \$CANTOGEN_API_KEY"ASR 關鍵詞詞庫
一本 per-account 嘅詞表 — 幫 ASR 認出專有名詞、機構名同英文縮寫。
關鍵詞詞庫(keyword biasing)— 一本 per-account 嘅詞表,幫 ASR 認出專有名詞、機構名同英文縮寫。三個 method:GET 讀取、PUT 整本覆寫、DELETE 清空(等效 PUT {"terms": []})。同一帳戶嘅所有金鑰共用同一本詞庫(per-account,唔係 per-key);詞表會喺 server 端清理(trim/去重/丟超過 30 字嘅詞/最多 50 個)之後先儲存,回應會附上實際儲存咗嘅內容。
清理規則
terms— 最多 50 個詞(超出嘅由頭截斷)term length— 每個詞最多 30 字(超出嘅詞唔會儲存)cleanup— trim 空白、Unicode NFC 收斂、去掉重複詞(保留第一次出現嘅)
讀取 — GET /v1/asr/vocabulary
curl https://canto-gen.com/v1/asr/vocabulary \
-H "Authorization: Bearer \$CANTOGEN_API_KEY"{
"scope": "api",
"terms": ["證監會", "庫務局", "Canto-Gen"],
"updated_at": "2026-10-28T09:12:33.000Z"
}覆寫 — PUT /v1/asr/vocabulary
curl -X PUT https://canto-gen.com/v1/asr/vocabulary \
-H "Authorization: Bearer \$CANTOGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"terms": ["證監會", "庫務局", "Canto-Gen"]}'清空 — DELETE /v1/asr/vocabulary
curl -X DELETE https://canto-gen.com/v1/asr/vocabulary \
-H "Authorization: Bearer \$CANTOGEN_API_KEY"每次請求帶 `vocabulary`
每次請求都可以帶 vocabulary(字串陣列)做即時偏置 — POST /v1/asr/transcribe、POST /v1/asr/jobs 同 POST /v1/asr/realtime/token(實時轉寫)都收。API key 同 browser session 客戶一樣可以帶(sk_ 憑證或 browser session)。空陣列係明確覆蓋(今次唔做任何偏置);冇帶呢個欄位就係「用預設」語意(下一段)。
儲存詞庫幾時會自動套用
儲存嘅詞庫只係 API key 請求嘅預設:sk_ 客戶嘅轉寫請求如果冇帶 vocabulary 欄位,就會自動套用本帳戶儲存嘅詞庫;帶咗參數(包括空陣列)就以請求為準,永遠唔會 fallback 去儲存嗰份。Browser session(Playground)客戶唔受呢條預設影響 — session 請求冇帶參數就係冇偏置。
權限
asr_vocabulary 權限)。未開通嘅話,三個 method 一律回 403 {"error":"asr_vocabulary_not_granted"},並附一句點做嘅提示(聯絡 support 開通功能後再試)。開通咗之後,轉寫請求帶住 vocabulary 但仍然冇呢個權限 → 該次請求會忽略詞庫(唔會影響轉寫本身)。實時 WebSocket(Realtime)
適合互動式、低延遲的語音場景。
除 REST 外,港嘢另提供 WebSocket 實時端點:在單一長連線上傳送文字並接收串流 PCM 音訊,適合自帶 LLM 的語音應用。協議以 OpenAI Realtime 為基礎;港嘢新增的事件與欄位一律標明為 extension。
wss://api.canto-gen.com/v1/audio/realtime
認證
認證方式與 REST 相同:sk_ API 金鑰,所需 scope 為 tts:generate。優先使用 Authorization: Bearer sk_… header;瀏覽器 WebSocket API 無法設定自訂 header,可改用 query 參數 ?api_key=sk_…(別名 ?token=)。query 參數會寫入 URL、伺服器日誌與瀏覽器歷史,存在洩漏風險,僅限瀏覽器環境使用;伺服器端請求一律使用 header。
事件 — client → server
| session.update | OpenAI 原生 | 建立/更新 session 設定:voice、language、output_audio_format、max_session_chars、tts.segmentation(`max_session_chars` 亦可於連線時用 query `?max_session_chars=` 指定,一律被 clamp 落 plan 上限)。 |
| conversation.item.create | OpenAI 原生 | 提交一段明確文字(input_text);觸發合成。 |
| input_text.append | 港嘢 extension | 串流傳送原始 token delta。 |
| input_text.commit | 港嘢 extension | 強制段落邊界(立即 flush)。 |
| response.create | OpenAI 原生 | 觸發合成。 |
| response.cancel | OpenAI 原生 | barge-in:停止當前句子並退款。 |
| session.close | 港嘢 extension | 主動關閉連線並結算。 |
事件 — server → client
| session.created | OpenAI 原生 | 連線建立;附伺服器簽發(server-minted)的 session id,同**生效值** `max_session_chars`(已被 clamp 落 plan 上限)。 |
| session.updated | OpenAI 原生 | 設定更新確認。 |
| response.created | OpenAI 原生 | 單句開始合成。 |
| response.output_audio.delta | OpenAI 原生 | base64 PCM16 @ 48 kHz 音訊 chunk。 |
| response.output_audio.done | OpenAI 原生 | 單句音訊完成。 |
| response.done | OpenAI 原生 | 單句結束;usage 附 input_chars/billed_chars/remaining(extension 欄位)。 |
| error | OpenAI 原生 | {type, code, message, http_status}。 |
切句模式(tts.segmentation)
tts.segmentation(extension)控制切句方式:{"mode":"server"}(預設)由伺服器按標點自動切句並逐句合成 — client 只需持續 append token;{"mode":"client"} 則由 client 透過 conversation.item.create / input_text.commit 自行決定段落邊界。可選 min_chars / max_chars / punctuation。
限制與逾時
billing— 逐句(per utterance)reserve→complete/退款;實扣 = ceil(輸入字符 × 1.5)(2026-11-08 起 WS realtime 倍數,SSOT = constants.ts WS_REALTIME_CHARACTER_MULTIPLIER)。失敗/barge-in 自動退款。`response.done` usage:`input_chars` = raw 輸入、`billed_chars` = 實扣(含倍數)、`remaining` = 餘額。idle_timeout— 閒置 120 秒(無任何 app-level 活動)→ 伺服器關閉連線並結算。max_session_duration— free plan 單一 session 最長 5 分鐘;付費 plan 無時長上限(達全域上限時關閉)。max_sessions_per_user— 同一用戶的同時 session 上限按 plan 階梯:free 1/lite 2/starter 3/pro 4/studio 5/enterprise 5;未知 plan 一律視為 free。max_sessions_global— 全平台同時最多 8 個 session。max_session_chars— 每個 session **輸入**字符上限(**免費 2,000 字/付費 20,000 字**;按輸入字符量度 — 實扣另乘 WS ×1.5 倍數,見 billing);server 端 clamp — client 經 `session.update`(或連線時 query `?max_session_chars=`)只可以要求更低,唔可以高過 plan 上限;超出回 session_char_limit_exceeded。生效值會喺 `session.created` 直接回傳(唔使行多次 `session.update` 先知)。max_in_flight— 每 session 同時最多 3 句未結算。raw_ingress— 每 session 原始輸入上限 20,000 字、每分鐘 5,000 字(標點與空白亦計);超出回 raw_limit_exceeded,即時拒絕。lease— 每句合成有 60 秒結算租約;逾時未完成會自動退款。rate_limit / monthly_cap— 每用戶每分鐘 rate limit(同一帳戶嘅所有金鑰加埋計 — 開多把金鑰唔會突破總額;單把金鑰另外有較細上限);每月 credits 上限按金鑰計。用量帳本逐句記錄(per utterance)。daily_generation_limit— 免費方案每日 50 個生成句(與 REST 共用同一計數,輪詢與下載不計);超出回 sandbox_daily_limit(429),付費方案無每日上限。frame_size— 單一 WS 訊息上限 64 KiB。heartbeat— 伺服器定期 ping;心跳不計入 app 活動。
// npm i ws — one long-lived connection: stream tokens in, stream PCM out.
import WebSocket from "ws";
const ws = new WebSocket("wss://api.canto-gen.com/v1/audio/realtime", {
headers: { Authorization: `Bearer ${process.env.CANTOGEN_API_KEY}` },
});
ws.on("open", () => {
ws.send(JSON.stringify({
type: "session.update",
session: { voice: "sum", language: "yue", output_audio_format: "pcm16", max_session_chars: 500 },
}));
// One explicit utterance — or keep sending input_text.append deltas.
ws.send(JSON.stringify({
type: "conversation.item.create",
item: { type: "message", content: [{ type: "input_text", text: "你好,歡迎使用港嘢!" }] },
}));
});
const chunks = [];
ws.on("message", (raw) => {
const ev = JSON.parse(raw.toString());
if (ev.type === "session.created") console.log("session", ev.session.id);
if (ev.type === "response.output_audio.delta") chunks.push(Buffer.from(ev.delta, "base64"));
if (ev.type === "response.done") {
// PCM16 @ 48 kHz — feed an AudioWorklet or write the chunks to disk.
console.log("billed", ev.response.usage.billed_chars, "remaining", ev.response.usage.remaining);
ws.close();
}
if (ev.type === "error") console.error(ev.error.code, ev.error.message);
});錯誤碼
| invalid_api_key | 401 | 金鑰缺失、無效、過期或 scope 不符。 |
| rate_limit_exceeded | 429 | 觸及每用戶每分鐘上限(同一帳戶嘅所有金鑰加埋計);附 retry_after。 |
| sandbox_daily_limit | 429 | 免費方案每日 50 個生成句已用完(與 REST 共用計數);明日再試或升級方案。 |
| monthly_cap_reached | 429 | 已達金鑰本月 credits 上限。 |
| character_limit_reached | 402 | 帳戶 credits 池不足,該句不會合成。 |
| concurrency_limit_reached | 429 | 同時 session 或同時未結算句數已達上限。 |
| session_char_limit_exceeded | 403 | 已達本次 session 字數上限。 |
| raw_limit_exceeded | 413 | 原始輸入量(含標點/空白)超出上限。 |
| text_too_long | 400 | 單段文字超出上限。 |
| invalid_session | 400 | session 已關閉或狀態無效。 |
| engine_unavailable | 503 | 實時引擎暫時不可用;請重試。 |
實時轉寫 WebSocket
實時聽寫 — 麥克風即時字幕、voice agent 轉寫等低延遲場景。
實時聽寫 — 單一長連線串入 PCM 音訊、串出轉寫:transcription.delta = 增量文字(append-only、單調遞增,永不改寫已發佈內容;約每 2 秒一段)+transcription.done = 最終全文。適合麥克風即時字幕、voice agent 轉寫等低延遲場景。1,400 credits/音頻小時(HK$1.40/音頻小時;1 HK$ = 1,000 credits)(batch 的 1.75 倍)、按秒計費、只收成功音訊。client final commit 之後 gateway 會喺 done 一到即刻收線(≤6s 兜底)。語言:連線 query 可帶 ?profile=<id>(auto-v1/yue-zh-en-mixed-v1/yue-trad-v1/zh-cmn-v1/en-v1;未知 id → 1008 invalid_profile)。
wss://api.canto-gen.com/v1/asr/realtime
認證
伺服器端:Authorization: Bearer sk_…。瀏覽器:永遠唔准將永久 API key 放入 URL — 先喺伺服器端叫 POST /v1/asr/realtime/token 簽一枚短命 ephemeral token(cst_…,60–600 秒,預設 300),再用 ?token=<cst_…> 開 WS(canonical;?api_key= 仍收做過渡 alias — 2026-10-21 gateway 正名,e2e 兩式實測 PASS)。可選 vocabulary(關鍵詞偏置,上限 50 詞,asr_vocabulary 權限限定;無權限靜默忽略)— sk_ 同 session caller 都帶得。
curl -X POST https://canto-gen.com/v1/asr/realtime/token \
-H "Authorization: Bearer \$CANTOGEN_API_KEY" -H "Content-Type: application/json" \
-d '{"expires_in_seconds":300}'協議次序
| 伺服器 ▶ 你 | {"type":"gateway.welcome","rate_hkd_per_hour":1.4,…} |
| 伺服器 ▶ 你 | {"type":"session.created",…} |
| 你 ▶ 伺服器 | {"type":"session.update","model":"asr"} |
| 你 ▶ 伺服器 | {"type":"input_audio_buffer.commit","final":false} |
| 你 ▶ 伺服器 | {"type":"input_audio_buffer.append","audio":"<b64>"} × N |
| 伺服器 ▶ 你 | {"type":"transcription.delta","delta":"…"} |
| 你 ▶ 伺服器 | {"type":"input_audio_buffer.commit","final":true} |
| 伺服器 ▶ 你 | {"type":"transcription.done","text":"…"} |
音訊格式與轉檔
音訊 = PCM16LE mono 16 kHz base64(32,000 bytes = 1 秒);單 frame ≤640KB、平均 ≤640KB/s。送錯 sample rate 會得到垃圾轉寫並按收到的 bytes 計費 — 轉檔責任在 client(業界標準):瀏覽器用 new AudioContext({ sampleRate: 16000 }) 取 mic;Node/檔案用 ffmpeg -i in.any -f s16le -ar 16000 -ac 1 out.pcm。關閉前會收 gateway.close(code+reason)。連線 query 可宣告格式:?sample_rate=8000–48000&channels=1|2;送容器檔(WAV/MP3/Ogg/FLAC)→ 4010 invalid_audio_format(零計費)— 要 raw PCM16LE。
計費與上限
billing— 1,400 credits/音頻小時(HK$1.40/音頻小時;1 HK$ = 1,000 credits;batch 的 1.75 倍)、按秒計費不進位;連線前驗餘額(唔夠一個 tick → 4002);session 中每 60 秒 in-arrears 預扣(唔夠 → 4009);收線按實際音頻秒結算(billed == audio)。實時用量同批次轉寫用量分開計。max_sessions_global— 全平台同時 10 條 session;每 key 同時 free 2/paid 4 條。session duration / idle— 冇單 session 長度上限(2026-10-30 起對所有 plan 移除);閒置(無 client frame)120 秒收線;每 60 秒計費 tick 預扣,餘額唔夠即 close(4009)。format declaration— 連線 query?sample_rate=8000–48000&channels=1|2— 計費秒數按宣告 bps 折算;唔宣告 = 16kHz mono 契約。
WS close codes
| 1000 | completed | 正常完(done 已收)。 |
| 1001 | idle_timeout | 逾時無任何 client frame(120s)。 |
| 1008 | protocol_violation | 壞 protocol/binary frame/base64 壞/超速。 |
| 1009 | message_too_big | 單 frame > 640KB。 |
| 1011 | engine_lost | 引擎中途收線。 |
| 1013 | engine_unavailable | 引擎連唔上。 |
| 4001 | invalid_or_expired_token | key 無效/過期/撤銷。 |
| 4002 | insufficient_balance | 連線前餘額唔夠。 |
| 4008 | capacity_exceeded | 同時 session 爆 cap(global 10/per-key free 2/paid 4)。 |
| 4009 | insufficient_balance | session 中餘額唔夠下一筆 hold。 |
| 4010 | invalid_audio_format | 送咗容器檔(WAV/Ogg/FLAC/MP3)— 要 raw PCM16LE mono 16kHz(ffmpeg -ac 1 -ar 16000 -f s16le)。 |
// npm i ws — one long-lived connection: stream PCM in, transcript out.
import WebSocket from "ws";
const ws = new WebSocket("wss://api.canto-gen.com/v1/asr/realtime", {
headers: { Authorization: `Bearer ${process.env.CANTOGEN_API_KEY}` },
});
ws.on("open", () => {
ws.send(JSON.stringify({ type: "session.update", model: "asr" }));
ws.send(JSON.stringify({ type: "input_audio_buffer.commit", final: false }));
// feed 16 kHz mono s16LE chunks as they come off the mic / file
ws.send(JSON.stringify({ type: "input_audio_buffer.append", audio: pcmChunk.toString("base64") }));
});
ws.on("message", (raw) => {
const ev = JSON.parse(raw.toString());
if (ev.type === "transcription.delta") process.stdout.write(ev.delta);
if (ev.type === "transcription.done") { console.log(ev.text); ws.close(); }
});錯誤碼
錯誤回應使用穩定的機器可讀 error 代碼,另附可選的人類可讀 message。
{
"error": "text_too_long",
"message": "text exceeds 500 characters."
}| HTTP | error code | 原因 | 處理方法 |
|---|---|---|---|
| 400 | invalid_model | model 必須是 "cantogen-tts"(或省略)。 | 省略 model,或設為 "cantogen-tts"。 |
| 400 | voice_mode_conflict | 同時傳入了多於一個 voice / design / clone — 三種模式互斥。 | 每次請求只傳入一種聲音模式。 |
| 400 | text_required | text 缺失或空白。 | 傳入非空 text(1–500 credits)。 |
| 400 | text_too_long | text 超過 500 credits。 | 請拆分文字 — 超限請求會被拒絕,不會截斷處理。 |
| 400 | unsupported_format | response_format 必須是 mp3 或 wav。 | 使用 mp3 或 wav。 |
| 400 | invalid_pitch | pitch 必須介乎 −12 至 +12 半音。 | 將 pitch 調整至有效範圍。 |
| 400 | invalid_volume | volume 必須介乎 0 至 10。 | 將 volume 調整至有效範圍。 |
| 400 | invalid_emotion | emotion 不在 9 個支援值之內。 | 使用 9 個支援的情緒值之一。 |
| 400 | invalid_srt | srt 必須是 boolean。 | 使用 true / false。 |
| 400 | reference_audio_required | clone.reference_audio 缺失。 | 附上 base64 參考樣本。 |
| 400 | invalid_reference_audio | clone.reference_audio 不是有效的 base64 音訊。 | 傳入 data URL(data:audio/…;base64,…) 或 raw base64。 |
| 400 | invalid_reference_audio_size | clone.reference_audio 音頻超過約 3 MB(JSON API 單一請求上限)。 | 縮短樣本(至少 8 秒即可)再試。 |
| 400 | spoken_text_required | text 無可朗讀內容 — 計費 credits 為 0(只剩標點/空白/emoji/tone tags)。 | 傳入含可讀文字的 text。 |
| 400 | design_gender_and_age_required | design.gender 與 design.age 兩項均必填。 | 同時提供兩個欄位。 |
| 400 | invalid_job_id | 查詢或取消所用的 id 不是 UUID。 | 檢查 job_id。 |
| 400 | invalid_request | body 不是有效 JSON,或 Content-Type 非 JSON(/v1 僅接受 application/json);文件轉寫則為 multipart 缺 `file`/`model`、音檔為空或音檔格式不支援。 | 以 Content-Type: application/json 傳送合法 JSON body。 |
| 413 | payload_too_large | 請求超過大小上限 — JSON API 4.4 MB(clone 參考樣本);文件轉寫同步 4.5 MB(平台 request-body 上限);非同步 jobs audio_url/storage_path 500 MB。 | 同步:壓縮成 16kHz mono Opus 16k(≈33–40 分鐘/4.5MB)或改用 POST /v1/asr/jobs(audio_url/storage_path 至 500MB)。 |
| 401 | invalid_or_expired_token | API 金鑰缺失、無效、已過期或已被撤銷。 | 建立新金鑰並檢查 Bearer header。 |
| 402 | character_limit_reached | 帳戶 credits 池不足以完成本次生成(回應內含 remaining)。 | 購買 Credit Pack 或等待月度重置。 |
| 403 | insufficient_scope | 金鑰缺少所需 scope(複製聲音需要 tts:clone);回應內含 "scope"。 | 建立具備所需 scope 的金鑰。 |
| 403 | monthly_cap_reached | 金鑰的每月 credits 上限已達;回應內含 "used"。 | 等候 UTC 月份重設,或調高上限。 |
| 404 | job_not_found | 沒有此 id 的任務(或任務屬於另一金鑰)。 | 檢查 job_id 及提交時所用的金鑰。 |
| 409 | already_settled | 任務已屬終態(completed/failed/cancelled),無法再取消,亦不會退款。 | 改以 GET /v1/audio/jobs/{id} 查詢最終狀態。 |
| 409 | duplicate_request | 同一個 Idempotency-Key(alias x-idempotency-key)已提交過(重試安全:不會重複扣費)。 | 沿用原本的 job_id 輪詢,或以新 key 提交新任務。 |
| 404 | not_found | 沒有此 endpoint(路徑有誤)。 | 對照 /v1/openapi.json 的路徑。 |
| 403 | batch_requires_pro | 批量生成(items)為入門/專業/工作室方案功能。單句任務的並行上限按方案分級(free 3/輕量 4/入門 5/專業 10/工作室 20/企業 20 個 pending),超上限回 429 in_flight_limit_reached。 | 待現有任務完成後再提交,或升級至入門/專業/工作室方案以解鎖批量生成與更高並行上限。 |
| 429 | capacity_exceeded | 公開 API 生成池到頂(全域並發上限)。 | 等候 Retry-After 秒再試,或改用非同步 `POST /v1/audio/jobs`。 |
| 429 | rate_limit_exceeded | 已觸及每用戶每分鐘上限(同一帳戶嘅所有金鑰加埋計)。 | 等候 Retry-After 秒(回應內容亦以 retry_after 標示),然後重試。 |
| 503 | service_unavailable | 語音引擎暫時離線(維護或後端未就緒)— 請求在受理前已被拒,未扣費。回應帶 Retry-After。 | 等候 Retry-After 秒(預設 60)後重試;失敗不扣費。 |
| 503 | rate_limit_unavailable | 速率限制服務暫時不可用 — 為避免放行未受管流量,請求在受理前已被拒,未扣費。回應帶 Retry-After。 | 等候 Retry-After 秒(預設 5)後重試。 |
| 429 | sandbox_daily_limit | 免費方案每日 50 個生成請求上限已用完;輪詢與下載不受此限。 | 明日再試,或升級至輕量方案解鎖全速 API。 |
| 429 | api_busy | API 生成隊列已達全域容量上限(受理前即拒,不扣費)。 | 稍候數秒重試。 |
| 502 | audio_delivery_failed | 生成已完成,但音訊提取失敗。 | 改以 GET /v1/audio/jobs/{id} 輪詢並下載 audio_url。 |
| 503 | sync_generation_failed | 同步等待期間任務失敗或被取消(已自動退款)。 | 改用 POST /v1/audio/jobs(非同步)重試。 |
| 503 | reference_upload_failed | clone 參考音頻暫時儲存失敗。 | 直接重試。 |
| 503 | voice_gallery_unavailable / jobs_unavailable | 後端暫時性問題。 | 以指數退避重試。 |
| 400 | unsupported_response_format | 文件轉寫的 response_format 暫只支援 json/text — srt/verbose_json 需要段級時間標記,暫未提供。 | 使用 json 或 text。 |
| 402 | insufficient_balance | 預付餘額不足以預扣本次文件轉寫費用(未開始處理、零扣費)。 | 前往 /account/billing 儲值後重試(失敗不扣費)。 |
| 503 | engine_unavailable | 文件轉寫服務暫時不可用(音檔時長偵測失敗、計費系統、轉寫管線故障,或同步窗內引擎排隊/退化 — 屬瞬態)。已預扣金額全額退回。 | 等候 Retry-After 秒重試;不會產生費用。 |
| 400 | audio_too_long | 音頻超過同步交付上限 8 分鐘(480 秒)— 處理前拒、零扣費(回應帶 duration_seconds+async_endpoint)。 | 改用 POST /v1/asr/jobs(非同步,上限 4 小時/500MB)。 |
| 400 | storage_path_session_only | API key caller 送 `storage_path` — 該進場只限 browser session(playground 大檔 lane)。 | 改用 audio_url 或 multipart file 進場。 |
| 403 | storage_path_forbidden | `storage_path` 唔屬於認證用戶(防跨用戶閘)。 | 只可以用 /api/asr/upload-url 回傳嘅自己 path。 |
| 404 | storage_path_not_found | `storage_path` 指住嘅物件唔存在(上載未完成或已過 TTL — free 24 小時/paid 7 日)。 | 重新經 /api/asr/upload-url 上載後再提交。 |
| 503 | sync_timeout | 語音同步快線等待超過約 45 秒 — 任務已取消並於數秒內退款(回應帶 Retry-After;X-Request-Id 留作對帳)。 | 稍後重試,或改用 POST /v1/audio/jobs(非同步)。 |
基礎建設
為正式流量預留專用容量。
API 語音負載運行於專用 GPU 池 — 與互動 Playground 完全隔離,正式流量不會與任何瀏覽器工作階段爭奪算力。
帳戶與用量面
純 API 客戶唔使登入 web console 都用得嘅三個入口 — 生成紀錄清單、匿名使用統計開關、帳戶自我刪除。
純 API 客戶唔使登入 web console 都用得嘅三個帳戶面入口 — 查返自己嘅生成紀錄、開關匿名使用統計,同埋(不可逆嘅)刪除自己個帳戶。三個都係 owner-scoped:只會顯示/影響你同一個帳戶嘅嘢。
生成紀錄清單 — GET /v1/audio/jobs
列出你自己嘅生成紀錄(最新先)— 純 API 客戶唔使登入 web UI 就查得返自己提交過乜、做到咗幾耐。每條紀錄都帶一個有界嘅文字預覽(最多 120 字);要全文就用 GET /v1/audio/jobs/{id},或者自己保留原文。金鑰要帶 tts:generate 或 tts:design scope(唔夠 → 403 insufficient_scope)。
curl "https://canto-gen.com/v1/audio/jobs?limit=20" \
-H "Authorization: Bearer \$CANTOGEN_API_KEY"{
"jobs": [
{
"id": "b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
"status": "done",
"created_at": "2026-10-29T09:12:00.000Z",
"voice_slug": "sum",
"duration_ms": 4200,
"text_preview": "你好,歡迎使用港嘢!"
}
],
"next_before": null
}limit— 每頁行數(1–100,預設 20)before— 游標 — 上一頁最後一條紀錄嘅id(要 uuid)status— 可選過濾:queued/processing/cancelling/done/error/cancellednext_before— 下一頁嘅游標;null= 冇下一頁text_preview— 生成文字嘅有界預覽(最多 120 字)duration_ms— 音訊時長(毫秒;未生成完成 =null)
⚠️ status 用任務實際狀態值(done/error/…);GET /v1/audio/jobs/{id} 嘅輪詢面用公開狀態名(completed/failed/…)—— 兩套詞彙唔同,睇清自己讀緊邊個 endpoint。
匿名使用統計 — GET / PUT /v1/account/telemetry
讀/寫本帳戶嘅匿名使用統計(質素訊號)設定。telemetry_opt_out: true = 關閉自動行為遙測(例如你嘅使用行為記錄);你主動提交嘅評分/回報唔受影響 — 嗰啲係你明示嘅意圖,唔當成遙測。每個帳戶一個設定(同一帳戶嘅所有金鑰共用 user_profiles.telemetry_opt_out)。
curl https://canto-gen.com/v1/account/telemetry \
-H "Authorization: Bearer \$CANTOGEN_API_KEY"{
"telemetry_opt_out": false
}curl -X PUT https://canto-gen.com/v1/account/telemetry \
-H "Authorization: Bearer \$CANTOGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"telemetry_opt_out": true}'{
"ok": true,
"telemetry_opt_out": true
}刪除帳戶 — POST /v1/account/deletion
刪除你自己嘅帳戶(自我服務刪除,純 API 客戶唔使登入 web UI 就用得)。兩步確認:body { confirmEmail, confirmWord } — confirmEmail 大小寫不敏感地等於你嘅帳戶電郵,confirmWord 大小寫敏感地等於 DELETE。成功 → 帳戶即時停用(登入被封、現有 session 全部失效),個人資料由每日清理程序清走、30 日內永久清除(purge_by 係完成清除嘅上限時刻)。
curl -X POST https://canto-gen.com/v1/account/deletion \
-H "Authorization: Bearer \$CANTOGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"confirmEmail": "you@example.com", "confirmWord": "DELETE"}'{
"ok": true,
"purge_by": "2026-11-02T03:00:00.000Z"
}清除範圍:生成紀錄、聲線、參考音頻等個人資料一律清走;加密備份隨供應商嘅輪替週期移除(唔會即刻清);帳務/用量紀錄依法保留(唔會因為刪戶而清走)。團隊帳戶要先解散 — 你係一個仲有其他成員嘅工作區擁有者會回 409 team_owner(要先解散/轉讓);仲有未完成嘅生成工作會回 409 active_jobs。重複請求係冪等嘅(同一個帳戶只有一條刪除申請)。
錯誤碼
| HTTP | error | 原因 |
|---|---|---|
| 400 | invalid_limit | `limit` 唔係 1–100 嘅整數。 |
| 400 | invalid_cursor | `before` 唔係一個 uuid,或者唔屬於你嘅任何一條紀錄。 |
| 400 | invalid_status | `status` 唔喺值集內(queued/processing/cancelling/done/error/cancelled)。 |
| 400 | invalid_telemetry_opt_out | `telemetry_opt_out` 唔係 boolean。 |
| 400 | confirm_missing | 刪戶 body 冇帶 `confirmEmail` 或 `confirmWord`。 |
| 400 | confirm_email_mismatch | `confirmEmail` 同你嘅帳戶電郵唔一致(大小寫唔敏感比較)。 |
| 400 | confirm_word_mismatch | `confirmWord` 唔係 `DELETE`(大小寫敏感)。 |
| 401 | invalid_or_expired_token | API 金鑰缺失、無效、已過期或已被撤銷。 |
| 403 | insufficient_scope | 金鑰缺少 `tts:generate` 或 `tts:design` scope(生成紀錄清單面)。 |
| 409 | active_jobs | 仲有未完成嘅生成工作(queued/processing/cancelling)— 等佢哋完成先再刪戶。 |
| 409 | team_owner | 你係一個仲有其他成員嘅工作區擁有者 — 要先解散/轉讓工作區。 |
| 503 | jobs_unavailable | 生成紀錄清單暫時讀唔到(`GET /v1/audio/jobs`)。 |
| 503 | telemetry_read_failed | 匿名使用統計設定暫時讀唔到。 |
| 503 | telemetry_update_failed | 匿名使用統計設定暫時儲存唔到。 |
| 503 | deletion_request_failed | 刪除申請暫時寫唔入 — 稍後重試(重試係冪等嘅)。 |
數據保留與刪除
你提交嘅文字、音頻同輸出點樣被保留、幾時被清走 —— 一頁講清,數字同我們嘅保留期框架一致。
保留與刪除規則
| 資料類型 | 保留/刪除 |
|---|---|
| 生成內容(生成工作紀錄連文字、生成音檔、ASR 轉錄紀錄) | 一律保留 90 日,之後由每日自動清理刪走 |
| 你主動刪除嘅資料(刪除聲線、刪除個別紀錄、刪除轉錄或音檔) | 即時失效、不設復原,30 日內永久清除 |
| 未註冊/冇任何工作引用嘅參考音頻(上載咗但冇綁定) | 24 小時寬限期,之後最長 30 日內清走 |
| 已註冊聲線嘅參考音頻 | 聲線仲喺度就保留;刪除聲線即時失效,檔案 30 日內清走 |
| 會議記錄(會議錄音、會議逐字稿) | 唔喺自動清理範圍 — 跟帳戶生命週期,只喺你明確刪除或刪除帳戶時清 |
| 帳戶刪除 | 即時停用(唔可以再登入或呼叫 API),30 日內完成永久清除 |
| 備份 | 加密備份隨供應商嘅輪替週期移除 |
刪除一律先刪資料庫紀錄、後刪音檔,資料即時失效、唔設復原;刪走之後唔會再喺任何生成或轉寫流程入面用到。
數據存放地與次處理者
資料中心位於南韓(首爾),備份由同區託管管理。次處理者:Supabase(託管資料庫同儲存)、Stripe(付款處理,唔經手你嘅內容)。語音生成由我們自家嘅雲端基礎建設執行,唔涉額外第三方。
絕不用作訓練
刪除一條轉錄紀錄
刪除一條 ASR 轉錄紀錄(連你上載嘅音檔):DELETE /v1/asr/transcriptions/{id}。個 id 就係 POST /v1/asr/transcribe/POST /v1/asr/jobs 回應帶返嘅 id。只可以刪自己金鑰嘅紀錄;搵唔到或者唔屬於你,一律回 404(唔會洩露 id 存在與否)。
curl -X DELETE https://canto-gen.com/v1/asr/transcriptions/<id> \
-H "Authorization: Bearer \$CANTOGEN_API_KEY"刪除你的聲線
刪除你自己嘅聲線:DELETE /v1/voices/{id}({id} 係聲線嘅 slug 或者 id)。聲線即刻喺所有清單消失、唔可以再用於生成;參考音檔同準備好嘅參考音頻副本即時清走,唔設復原。官方預設聲線唔可以刪(同一個 404,唔會洩露存在與否);金鑰要帶 voices:manage scope。如果有生成工作仲引用緊呢把聲線,會回 409 voice_busy(唔會刪,等個工作完成之後再刪)。
curl -X DELETE https://canto-gen.com/v1/voices/<voice-slug> \
-H "Authorization: Bearer \$CANTOGEN_API_KEY"刪除一條生成紀錄
刪除一條生成紀錄:DELETE /v1/audio/jobs/{id}({id} 係 POST /v1/audio/jobs 回應帶返嘅 job_id)。如果個 job 仲未完成(queued/processing),呢條 route 照取消佢(退款語義唔變);如果已經完成/失敗/取消咗,就會刪走工作紀錄(連你生成嘅文字)、音檔同字幕副檔。刪除一律先刪資料庫紀錄、後刪音檔,資料即時失效、唔設復原。
curl -X DELETE https://canto-gen.com/v1/audio/jobs/<job_id> \
-H "Authorization: Bearer \$CANTOGEN_API_KEY"參考與下載
本頁為快速入門指南;/v1/docs/reference(Scalar)為詳細的 API 參考 — 每個 endpoint 的完整 request/response schema、所有錯誤碼與 try-it 面板均在其內。本頁全部內容同時提供機器可讀格式。
/v1/audio/speech200 sync短文字同步生成 — 直接回傳 200 音訊 bytes(voice/design 模式,≤300 credits)。
完整 schema → Scalar Reference/v1/audio/jobs202 async提交語音任務(單一或批次 ≤25;批次需入門方案或以上)。回傳 202 及 job_id 與 poll_url。
完整 schema → Scalar Reference/v1/audio/jobs/{id}poll查詢任務狀態;完成後回應會附上預簽名的 audio_url。
完整 schema → Scalar Reference/v1/audio/jobslist列出你自己嘅生成紀錄(最新先)。Owner-scoped:`limit`(1–100,預設 20)+ `before` 游標分頁,`status` 可過濾;回 `id`/`status`/`created_at`/`voice_slug`/`duration_ms`/`text_preview`(≤120 字)。
完整 schema → Scalar Reference/v1/voices列出廣東話優化聲線目錄,附試聽片段。此 endpoint 可匿名存取。
完整 schema → Scalar Reference/v1/voices/{id}delete刪除你自己嘅聲線(slug 或 id)— 即時失效、唔可以再用於生成,檔案即時清走。官方預設聲線唔可以刪。
完整 schema → Scalar Reference/v1/audio/jobs/{id}cancel / delete仲未完成嘅任務照取消(退款);已終態嘅任務就係刪紀錄(工作紀錄 + 音檔 + 字幕副檔)。
完整 schema → Scalar Reference/v1/asr/transcribe200 sync文件轉寫 — 上載音檔同步回傳文字;按音頻時長計費 — 文件轉寫 800 credits/小時(HK$0.80/小時;1 HK$ = 1,000 credits),只扣成功。
完整 schema → Scalar Reference/v1/asr/jobs202 async非同步提交轉寫任務 — 即回 202 queued;multipart 上載、audio_url(server 下載)或 storage_path(browser session 大檔 lane,至 500MB)。長音檔首選。
完整 schema → Scalar Reference/v1/asr/transcriptions/{id}poll取回轉寫結果/狀態(queued → processing → completed/failed);completed 附文字稿。
完整 schema → Scalar Reference/v1/balance查詢預付餘額(HKD)、文件轉寫/實時聽寫費率與自動儲值設定。
完整 schema → Scalar Reference/v1/asr/vocabularyread讀取本帳戶嘅 ASR 關鍵詞詞庫(一本,per-account)。`terms` 係已清理嘅詞列表,`updated_at` 係上次更新時間(未建立過 → null)。
完整 schema → Scalar Reference/v1/asr/vocabularyreplace整本覆寫本帳戶嘅 ASR 關鍵詞詞庫(唔係增量)。`terms` 會先清理(trim/去重/丟超過 30 字嘅詞/最多 50 個)再儲存;回應係實際儲存咗嘅內容。
完整 schema → Scalar Reference/v1/asr/vocabularyclear清空本帳戶嘅 ASR 關鍵詞詞庫(等效 `PUT {"terms": []}`)。之後 API key 客戶嘅轉寫請求如果冇帶 `vocabulary` 參數,就唔會再套任何詞。
完整 schema → Scalar Reference/v1/account/telemetryread讀本帳戶嘅匿名使用統計(質素訊號)設定 → `{ telemetry_opt_out }`。每個帳戶一個設定(`user_profiles.telemetry_opt_out`)。
完整 schema → Scalar Reference/v1/account/telemetryopt-out開/關本帳戶嘅匿名使用統計(body `{ telemetry_opt_out: boolean }`)。`true` = 關閉自動行為遙測;你主動提交嘅評分/回報唔受影響。
完整 schema → Scalar Reference/v1/account/deletionirreversible刪除你自己嘅帳戶(自我服務)。兩步確認 body `{ confirmEmail, confirmWord }`;成功回 `{ ok, purge_by }` — 帳戶即時停用,個人資料 30 日內永久清除。
完整 schema → Scalar Reference# OpenAPI 3.1 規格 — 直接生成你所用語言的 typed client
curl https://canto-gen.com/v1/openapi.json
# 本頁純文字 Markdown 版
curl https://canto-gen.com/v1/docs.md
# Agent 索引(llms.txt)
curl https://canto-gen.com/llms.txt複製本頁 Markdown、或取用 Markdown/llms.txt/OpenAPI 機器可讀版本。