廣東話優化嘅語音 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 模式

Claude CodeClaude CodeOpenCodeOpenCodeCodexCodexGemini CLIGemini CLICursorCursorCopilotCopilotClineClineAiderAider

MCP tools 一覽

工具說明認證要求所需 Scope
get_api_docs即場抓最新 API 規格(GET /v1/skill.md,零憑證)none
list_gallery列出官方預設聲線(唯讀)sk_ keytts:generate
list_my_voices列出個人聲線sk_ keyvoices:manage
create_my_voice上載本地音頻建立個人聲線(需 plan 支援)sk_ keyvoices:manage
delete_my_voice刪除個人聲線(即時失效,不可再用於生成;參考音頻 30 日內永久清除;歷史記錄保留聲線名稱)sk_ keyvoices:manage
tts_generatepreset 模式生成(指定聲線 slug)sk_ keytts:generate
generate_designdesign 模式生成(gender + age)sk_ keytts:generatetts:design
generate_cloneclone 模式生成(本地參考音頻;需 plan 支援)sk_ keytts:generatetts:clone
check_job輪詢非同步生成任務狀態至完成(跟進 /v1/audio/jobs 非同步生成流程)sk_ keytts:generatetts:design
cancel_job取消生成任務(未開始 → 全額退款;生成中 → 收尾後取消,已完成部分仍會計費;已終態 → 刪走該生成紀錄)sk_ keytts:generatetts:design
asr_transcribe文件轉寫(batch,按音頻時長計費;長音檔自動轉非同步並 poll 到完成)sk_ keytts:generate
get_balance查預付 HK$ 餘額+ASR 費率+自動儲值設定(零成本查詢)sk_ keytts:generate
get_usage審數:錢包 ledger 明細(游標分頁;零成本查詢)sk_ keytts: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_ keytts:generatetts:design
set_telemetry_opt_out開/關匿名使用統計(PUT /v1/account/telemetry;關咗就唔會再收自動行為遙測,主動評分/回報照收)sk_ key

AI agent 適用 MCP

本地 stdio 架構:MCP 伺服器運行於你自己的機器,金鑰由你填入本機設定檔,不經遠端託管。

取得 API 金鑰

API 請求以 Bearer 方式驗證你的金鑰。金鑰只在建立時顯示一次 — 伺服器端僅儲存 SHA-256 hash,遺失的金鑰只能撤銷後重新建立。

1

在「API 金鑰」頁面建立金鑰

前往「API 金鑰」頁面建立金鑰,然後直接儲存到環境變數:

environmentbash
export CANTOGEN_API_KEY="sk_live_..."

金鑰前綴

sk_live_…唯一的金鑰格式。免費方案金鑰受每日生成上限約束;付費方案用量計入該金鑰的每月 credits 上限。

Scopes

tts:generate預設。開放 voice 及 design 生成,以及所有讀取 endpoint(聲線目錄、任務查詢)。
tts:cloneclone 模式(以參考樣本複製聲音)必須使用此 scope。
tts:designdesign 模式(gender + age 合成聲線)的細粒度 scope — 已由 tts:generate 涵蓋,兩者其一即可。
voices:manage個人聲線管理(MCP 的 list / create / delete my voices)必須使用此 scope。

每把金鑰附帶的限制

每分鐘 rate limit(預設 60 個請求)及可選的每月 credits 上限。除 GET /v1/voices(公開聲線目錄,可匿名存取)外,所有 REST endpoint 均以 Authorization: Bearer $CANTOGEN_API_KEY 驗證。

定價

API 存取為付費方案(輕量/入門/專業/工作室)專屬,全速無每日上限。免費方案用戶亦可以建立 API 金鑰試用(每日上限 50 個生成請求;輪詢與下載不計入),升級即解鎖全速存取。

非同步 1 字 = 1 credit,無附加費

API 用量與網頁 Playground 共用同一個帳戶 credits 池,按帳單週期重置 — 非同步 API 1 字 = 1 credit,無倍數、無附加費;實時語音(同步 POST /v1/audio/speech)按 1.3 倍計量。credits 池用完可購買 Credit Pack。每個請求的 X-Credits-Charged 回應 header 顯示實扣 credits 數(已含倍數)。

商用授權 — 邊啲音頻可以商用?

