Los SDK oficiales envuelven la API REST para código de servidor y scripts. Una sola llamada transcribe un archivo: sube la grabación, espera el job y te entrega la transcripción. Por el camino, el SDK revisa el archivo antes de retener minutos, reintenta lo que es seguro reintentar, mantiene viva una subida larga y lleva una clave de idempotencia en cada subida y cada compra para que un reintento nunca cobre dos veces. La CLI está construida sobre el SDK de TypeScript y hace lo mismo desde una terminal.
Paquetes
| Lenguaje | Paquete | Registro | Código fuente |
|---|---|---|---|
| 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 |
Versiones mínimas de cada entorno:
- TypeScript: Node 22 o posterior. Bun 1.2+ y Deno 2+ solo se verifican para importar el paquete, no para su comportamiento HTTP.
- Python: 3.10 o posterior.
- Go: 1.25 o posterior.
- PHP: 8.2 o posterior, con
ext-jsonyext-mbstring;ext-curlpara subir partes en paralelo. - CLI: Node 22 o posterior.
Los SDK son para servidores y scripts. La API no acepta orígenes de navegador,
y un token en el bundle de un navegador es un token filtrado, así que el SDK de
TypeScript se niega a iniciar donde existen window y document.
Obtén un token
Todos los SDK y la CLI se autentican con un token de acceso personal. Crea uno
en Crear un token nuevo, en la página de MCP de la cuenta,
elige los scopes que necesita tu código y decide si puede comprar minutos. El
token se muestra una sola vez y tiene la forma hsr1:<region>:pat.<id>.<secret>.
Los scopes y el funcionamiento de un token están en la página de la API.
Los SDK leen el token de HUSHSCRIPT_TOKEN cuando no le pasas uno:
export HUSHSCRIPT_TOKEN=hsr1:...
Un agente también puede abrir su propia cuenta, pagarla en una página de pago
alojada y reclamar su primer token desde código: Hushscript.agent.signup() y
Hushscript.agent.claim() en TypeScript, Hushscript.agent_signup() y Hushscript.agent_claim() en
Python, AgentSignup y AgentClaim en Go, y Client::agentSignup() y
Client::agentClaim() en PHP. El flujo y sus reglas están en Uso
automatizado.
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() acepta una ruta, un Blob, un Uint8Array o un
ReadableStream<Uint8Array>. Un stream necesita su size exacto y
durationSeconds. hs.balance() devuelve los minutos que puedes gastar,
hs.transcripts.list() recorre por páginas las transcripciones terminadas y
hs.buy("300min", { acknowledgeNoRefund: true }) compra un paquete. Cada
operación de /v1 también está disponible como hs.api, con los mismos
reintentos, tiempos de espera y redacción.
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")
Cada llamada tiene un equivalente asyncio en AsyncHushscript con los mismos
nombres. transcribe() acepta una ruta, bytes o un objeto de archivo
binario; un objeto de archivo que no admite seek necesita size y
duration_seconds. hs.balance(), hs.transcripts.list() y
hs.buy("300min", acknowledge_no_refund=True) cubren el saldo, la lista de
transcripciones y las compras.
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 acepta una ruta, TranscribeReader un io.ReaderAt y su tamaño
exacto, y TranscribeStream un lector de solo avance con su tamaño y
DurationSeconds. client.Balance, client.Transcripts.List y client.Buy
cubren el saldo, la lista de transcripciones y las compras. Las opciones que
pueden estar desactivadas, activadas o sin definir son *bool, creadas con
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() acepta una ruta o un stream abierto; un stream que no admite
seek necesita las opciones size y duration_seconds. Las opciones usan
claves de array en snake_case, y los resultados usan propiedades en camelCase.
$hs->balance(), $hs->transcripts()->list() y $hs->buy('300min', true)
cubren el saldo, la lista de transcripciones y las compras. En Laravel, enlaza
un solo Client en un service provider y ejecuta las transcripciones en un job
en cola con una opción idempotency_key estable.
CLI
npm install --global @hushscript/cli
hushscript login
hushscript transcribe meeting.mp3 --format srt --out meeting.srt
La CLI toma el token de --token, luego de HUSHSCRIPT_TOKEN y, por último,
del que guardó hushscript login. login pide el token sin mostrarlo en
pantalla y lo guarda en un archivo que solo tu usuario puede leer;
hushscript logout lo elimina. En CI, es preferible usar la variable de
entorno.
| Comando | Qué hace |
|---|---|
login |
Pide un token y lo guarda. |
logout |
Elimina el token guardado. |
balance |
Muestra los minutos que puedes gastar. |
transcribe <file> |
Sube una grabación, espera e imprime la transcripción. Opciones: --language, --translate, --format srt|vtt|txt|json, --out, --key. |
resume <token> <file> |
Termina una transcripción que transcribe dejó a medias. |
transcripts |
Lista las transcripciones terminadas, de la más reciente a la más antigua. |
transcript <id> |
Imprime una transcripción. |
jobs |
Lista los jobs; --active para los que no han terminado. |
packs |
Lista los paquetes de minutos que puedes comprar, con sus precios. |
buy <pack> |
Compra un paquete con tu tarjeta predeterminada guardada. Opciones: --yes, --key. |
--json imprime un único documento JSON en stdout y nada más, y convierte
stderr en JSON Lines. El código de salida es 0 si todo salió bien, 1 cuando la
API o el SDK informaron un error, 2 en un error de uso (no se envió nada) y 130
cuando se interrumpió la ejecución.
Archivos compatibles
MP3, M4A, MP4 y MOV (se usa la pista de audio de un video), WAV, FLAC y OGG con Vorbis u Opus, de 15 segundos a 10 horas. Los SDK verifican el formato a partir de los bytes del archivo y miden la duración antes de retener minutos. No convierten medios, así que convierte primero cualquier otro formato:
ffmpeg -i input -vn -c:a libopus output.opus
Errores
Todo error que lanza un SDK pertenece a una misma familia, así que un solo
catch los cubre todos: HushscriptError en TypeScript y Python,
*hushscript.Error en Go y HushscriptException en PHP. Un error incluye un
code en forma de slug, como insufficient_balance, el código numérico, el
estado HTTP, un mensaje, un hint que indica qué hacer a continuación, los
detalles y retryAfter (en PHP el slug es errorCode; en Python, retryAfter
es 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;
}
Un PreflightError significa que el SDK rechazó el archivo antes de retener
cualquier crédito. Que tu saldo cubra o no un archivo lo decide el servidor:
se devuelve un 402 al crear la subida, antes de enviar ninguna parte.
Cobros y reintentos
Cada subida y cada compra lleva una clave de idempotencia, y los reintentos la reutilizan, así que una llamada reintentada repite la primera en lugar de iniciar una segunda.
buy() cobra tu tarjeta predeterminada guardada. Comprar desde código está
desactivado hasta que lo permitan tres interruptores: el token tiene el scope
billing, el token tiene activada la opción “Permitir que este token compre minutos” y
está activada la opción “Permitir que las aplicaciones conectadas compren minutos” para la cuenta. Si
falta alguno, la llamada falla con pat_scope_missing. Muestra el aviso de no
reembolso a tu comprador antes de llamarla.
Una compra se reintenta como máximo una vez, ante un error de red, un 502 o un
503, con la misma clave. Algunas respuestas prueban que no se cobró nada: un
400, 402, 404 o 422, y un 403 con el código 4021 (pat_purchase_requires_app,
la tarjeta fue rechazada o no se puede cobrar sin ti) o 4023
(pat_purchase_requires_authentication, el banco quiere confirmar el pago).
Después de un 4021 o un 4023, compra el paquete en la aplicación. Cualquier
otro fallo después de enviar la solicitud, incluidos un 401 o un 429, significa
que es posible que la tarjeta se haya cobrado. Ese error lleva la clave de
idempotencia: vuelve a intentarlo con la misma clave y la compra nunca podrá
ocurrir dos veces. En 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)
Una compra que falló antes de que se enviara su solicitud no lleva clave: no se
cobró nada. Una clave que pases tú mismo debe tener de 1 a 128 caracteres de
A-Za-z0-9_-; no la reutilices para un paquete distinto. La CLI imprime la
clave cuando es posible que se haya enviado una compra:
hushscript buy 300min --yes --key <key>
Tokens de reanudación
Una vez que existe un job, un error lleva un token de reanudación junto a la
clave de idempotencia. Una espera que se agota lanza WaitTimeoutError con el
token, y el job sigue ejecutándose. Pasa el token a resume() para continuar
sin un segundo cobro: un job que ya pasó la etapa de subida no necesita el
archivo, y uno que aún está subiendo se continúa con el mismo archivo. En PHP:
try {
$hs->transcribe($path, ['wait_timeout' => 60]);
} catch (\Hushscript\Exception\WaitTimeoutError $timeout) {
$transcript = $hs->resume($timeout->resumeToken, $path);
}
En la CLI, Ctrl-C durante transcribe imprime el token de reanudación del job
y el comando que lo continúa:
hushscript resume <token> meeting.mp3 --format srt --out meeting.srt
Registros y redacción
Los SDK no envían telemetría; el encabezado User-Agent es la única
identificación del cliente. El registro está desactivado por defecto.
HUSHSCRIPT_LOG=debug escribe una línea por solicitud en la salida de error
estándar con el método, la ruta, el estado y el tiempo, y nunca un encabezado,
un cuerpo, un título ni texto de la transcripción.
El token se redacta de todo error, línea de registro y forma impresa del
cliente. En los mensajes de error, las sugerencias y las causas, una URL
conserva su host y su ruta, pero su cadena de consulta pasa a ser
?[redacted], así que una URL de subida firmada nunca se imprime. Los
resultados que te entregan un secreto, como un secreto de reclamo o un token
nuevo, lo mantienen legible como campo pero muestran [redacted] al
imprimirse; una exportación JSON es tuya y lleva el valor. La CLI limpia de
stderr todos los tokens que conoce; sus resultados en stdout son tu salida y no
se limpian.
Configuración
| Ajuste | Variable de entorno | Valor por defecto |
|---|---|---|
| Token | HUSHSCRIPT_TOKEN |
ninguno |
| URL base | HUSHSCRIPT_BASE_URL |
https://api.hushscript.com |
| Nivel de registro | HUSHSCRIPT_LOG |
off |
| Tiempo de espera de solicitud | ninguna | 60 segundos |
| Reintentos | ninguna | 3 |
Una opción pasada en código se impone sobre su variable de entorno, y un valor vacío cuenta como no definido. Los minutos salen del mismo saldo que la aplicación; los paquetes y los precios están en la página de precios.