Die offiziellen SDKs kapseln die REST-API für Servercode und Skripte. Ein Aufruf transkribiert eine Datei: Er lädt die Aufnahme hoch, wartet auf den Job und gibt das Transkript zurück. Dazwischen prüft das SDK die Datei, bevor Minuten reserviert werden, wiederholt, was sich gefahrlos wiederholen lässt, hält einen langen Upload am Leben und versieht jeden Upload und jeden Kauf mit einem Idempotenzschlüssel, sodass eine Wiederholung nie doppelt abbucht. Die CLI baut auf dem TypeScript-SDK auf und tut dasselbe im Terminal.
Pakete
| Sprache | Paket | Registry | Quellcode |
|---|---|---|---|
| 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 |
Mindestversionen der Laufzeitumgebung:
- TypeScript: Node 22 oder neuer. Bun 1.2+ und Deno 2+ werden nur auf den Import des Pakets geprüft, nicht auf ihr HTTP-Verhalten.
- Python: 3.10 oder neuer.
- Go: 1.25 oder neuer.
- PHP: 8.2 oder neuer, mit
ext-jsonundext-mbstring;ext-curlfür gleichzeitige Part-Uploads. - CLI: Node 22 oder neuer.
Die SDKs sind für Server und Skripte gedacht. Die API akzeptiert keine
Browser-Origins, und ein Token in einem Browser-Bundle ist ein offengelegter
Token. Deshalb verweigert das TypeScript-SDK den Start, wo window und
document existieren.
Token erstellen
Jedes SDK und die CLI authentifizieren sich mit einem persönlichen
Zugriffstoken. Erstellen Sie einen unter Neuen Token erstellen auf der
MCP-Seite im Konto, wählen Sie die
Berechtigungen aus, die Ihr Code braucht, und entscheiden Sie, ob er Minuten
kaufen darf. Der Token wird nur einmal angezeigt und sieht so aus:
hsr1:<region>:pat.<id>.<secret>. Die Berechtigungen und die Funktionsweise
eines Tokens stehen auf der API-Seite.
Die SDKs lesen den Token aus HUSHSCRIPT_TOKEN, wenn Sie keinen übergeben:
export HUSHSCRIPT_TOKEN=hsr1:...
Ein Agent kann auch sein eigenes Konto eröffnen, es auf einer gehosteten
Checkout-Seite bezahlen lassen und seinen ersten Token per Code abholen:
Hushscript.agent.signup() und Hushscript.agent.claim() in TypeScript,
Hushscript.agent_signup() und Hushscript.agent_claim() in Python, AgentSignup und AgentClaim
in Go sowie Client::agentSignup() und Client::agentClaim() in PHP. Der
Ablauf und seine Regeln stehen unter Automatisierte Nutzung.
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() nimmt einen Pfad, einen Blob, ein Uint8Array oder einen
ReadableStream<Uint8Array> entgegen. Ein Stream braucht seine exakte size
und durationSeconds. hs.balance() gibt die Minuten zurück, die Sie
ausgeben können, hs.transcripts.list() blättert durch fertige Transkripte,
und hs.buy("300min", { acknowledgeNoRefund: true }) kauft ein Paket. Jede
/v1-Operation steht auch als hs.api zur Verfügung, mit denselben
Wiederholungen, Timeouts und Schwärzungen.
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")
Jeder Aufruf hat auf AsyncHushscript einen asyncio-Zwilling mit denselben
Namen. transcribe() nimmt einen Pfad, bytes oder ein binäres Dateiobjekt
entgegen; ein Dateiobjekt ohne Seek-Unterstützung braucht size und
duration_seconds. hs.balance(), hs.transcripts.list() und
hs.buy("300min", acknowledge_no_refund=True) decken Guthaben,
Transkriptliste und Käufe ab.
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 nimmt einen Pfad entgegen, TranscribeReader einen
io.ReaderAt samt exakter Größe und TranscribeStream einen nur vorwärts
lesbaren Reader mit Größe und DurationSeconds. client.Balance,
client.Transcripts.List und client.Buy decken Guthaben, Transkriptliste
und Käufe ab. Optionen, die aus, an oder nicht gesetzt sein können, sind
*bool und werden mit hushscript.Bool erzeugt.
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() nimmt einen Pfad oder einen offenen Stream entgegen; ein
Stream ohne Seek-Unterstützung braucht die Optionen size und
duration_seconds. Optionen verwenden snake_case-Array-Schlüssel, Ergebnisse
camelCase-Eigenschaften. $hs->balance(), $hs->transcripts()->list() und
$hs->buy('300min', true) decken Guthaben, Transkriptliste und Käufe ab. Für
Laravel binden Sie einen Client in einem Service Provider und führen
Transkriptionen in einem Queue-Job mit einer stabilen Option idempotency_key
aus.
CLI
npm install --global @hushscript/cli
hushscript login
hushscript transcribe meeting.mp3 --format srt --out meeting.srt
Die CLI übernimmt den Token aus --token, dann aus HUSHSCRIPT_TOKEN, dann
den von hushscript login gespeicherten. login fragt den Token ohne Echo ab
und legt ihn in einer Datei ab, die nur Ihr Benutzer lesen kann; hushscript logout löscht sie. Bevorzugen Sie in CI die Umgebungsvariable.
| Befehl | Wirkung |
|---|---|
login |
Fragt einen Token ab und speichert ihn. |
logout |
Löscht den gespeicherten Token. |
balance |
Zeigt die Minuten, die Sie ausgeben können. |
transcribe <file> |
Lädt eine Aufnahme hoch, wartet und gibt das Transkript aus. Flags: --language, --translate, --format srt|vtt|txt|json, --out, --key. |
resume <token> <file> |
Schließt eine Transkription ab, die transcribe hinterlassen hat. |
transcripts |
Listet fertige Transkripte auf, die neuesten zuerst. |
transcript <id> |
Gibt ein Transkript aus. |
jobs |
Listet Jobs auf; --active für die noch nicht beendeten. |
packs |
Listet die kaufbaren Minutenpakete mit Preisen auf. |
buy <pack> |
Kauft ein Paket mit Ihrer gespeicherten Standardkarte. Flags: --yes, --key. |
--json gibt genau ein JSON-Dokument auf stdout aus und sonst nichts und
wandelt stderr in JSON Lines um. Der Exit-Code ist 0 bei Erfolg, 1, wenn die
API oder das SDK einen Fehler gemeldet hat, 2 bei einem Aufruffehler (es
wurde nichts gesendet) und 130, wenn der Lauf unterbrochen wurde.
Unterstützte Dateien
MP3, M4A, MP4 und MOV (die Audiospur eines Videos wird verwendet), WAV, FLAC und OGG mit Vorbis oder Opus, von 15 Sekunden bis 10 Stunden. Die SDKs prüfen das Format anhand der Bytes der Datei und ermitteln die Dauer, bevor Minuten reserviert werden. Sie konvertieren keine Medien; konvertieren Sie alles andere zuerst:
ffmpeg -i input -vn -c:a libopus output.opus
Fehler
Jeder Fehler, den ein SDK auslöst, gehört zu einer Familie, sodass ein
einziges catch alles abdeckt: HushscriptError in TypeScript und Python,
*hushscript.Error in Go und HushscriptException in PHP. Ein Fehler enthält
einen Slug-code wie insufficient_balance, den numerischen Code, den
HTTP-Status, eine Meldung, einen hint, der sagt, was als Nächstes zu tun
ist, die Details und retryAfter (in PHP heißt der Slug errorCode, in Python
heißt 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;
}
Ein PreflightError bedeutet, dass das SDK die Datei abgelehnt hat, bevor
Guthaben reserviert wurde. Ob Ihr Guthaben für eine Datei reicht, entscheidet
der Server: Ein 402 kommt zurück, wenn der Upload angelegt wird, bevor ein
Teil gesendet wurde.
Abbuchung und Wiederholungen
Jeder Upload und jeder Kauf trägt einen Idempotenzschlüssel, und Wiederholungen verwenden ihn erneut, sodass ein wiederholter Aufruf den ersten wiedergibt, statt einen zweiten zu starten.
buy() belastet Ihre gespeicherte Standardkarte. Kaufen per Code ist
deaktiviert, bis drei Schalter es erlauben: Der Token hat den Scope
billing, beim Token ist „Diesem Token erlauben, Minuten zu kaufen“ eingeschaltet, und
für das Konto ist „Verbundenen Apps erlauben, Minuten zu kaufen“ eingeschaltet. Fehlt einer,
schlägt der Aufruf mit pat_scope_missing fehl. Zeigen Sie Ihren Käufern den
Hinweis, dass keine Erstattung erfolgt, bevor Sie ihn aufrufen.
Ein Kauf wird höchstens einmal wiederholt, bei einem Netzwerkfehler, einem 502
oder einem 503, mit demselben Schlüssel. Manche Antworten belegen, dass nichts
abgebucht wurde: ein 400, 402, 404 oder 422 sowie ein 403 mit dem Code 4021
(pat_purchase_requires_app, die Karte wurde abgelehnt oder kann nicht ohne
Ihr Zutun belastet werden) oder 4023 (pat_purchase_requires_authentication,
die Bank will die Zahlung bestätigen). Kaufen Sie das Paket nach 4021 oder
4023 in der App. Jeder andere Fehler nach dem Senden der Anfrage, auch ein 401
oder 429, bedeutet, dass die Karte womöglich belastet wurde. Dieser Fehler
enthält den Idempotenzschlüssel: Fragen Sie erneut mit demselben Schlüssel an,
und der Kauf kann nie doppelt stattfinden. In 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)
Ein Kauf, der scheiterte, bevor seine Anfrage gesendet wurde, enthält keinen
Schlüssel: Es wurde nichts abgebucht. Ein Schlüssel, den Sie selbst angeben,
muss 1 bis 128 Zeichen aus A-Za-z0-9_- lang sein; verwenden Sie ihn nicht
für ein anderes Paket erneut. Die CLI gibt den Schlüssel aus, wenn ein Kauf
womöglich gesendet wurde:
hushscript buy 300min --yes --key <key>
Resume-Tokens
Sobald ein Job existiert, enthält ein Fehler neben dem Idempotenzschlüssel einen
Resume-Token. Läuft ein Warten ab, löst es WaitTimeoutError mit dem Token
aus, und der Job läuft weiter. Übergeben Sie den Token an resume(), um ohne
zweite Abbuchung fortzufahren: Ein Job nach dem Upload braucht keine Datei,
und einer, der noch hochlädt, wird mit derselben Datei fortgesetzt. In PHP:
try {
$hs->transcribe($path, ['wait_timeout' => 60]);
} catch (\Hushscript\Exception\WaitTimeoutError $timeout) {
$transcript = $hs->resume($timeout->resumeToken, $path);
}
In der CLI gibt Strg+C während transcribe den Resume-Token des Jobs und den
Befehl aus, der ihn fortsetzt:
hushscript resume <token> meeting.mp3 --format srt --out meeting.srt
Protokollierung und Schwärzung
Die SDKs senden keine Telemetrie; der Header User-Agent ist die einzige
Client-Kennung. Die Protokollierung ist standardmäßig aus.
HUSHSCRIPT_LOG=debug schreibt eine Zeile pro Anfrage auf die
Standardfehlerausgabe, mit Methode, Pfad, Status und Dauer, und nie
einen Header, Body, Titel oder Transkripttext.
Der Token wird aus jedem Fehler, jeder Logzeile und jeder ausgegebenen Form
des Clients geschwärzt. In Fehlermeldungen, Hinweisen und Ursachen behält eine
URL Host und Pfad, ihr Query-String wird aber zu ?[redacted], sodass eine
signierte Upload-URL nie ausgegeben wird. Ergebnisse, die Ihnen ein Geheimnis
übergeben, etwa ein Claim-Secret oder ein neuer Token, behalten es als Feld
lesbar, zeigen beim Ausgeben aber [redacted]; ein JSON-Export gehört Ihnen
und enthält den Wert. Die CLI entfernt jeden ihr bekannten Token aus stderr;
ihre Ergebnisse auf stdout sind Ihre Ausgabe und werden nicht bereinigt.
Konfiguration
| Einstellung | Umgebungsvariable | Standard |
|---|---|---|
| Token | HUSHSCRIPT_TOKEN |
keiner |
| Basis-URL | HUSHSCRIPT_BASE_URL |
https://api.hushscript.com |
| Log-Level | HUSHSCRIPT_LOG |
off |
| Anfrage-Timeout | keine | 60 Sekunden |
| Wiederholungen | keine | 3 |
Eine im Code übergebene Option hat Vorrang vor ihrer Umgebungsvariable, und ein leerer Wert gilt als nicht gesetzt. Die Minuten stammen vom selben Guthaben wie die App; Pakete und Preise stehen auf der Preisseite.