付費期間(訂閱、字符包或 API 用量)生成嘅音頻:可自由用於個人或商業用途,終身有效(取消訂閱後仍然有效)。免費方案生成嘅音頻:僅供個人非商業用途,升級唔會追溯授權。預設聲線與聲音模型 IP 屬港嘢 — 你獲授權嘅係音頻檔,唔係聲線本身;唔准轉售或再包裝聲線/聲線庫/引擎為獨立語音合成服務。全文見服務條款 v1.2。

詞彙表

  • 每日生成上限 — 免費方案金鑰每日 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。

快速入門

三分鐘完成第一次生成:列出聲線目錄 → 提交語音任務 → 輪詢結果。

1

列出聲線目錄(GET /v1/voices)

list voicesbash
curl https://canto-gen.com/v1/voices \
  -H "Authorization: Bearer $CANTOGEN_API_KEY"
200 responsejson
{
  "voices": [
    {
      "slug": "sum",
      "name": "心妍",
      "gender": "female",
      "age": "adult",
      "styles": [],
      "preview_url": "https://canto-gen.com/api/voice-clip?slug=sum"
    }
  ]
}

聲線目錄為即時資料 — 請務必從你自己的回應中挑選 slug。此處的 "sum"(心妍)僅為文件示例,或在Playground 圖庫親耳試聽。

2

提交語音任務(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:

202 responsehttp
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
}

非同步為本 — 附同步快捷方式

非同步 endpoint 回傳 202,附帶 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 都得 — 同樣由資料庫同步。

聲音模式

選用圖庫聲線、以文字描述一個新聲線、或由樣本複製。每次請求只可使用其中一種模式。

三種模式互斥

三種聲音模式互斥:每次請求只可傳入 voice、design 或 clone 其中一項 — 否則回傳 400 voice_mode_conflict。設計及複製的聲線僅對該次請求生效,不會儲存為可重用的聲線資產。
voicedefault

圖庫聲線

以 slug 直接選用廣東話優化圖庫中的現成聲線。

  • 瀏覽 GET /v1/voices — 所有預設聲線均以廣東話為母語,附試聽片段。
  • 將 slug 作為 voice 參數傳入。文件示例為 sum(心妍)— 請務必從你自己的回應中挑選 slug。slug 為 ASCII 穩定識別符(行業標準做法),中文名作介面顯示之用。
voice 示例bash
# 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 參數。
design 示例bash
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 金鑰。
clone 示例bash
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 值;其他自由文字原樣接受。
emotion9 個支援值其中之一(見下方 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_formatmp3(預設)/ wav。
srttrue → 完成後的任務附帶 srt 欄位(以較高 credits 費率計費)。全方案適用。
happysadangryfearfuldisgustedsurprisedneutralexcitedgentle

參數上限

  • 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_id
GET /v1/audio/jobs/{id}輪詢 · 2–5 秒退避
status: completedaudio_url 就緒
GET audio_url預簽名 · 無需驗證

查詢任務狀態

GET /v1/audio/jobs/{id}bash
curl https://canto-gen.com/v1/audio/jobs/b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b \
  -H "Authorization: Bearer $CANTOGEN_API_KEY"

完成後的回應

completed jobjson
{
  "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/..."
}
以退避方式輪詢(Node)js
// 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 會過期 — 請盡早下載

audio_url 為預簽名連結,設有有效期:由素材音訊庫直接供應時有效期為 1 小時,由生成節點即時供應時為 7 天。請盡早下載;連結過期後重新查詢該任務即可取得新連結。任務在 queued/processing 期間以及 failed/cancelled 任務,均不附帶 audio_url 欄位。

字幕(SRT)

提交時傳入 "srt": true,完成後任務的查詢回應會附上 srt 欄位,內容為字幕(如上方完成回應所示)。srt_requested 欄位必定存在;srt 只在已要求且已就緒時出現。SRT 字幕輸出全方案適用。

計費細節

計費細節:任務的帳戶 credit 包含 SRT 附加費(srt: true 時 billedCharacters 會高於基本 credits 數),而每金鑰每月上限的帳本則按提交文字長度直接計算。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),帶咗(包括空陣列)就以請求為準。現階段轉寫以廣東話為本。

transcribe.shbash
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=json

200 回應

transcription.jsonjson
{
  "id": "b7e6f2a1-4c3d-4e5f-8a9b-0c1d2e3f4a5b",
  "object": "transcription",
  "text": "今日天氣幾好,一齊去行山啦。",
  "duration_seconds": 1830,
  "charged_hkd": 0.4067
}

超過同步交付上限(480 秒)→ 400 audio_too_long

