官方 SDK 為伺服器程式碼與腳本封裝了 REST API。一次呼叫即可轉錄一個檔案:它會上傳錄音、等待工作完成,並交回逐字稿。過程中,SDK 會在暫扣任何分鐘數之前先檢查檔案,重試可以安全重試的請求,讓長時間的上傳保持連線,並在每次上傳與購買時附上冪等金鑰,因此重試絕不會重複扣款。命令列工具建立在 TypeScript SDK 之上,可在終端機中做同樣的事。
套件
| 語言 | 套件 | 套件庫 | 原始碼 |
|---|---|---|---|
| TypeScript | @hushscript/sdk | npm: www.npmjs.com/package/@hushscript/sdk | github.com/Hushscript/hushscript-sdk-typescript |
| Python | hushscript | PyPI: pypi.org/project/hushscript | github.com/Hushscript/hushscript-sdk-python |
| Go | github.com/Hushscript/hushscript-sdk-go | pkg.go.dev: pkg.go.dev/github.com/Hushscript/hushscript-sdk-go | github.com/Hushscript/hushscript-sdk-go |
| PHP | hushscript/sdk | Packagist: packagist.org/packages/hushscript/sdk | github.com/Hushscript/hushscript-sdk-php |
| CLI | @hushscript/cli | npm: www.npmjs.com/package/@hushscript/cli | github.com/Hushscript/hushscript-cli |
執行環境最低版本:
- TypeScript: Node 22 或更新版本。Bun 1.2+ 與 Deno 2+ 僅檢查能否匯入此套件,不檢查其 HTTP 行為。
- Python: 3.10 或更新版本。
- Go: 1.25 或更新版本。
- PHP: 8.2 或更新版本,需要
ext-json與ext-mbstring;並行上傳分段需要ext-curl。 - CLI: Node 22 或更新版本。
這些 SDK 供伺服器與腳本使用。API 不接受瀏覽器來源,而放進瀏覽器套件的權杖就等於外洩的權杖,因此 TypeScript SDK 在存在 window 與 document 的環境中會拒絕啟動。
取得權杖
每個 SDK 與命令列工具都以個人存取權杖驗證身分。請在帳戶中的 MCP 頁面的 建立新的權杖 區段建立權杖,選擇程式碼所需的權限範圍,並決定它是否可以購買分鐘數。權杖只會顯示一次,格式為 hsr1:<region>:pat.<id>.<secret>。權限範圍與權杖的運作方式請見 API 頁面。
未傳入權杖時,SDK 會從 HUSHSCRIPT_TOKEN 讀取:
export HUSHSCRIPT_TOKEN=hsr1:...
代理程式也可以自行開設帳戶、在託管的結帳頁面完成付款,並以程式碼領取第一個權杖:TypeScript 使用 Hushscript.agent.signup() 與 Hushscript.agent.claim(),Python 使用 Hushscript.agent_signup() 與 Hushscript.agent_claim(),Go 使用 AgentSignup 與 AgentClaim,PHP 使用 Client::agentSignup() 與 Client::agentClaim()。流程與規則請見自動化使用。
TypeScript
npm install @hushscript/sdk
import { writeFile } from "node:fs/promises";
import { Hushscript } from "@hushscript/sdk";
const hs = new Hushscript(); // reads HUSHSCRIPT_TOKEN
const transcript = await hs.transcribe("meeting.mp3");
console.log(transcript.text);
await writeFile("meeting.srt", transcript.toSRT());
transcribe() 接受路徑、Blob、Uint8Array 或 ReadableStream<Uint8Array>。串流必須提供確切的 size 與 durationSeconds。hs.balance() 回傳您可使用的分鐘數,hs.transcripts.list() 分頁列出已完成的逐字稿,hs.buy("300min", { acknowledgeNoRefund: true }) 則購買一個套餐。每個 /v1 操作也都可透過 hs.api 使用,並具備相同的重試、逾時與遮蔽處理。
Python
pip install hushscript
from pathlib import Path
from hushscript import Hushscript
with Hushscript() as hs: # reads HUSHSCRIPT_TOKEN
transcript = hs.transcribe("meeting.mp3")
print(transcript.text)
Path("meeting.srt").write_text(transcript.to_srt(), encoding="utf-8")
每個呼叫在 AsyncHushscript 上都有同名的 asyncio 版本。transcribe() 接受路徑、bytes 或二進位檔案物件;無法 seek 的檔案物件需要提供 size 與 duration_seconds。hs.balance()、hs.transcripts.list() 與 hs.buy("300min", acknowledge_no_refund=True) 分別負責查詢餘額、列出逐字稿與購買套餐。
Go
go get github.com/Hushscript/hushscript-sdk-go
package main
import (
"context"
"fmt"
"log"
"os"
hushscript "github.com/Hushscript/hushscript-sdk-go"
)
func main() {
client, err := hushscript.New() // reads HUSHSCRIPT_TOKEN
if err != nil {
log.Fatal(err)
}
transcript, err := client.Transcribe(context.Background(), "meeting.mp3", nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(transcript.Text(nil))
if err := os.WriteFile("meeting.srt", []byte(transcript.SRT(nil)), 0o600); err != nil {
log.Fatal(err)
}
}
Transcribe 接受路徑,TranscribeReader 接受 io.ReaderAt 及其確切大小,TranscribeStream 則接受只能向前讀取的 reader,並搭配其大小與 DurationSeconds。client.Balance、client.Transcripts.List 與 client.Buy 分別負責查詢餘額、列出逐字稿與購買套餐。可以是關閉、開啟或未設定的選項為 *bool,以 hushscript.Bool 建立。
PHP
composer require hushscript/sdk
<?php
require __DIR__ . '/vendor/autoload.php';
use Hushscript\Client;
$hs = new Client(); // reads HUSHSCRIPT_TOKEN
$transcript = $hs->transcribe('meeting.mp3');
echo $transcript->text();
file_put_contents('meeting.srt', $transcript->toSrt());
transcribe() 接受路徑或已開啟的串流;無法 seek 的串流需要 size 與 duration_seconds 選項。選項使用 snake_case 陣列鍵,結果則使用 camelCase 屬性。$hs->balance()、$hs->transcripts()->list() 與 $hs->buy('300min', true) 分別負責查詢餘額、列出逐字稿與購買套餐。在 Laravel 中,請在 service provider 裡綁定一個 Client,並在佇列工作中執行轉錄,同時設定固定的 idempotency_key 選項。
CLI
npm install --global @hushscript/cli
hushscript login
hushscript transcribe meeting.mp3 --format srt --out meeting.srt
命令列工具依序從 --token、HUSHSCRIPT_TOKEN,以及 hushscript login 儲存的權杖取得權杖。login 會在不回顯的情況下詢問權杖,並將它存放在只有您的使用者帳號能讀取的檔案中;hushscript logout 會將其刪除。在 CI 中,建議使用環境變數。
| 指令 | 功能 |
|---|---|
login |
提示輸入權杖並儲存。 |
logout |
刪除已儲存的權杖。 |
balance |
顯示您可使用的分鐘數。 |
transcribe <file> |
上傳錄音、等待並印出逐字稿。旗標:--language、--translate、--format srt|vtt|txt|json、--out、--key。 |
resume <token> <file> |
完成 transcribe 中途遺留的轉錄。 |
transcripts |
列出已完成的逐字稿,最新的在前。 |
transcript <id> |
印出一份逐字稿。 |
jobs |
列出工作;--active 只列出尚未完成的工作。 |
packs |
列出可購買的分鐘套餐及價格。 |
buy <pack> |
以您儲存的預設卡片購買一個套餐。旗標:--yes、--key。 |
--json 只在 stdout 輸出一份 JSON 文件,不輸出其他內容,並讓 stderr 改為 JSON Lines。結束代碼 0 表示成功,1 表示 API 或 SDK 回報了錯誤,2 表示用法錯誤(未送出任何內容),130 表示執行被中斷。
支援的檔案
MP3、M4A、MP4 與 MOV(使用影片的音軌)、WAV、FLAC,以及採用 Vorbis 或 Opus 的 OGG,長度從 15 秒到 10 小時。SDK 會根據檔案的位元組檢查格式,並在暫扣任何分鐘數之前探測時長。它們不轉換媒體,因此其他格式請先自行轉換:
ffmpeg -i input -vn -c:a libopus output.opus
錯誤
SDK 拋出的每個錯誤都屬於同一個家族,所以一個 catch 就能涵蓋全部:TypeScript 與 Python 為 HushscriptError,Go 為 *hushscript.Error,PHP 為 HushscriptException。錯誤包含 slug 形式的 code(例如 insufficient_balance)、數字代碼、HTTP 狀態、訊息、說明下一步該怎麼做的 hint、詳細資料,以及 retryAfter(PHP 中的 slug 為 errorCode,Python 中的 retryAfter 為 retry_after)。
import { HushscriptError, InsufficientBalanceError } from "@hushscript/sdk";
try {
await hs.transcribe("meeting.mp3");
} catch (error) {
if (error instanceof InsufficientBalanceError) console.log(error.hint);
else if (error instanceof HushscriptError) console.log(error.code, error.hint ?? error.message);
else throw error;
}
PreflightError 表示 SDK 在暫扣任何額度之前就拒絕了該檔案。餘額是否足以支付某個檔案由伺服器判定:建立上傳時會回傳 402,此時尚未送出任何分段。
扣款與重試
每次上傳與每次購買都帶有冪等金鑰,而重試會沿用同一把金鑰,因此重試的呼叫會重現第一次的結果,而不是另起一次。
buy() 會向您儲存的預設卡片扣款。要從程式碼購買,必須三個開關都允許:權杖具有 billing 權限範圍、權杖已開啟「允許此權杖購買分鐘數」,且帳戶已開啟「允許已連接的應用程式購買分鐘數」。缺少任何一項,呼叫都會以 pat_scope_missing 失敗。呼叫前,請先向您的買家顯示不退款聲明。
購買最多重試一次,只在網路錯誤、502 或 503 時進行,並使用相同的金鑰。有些回應可以證明未曾扣款:400、402、404 或 422,以及代碼為 4021(pat_purchase_requires_app,卡片被拒或需要您親自操作才能扣款)或 4023(pat_purchase_requires_authentication,銀行要求確認付款)的 403。遇到 4021 或 4023 時,請在應用程式中購買套餐。請求送出後發生的任何其他失敗,包括 401 或 429,都表示卡片可能已被扣款。該錯誤會帶有冪等金鑰:使用同一把金鑰再次請求,購買就絕不會發生兩次。以 Python 為例:
from hushscript import HushscriptError
try:
purchase = hs.buy("300min", acknowledge_no_refund=True)
except HushscriptError as error:
refused = error.status in {400, 402, 404, 422} or (
error.status == 403 and error.numeric_code in {4021, 4023}
)
if error.idempotency_key is None or refused:
raise # only these refusals charged nothing; any other failure keeps the key for a retry
purchase = hs.buy("300min", acknowledge_no_refund=True, idempotency_key=error.idempotency_key)
請求送出之前就失敗的購買不帶金鑰:表示沒有扣款。您自行傳入的金鑰長度必須為 1 到 128 個字元,字元取自 A-Za-z0-9_-;請勿將同一把金鑰用於不同的套餐。購買請求可能已送出時,命令列工具會印出該金鑰:
hushscript buy 300min --yes --key <key>
恢復權杖
工作一旦建立,錯誤就會在冪等金鑰旁帶有一個恢復權杖。等待逾時會拋出帶有該權杖的 WaitTimeoutError,而工作會繼續執行。把權杖傳回 resume() 即可繼續,不會再次扣款:已過上傳階段的工作不需要檔案,仍在上傳的工作則以同一個檔案接續。以 PHP 為例:
try {
$hs->transcribe($path, ['wait_timeout' => 60]);
} catch (\Hushscript\Exception\WaitTimeoutError $timeout) {
$transcript = $hs->resume($timeout->resumeToken, $path);
}
在命令列工具中,於 transcribe 期間按 Ctrl-C 會印出該工作的恢復權杖,以及接續它的指令:
hushscript resume <token> meeting.mp3 --format srt --out meeting.srt
記錄與遮蔽
SDK 不傳送任何遙測資料;User-Agent 標頭是唯一的用戶端識別。記錄預設為關閉。HUSHSCRIPT_LOG=debug 會對每個請求在標準錯誤輸出一行,內容為方法、路徑、狀態與耗時,絕不包含標頭、內文、標題或逐字稿文字。
權杖會從每一則錯誤、每一行記錄,以及用戶端的每一種列印形式中遮蔽。在錯誤訊息、提示與成因中,網址會保留主機與路徑,但查詢字串會變成 ?[redacted],因此簽署過的上傳網址絕不會被印出。會交給您密鑰的結果,例如認領密鑰或新的權杖,作為欄位時仍可讀取,但列印時會顯示 [redacted];JSON 匯出屬於您自己的資料,會帶有該值。命令列工具會從 stderr 清除它所知的每一個權杖;其 stdout 上的結果是您的輸出,不會被清除。
設定
| 設定 | 環境變數 | 預設值 |
|---|---|---|
| 權杖 | HUSHSCRIPT_TOKEN |
無 |
| 基礎網址 | HUSHSCRIPT_BASE_URL |
https://api.hushscript.com |
| 記錄層級 | HUSHSCRIPT_LOG |
off |
| 請求逾時 | 無 | 60 秒 |
| 重試次數 | 無 | 3 |
在程式碼中傳入的選項優先於對應的環境變數,空值視為未設定。分鐘數與應用程式使用同一份餘額;套餐與價格請見定價頁面。