同步交付 — 短至中等長度音檔(≤8 分鐘)直接回 200 文字。超過同步交付上限(480 秒,C3 2026-10-20)→ 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 儲值(可開啟自動儲值 — 餘額跌低門檻時自動增值)。

balance.shbash
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

vocabulary-get.shbash
curl https://canto-gen.com/v1/asr/vocabulary \
  -H "Authorization: Bearer \$CANTOGEN_API_KEY"
vocabulary.jsonjson
{
  "scope": "api",
  "terms": ["證監會", "庫務局", "Canto-Gen"],
  "updated_at": "2026-10-28T09:12:33.000Z"
}

覆寫 — PUT /v1/asr/vocabulary

vocabulary-put.shbash
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

vocabulary-delete.shbash
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.updateOpenAI 原生建立/更新 session 設定:voice、language、output_audio_format、max_session_chars、tts.segmentation(`max_session_chars` 亦可於連線時用 query `?max_session_chars=` 指定,一律被 clamp 落 plan 上限)。
conversation.item.createOpenAI 原生提交一段明確文字(input_text);觸發合成。
input_text.append港嘢 extension串流傳送原始 token delta。
input_text.commit港嘢 extension強制段落邊界(立即 flush)。
response.createOpenAI 原生觸發合成。
response.cancelOpenAI 原生barge-in:停止當前句子並退款。
session.close港嘢 extension主動關閉連線並結算。

事件 — server → client

session.createdOpenAI 原生連線建立;附伺服器簽發(server-minted)的 session id,同**生效值** `max_session_chars`(已被 clamp 落 plan 上限)。
session.updatedOpenAI 原生設定更新確認。
response.createdOpenAI 原生單句開始合成。
response.output_audio.deltaOpenAI 原生base64 PCM16 @ 48 kHz 音訊 chunk。
response.output_audio.doneOpenAI 原生單句音訊完成。
response.doneOpenAI 原生單句結束;usage 附 input_chars/billed_chars/remaining(extension 欄位)。
errorOpenAI 原生{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 活動。
Node 範例 clientjs
// 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_key401金鑰缺失、無效、過期或 scope 不符。
rate_limit_exceeded429觸及每用戶每分鐘上限(同一帳戶嘅所有金鑰加埋計);附 retry_after。
sandbox_daily_limit429免費方案每日 50 個生成句已用完(與 REST 共用計數);明日再試或升級方案。
monthly_cap_reached429已達金鑰本月 credits 上限。
character_limit_reached402帳戶 credits 池不足,該句不會合成。
concurrency_limit_reached429同時 session 或同時未結算句數已達上限。
session_char_limit_exceeded403已達本次 session 字數上限。
raw_limit_exceeded413原始輸入量(含標點/空白)超出上限。
text_too_long400單段文字超出上限。
invalid_session400session 已關閉或狀態無效。
engine_unavailable503實時引擎暫時不可用;請重試。

實時轉寫 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 都帶得。

mint-token.shbash
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

1000completed正常完(done 已收)。
1001idle_timeout逾時無任何 client frame(120s)。
1008protocol_violation壞 protocol/binary frame/base64 壞/超速。
1009message_too_big單 frame > 640KB。
1011engine_lost引擎中途收線。
1013engine_unavailable引擎連唔上。
4001invalid_or_expired_tokenkey 無效/過期/撤銷。
4002insufficient_balance連線前餘額唔夠。
4008capacity_exceeded同時 session 爆 cap(global 10/per-key free 2/paid 4)。
4009insufficient_balancesession 中餘額唔夠下一筆 hold。
4010invalid_audio_format送咗容器檔(WAV/Ogg/FLAC/MP3)— 要 raw PCM16LE mono 16kHz(ffmpeg -ac 1 -ar 16000 -f s16le)。
asr-realtime.jsjs
// 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。

錯誤格式json
{
  "error": "text_too_long",
  "message": "text exceeds 500 characters."
}
HTTPerror code原因處理方法
400invalid_modelmodel 必須是 "cantogen-tts"(或省略)。省略 model,或設為 "cantogen-tts"。
400voice_mode_conflict同時傳入了多於一個 voice / design / clone — 三種模式互斥。每次請求只傳入一種聲音模式。
400text_requiredtext 缺失或空白。傳入非空 text(1–500 credits)。
400text_too_longtext 超過 500 credits。請拆分文字 — 超限請求會被拒絕,不會截斷處理。
400unsupported_formatresponse_format 必須是 mp3 或 wav。使用 mp3 或 wav。
400invalid_pitchpitch 必須介乎 −12 至 +12 半音。將 pitch 調整至有效範圍。
400invalid_volumevolume 必須介乎 0 至 10。將 volume 調整至有效範圍。
400invalid_emotionemotion 不在 9 個支援值之內。使用 9 個支援的情緒值之一。
400invalid_srtsrt 必須是 boolean。使用 true / false。
400reference_audio_requiredclone.reference_audio 缺失。附上 base64 參考樣本。
400invalid_reference_audioclone.reference_audio 不是有效的 base64 音訊。傳入 data URL(data:audio/…;base64,…) 或 raw base64。
400invalid_reference_audio_sizeclone.reference_audio 音頻超過約 3 MB(JSON API 單一請求上限)。縮短樣本(至少 8 秒即可)再試。
400spoken_text_requiredtext 無可朗讀內容 — 計費 credits 為 0(只剩標點/空白/emoji/tone tags)。傳入含可讀文字的 text。
400design_gender_and_age_requireddesign.gender 與 design.age 兩項均必填。同時提供兩個欄位。
400invalid_job_id查詢或取消所用的 id 不是 UUID。檢查 job_id。
400invalid_requestbody 不是有效 JSON,或 Content-Type 非 JSON(/v1 僅接受 application/json);文件轉寫則為 multipart 缺 `file`/`model`、音檔為空或音檔格式不支援。以 Content-Type: application/json 傳送合法 JSON body。
413payload_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)。
401invalid_or_expired_tokenAPI 金鑰缺失、無效、已過期或已被撤銷。建立新金鑰並檢查 Bearer header。
402character_limit_reached帳戶 credits 池不足以完成本次生成(回應內含 remaining)。購買 Credit Pack 或等待月度重置。
403insufficient_scope金鑰缺少所需 scope(複製聲音需要 tts:clone);回應內含 "scope"。建立具備所需 scope 的金鑰。
403monthly_cap_reached金鑰的每月 credits 上限已達;回應內含 "used"。等候 UTC 月份重設,或調高上限。
404job_not_found沒有此 id 的任務(或任務屬於另一金鑰)。檢查 job_id 及提交時所用的金鑰。
409already_settled任務已屬終態(completed/failed/cancelled),無法再取消,亦不會退款。改以 GET /v1/audio/jobs/{id} 查詢最終狀態。
409duplicate_request同一個 Idempotency-Key(alias x-idempotency-key)已提交過(重試安全:不會重複扣費)。沿用原本的 job_id 輪詢,或以新 key 提交新任務。
404not_found沒有此 endpoint(路徑有誤)。對照 /v1/openapi.json 的路徑。
403batch_requires_pro批量生成(items)為入門/專業/工作室方案功能。單句任務的並行上限按方案分級(free 3/輕量 4/入門 5/專業 10/工作室 20/企業 20 個 pending),超上限回 429 in_flight_limit_reached。待現有任務完成後再提交,或升級至入門/專業/工作室方案以解鎖批量生成與更高並行上限。
429capacity_exceeded公開 API 生成池到頂(全域並發上限)。等候 Retry-After 秒再試,或改用非同步 `POST /v1/audio/jobs`。
429rate_limit_exceeded已觸及每用戶每分鐘上限(同一帳戶嘅所有金鑰加埋計)。等候 Retry-After 秒(回應內容亦以 retry_after 標示),然後重試。
503service_unavailable語音引擎暫時離線(維護或後端未就緒)— 請求在受理前已被拒,未扣費。回應帶 Retry-After。等候 Retry-After 秒(預設 60)後重試;失敗不扣費。
503rate_limit_unavailable速率限制服務暫時不可用 — 為避免放行未受管流量,請求在受理前已被拒,未扣費。回應帶 Retry-After。等候 Retry-After 秒(預設 5)後重試。
429sandbox_daily_limit免費方案每日 50 個生成請求上限已用完;輪詢與下載不受此限。明日再試,或升級至輕量方案解鎖全速 API。
429api_busyAPI 生成隊列已達全域容量上限(受理前即拒,不扣費)。稍候數秒重試。
502audio_delivery_failed生成已完成,但音訊提取失敗。改以 GET /v1/audio/jobs/{id} 輪詢並下載 audio_url。
503sync_generation_failed同步等待期間任務失敗或被取消(已自動退款)。改用 POST /v1/audio/jobs(非同步)重試。
503reference_upload_failedclone 參考音頻暫時儲存失敗。直接重試。
400unsupported_response_format文件轉寫的 response_format 暫只支援 json/text — srt/verbose_json 需要段級時間標記,暫未提供。使用 json 或 text。
402insufficient_balance預付餘額不足以預扣本次文件轉寫費用(未開始處理、零扣費)。前往 /account/billing 儲值後重試(失敗不扣費)。
503engine_unavailable文件轉寫服務暫時不可用(音檔時長偵測失敗、計費系統、轉寫管線故障,或同步窗內引擎排隊/退化 — 屬瞬態)。已預扣金額全額退回。等候 Retry-After 秒重試;不會產生費用。
400audio_too_long音頻超過同步交付上限 8 分鐘(480 秒)— 處理前拒、零扣費(回應帶 duration_seconds+async_endpoint)。改用 POST /v1/asr/jobs(非同步,上限 4 小時/500MB)。
400storage_path_session_onlyAPI key caller 送 `storage_path` — 該進場只限 browser session(playground 大檔 lane)。改用 audio_url 或 multipart file 進場。
403storage_path_forbidden`storage_path` 唔屬於認證用戶(防跨用戶閘)。只可以用 /api/asr/upload-url 回傳嘅自己 path。
404storage_path_not_found`storage_path` 指住嘅物件唔存在(上載未完成或已過 TTL — free 24 小時/paid 7 日)。重新經 /api/asr/upload-url 上載後再提交。
503sync_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)。

生成紀錄.shbash
curl "https://canto-gen.com/v1/audio/jobs?limit=20" \
  -H "Authorization: Bearer \$CANTOGEN_API_KEY"
generation-jobs.jsonjson
{
  "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/cancelled
  • next_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)。

匿名統計.shbash
curl https://canto-gen.com/v1/account/telemetry \
  -H "Authorization: Bearer \$CANTOGEN_API_KEY"
telemetry.jsonjson
{
  "telemetry_opt_out": false
}
匿名統計.shbash
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}'
telemetry-updated.jsonjson
{
  "ok": true,
  "telemetry_opt_out": true
}

刪除帳戶 — POST /v1/account/deletion

刪除你自己嘅帳戶(自我服務刪除,純 API 客戶唔使登入 web UI 就用得)。兩步確認:body { confirmEmail, confirmWord } — confirmEmail 大小寫不敏感地等於你嘅帳戶電郵,confirmWord 大小寫敏感地等於 DELETE。成功 → 帳戶即時停用(登入被封、現有 session 全部失效),個人資料由每日清理程序清走、30 日內永久清除(purge_by 係完成清除嘅上限時刻)。

刪除帳戶.shbash
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"}'
account-deletion.jsonjson
{
  "ok": true,
  "purge_by": "2026-11-02T03:00:00.000Z"
}

清除範圍:生成紀錄、聲線、參考音頻等個人資料一律清走;加密備份隨供應商嘅輪替週期移除(唔會即刻清);帳務/用量紀錄依法保留(唔會因為刪戶而清走)。團隊帳戶要先解散 — 你係一個仲有其他成員嘅工作區擁有者會回 409 team_owner(要先解散/轉讓);仲有未完成嘅生成工作會回 409 active_jobs。重複請求係冪等嘅(同一個帳戶只有一條刪除申請)。

錯誤碼

HTTPerror原因
400invalid_limit`limit` 唔係 1–100 嘅整數。
400invalid_cursor`before` 唔係一個 uuid,或者唔屬於你嘅任何一條紀錄。
400invalid_status`status` 唔喺值集內(queued/processing/cancelling/done/error/cancelled)。
400invalid_telemetry_opt_out`telemetry_opt_out` 唔係 boolean。
400confirm_missing刪戶 body 冇帶 `confirmEmail` 或 `confirmWord`。
400confirm_email_mismatch`confirmEmail` 同你嘅帳戶電郵唔一致(大小寫唔敏感比較)。
400confirm_word_mismatch`confirmWord` 唔係 `DELETE`(大小寫敏感)。
401invalid_or_expired_tokenAPI 金鑰缺失、無效、已過期或已被撤銷。
403insufficient_scope金鑰缺少 `tts:generate` 或 `tts:design` scope(生成紀錄清單面)。
409active_jobs仲有未完成嘅生成工作(queued/processing/cancelling)— 等佢哋完成先再刪戶。
409team_owner你係一個仲有其他成員嘅工作區擁有者 — 要先解散/轉讓工作區。
503jobs_unavailable生成紀錄清單暫時讀唔到(`GET /v1/audio/jobs`)。
503telemetry_read_failed匿名使用統計設定暫時讀唔到。
503telemetry_update_failed匿名使用統計設定暫時儲存唔到。
503deletion_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 存在與否)。

刪除轉錄.shbash
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(唔會刪,等個工作完成之後再刪)。

刪除聲線.shbash
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 照取消佢(退款語義唔變);如果已經完成/失敗/取消咗,就會刪走工作紀錄(連你生成嘅文字)、音檔同字幕副檔。刪除一律先刪資料庫紀錄、後刪音檔,資料即時失效、唔設復原。

刪除生成紀錄.shbash
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 面板均在其內。本頁全部內容同時提供機器可讀格式。

POST/v1/audio/speech200 sync

短文字同步生成 — 直接回傳 200 音訊 bytes(voice/design 模式,≤300 credits)。

完整 schema → Scalar Reference
POST/v1/audio/jobs202 async

提交語音任務(單一或批次 ≤25;批次需入門方案或以上)。回傳 202 及 job_id 與 poll_url。

完整 schema → Scalar Reference
GET/v1/audio/jobs/{id}poll

查詢任務狀態;完成後回應會附上預簽名的 audio_url。

完整 schema → Scalar Reference
GET/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
GET/v1/voices

列出廣東話優化聲線目錄,附試聽片段。此 endpoint 可匿名存取。

完整 schema → Scalar Reference
DELETE/v1/voices/{id}delete

刪除你自己嘅聲線(slug 或 id)— 即時失效、唔可以再用於生成,檔案即時清走。官方預設聲線唔可以刪。

完整 schema → Scalar Reference
DELETE/v1/audio/jobs/{id}cancel / delete

仲未完成嘅任務照取消(退款);已終態嘅任務就係刪紀錄(工作紀錄 + 音檔 + 字幕副檔)。

完整 schema → Scalar Reference
POST/v1/asr/transcribe200 sync

文件轉寫 — 上載音檔同步回傳文字;按音頻時長計費 — 文件轉寫 800 credits/小時(HK$0.80/小時;1 HK$ = 1,000 credits),只扣成功。

完整 schema → Scalar Reference
POST/v1/asr/jobs202 async

非同步提交轉寫任務 — 即回 202 queued;multipart 上載、audio_url(server 下載)或 storage_path(browser session 大檔 lane,至 500MB)。長音檔首選。

完整 schema → Scalar Reference
GET/v1/asr/transcriptions/{id}poll

取回轉寫結果/狀態(queued → processing → completed/failed);completed 附文字稿。

完整 schema → Scalar Reference
GET/v1/balance

查詢預付餘額(HKD)、文件轉寫/實時聽寫費率與自動儲值設定。

完整 schema → Scalar Reference
GET/v1/asr/vocabularyread

讀取本帳戶嘅 ASR 關鍵詞詞庫(一本,per-account)。`terms` 係已清理嘅詞列表,`updated_at` 係上次更新時間(未建立過 → null)。

完整 schema → Scalar Reference
PUT/v1/asr/vocabularyreplace

整本覆寫本帳戶嘅 ASR 關鍵詞詞庫(唔係增量)。`terms` 會先清理(trim/去重/丟超過 30 字嘅詞/最多 50 個)再儲存;回應係實際儲存咗嘅內容。

完整 schema → Scalar Reference
DELETE/v1/asr/vocabularyclear

清空本帳戶嘅 ASR 關鍵詞詞庫(等效 `PUT {"terms": []}`)。之後 API key 客戶嘅轉寫請求如果冇帶 `vocabulary` 參數,就唔會再套任何詞。

完整 schema → Scalar Reference
GET/v1/account/telemetryread

讀本帳戶嘅匿名使用統計(質素訊號)設定 → `{ telemetry_opt_out }`。每個帳戶一個設定(`user_profiles.telemetry_opt_out`)。

完整 schema → Scalar Reference
PUT/v1/account/telemetryopt-out

開/關本帳戶嘅匿名使用統計(body `{ telemetry_opt_out: boolean }`)。`true` = 關閉自動行為遙測;你主動提交嘅評分/回報唔受影響。

完整 schema → Scalar Reference
POST/v1/account/deletionirreversible

刪除你自己嘅帳戶(自我服務)。兩步確認 body `{ confirmEmail, confirmWord }`;成功回 `{ ok, purge_by }` — 帳戶即時停用,個人資料 30 日內永久清除。

完整 schema → Scalar Reference
下載bash
# 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 機器可讀版本。