Os SDKs oficiais encapsulam a API REST para código de servidor e scripts. Uma chamada transcreve um arquivo: ela envia a gravação, espera o job e devolve a transcrição. No meio do caminho, o SDK verifica o arquivo antes de qualquer minuto ser reservado, repete o que é seguro repetir, mantém vivo um envio longo e leva uma chave de idempotência em cada envio e em cada compra, para que uma nova tentativa nunca cobre duas vezes. A CLI é construída sobre o SDK de TypeScript e faz o mesmo a partir de um terminal.
Pacotes
| Linguagem | Pacote | Registro | Código-fonte |
|---|---|---|---|
| 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 |
Versões mínimas de runtime:
- TypeScript: Node 22 ou mais recente. Bun 1.2+ e Deno 2+ são verificados apenas para importar o pacote, não para o comportamento HTTP deles.
- Python: 3.10 ou mais recente.
- Go: 1.25 ou mais recente.
- PHP: 8.2 ou mais recente, com
ext-jsoneext-mbstring;ext-curlpara envios simultâneos de partes. - CLI: Node 22 ou mais recente.
Os SDKs são para servidores e scripts. A API não aceita origens de navegador,
e um token em um bundle de navegador é um token vazado, então o SDK de
TypeScript se recusa a iniciar onde existem window e document.
Obter um token
Todo SDK e a CLI se autenticam com um token de acesso pessoal. Crie um em
Criar um novo token, na página MCP da conta,
escolha os escopos de que seu código precisa e decida se ele pode comprar
minutos. O token é exibido uma única vez e tem o formato
hsr1:<region>:pat.<id>.<secret>. Os escopos e o funcionamento de um token
estão na página da API.
Os SDKs leem o token de HUSHSCRIPT_TOKEN quando você não passa um:
export HUSHSCRIPT_TOKEN=hsr1:...
Um agente também pode abrir a própria conta, pagá-la em uma página de
checkout hospedada e reivindicar o primeiro token por código:
Hushscript.agent.signup() e Hushscript.agent.claim() em TypeScript,
Hushscript.agent_signup() e Hushscript.agent_claim() em Python, AgentSignup e AgentClaim em
Go, e Client::agentSignup() e Client::agentClaim() em PHP. O fluxo e suas
regras estão em 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() aceita um caminho, um Blob, um Uint8Array ou um
ReadableStream<Uint8Array>. Um stream precisa do size e do
durationSeconds exatos. hs.balance() devolve os minutos que você pode
gastar, hs.transcripts.list() percorre as transcrições concluídas e
hs.buy("300min", { acknowledgeNoRefund: true }) compra um pacote. Toda
operação /v1 também está disponível como hs.api, com as mesmas tentativas
repetidas, os mesmos timeouts e a mesma ocultação de dados sensíveis.
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")
Toda chamada tem uma gêmea asyncio em AsyncHushscript, com os mesmos nomes.
transcribe() aceita um caminho, bytes ou um objeto de arquivo binário; um
objeto de arquivo que não permite seek precisa de size e
duration_seconds. hs.balance(), hs.transcripts.list() e
hs.buy("300min", acknowledge_no_refund=True) cobrem o saldo, a lista de
transcrições e as 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 aceita um caminho, TranscribeReader um io.ReaderAt e seu
tamanho exato, e TranscribeStream um leitor somente sequencial com seu
tamanho e DurationSeconds. client.Balance, client.Transcripts.List e
client.Buy cobrem o saldo, a lista de transcrições e as compras. As opções
que podem estar desligadas, ligadas ou indefinidas são *bool, criadas com
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() aceita um caminho ou um stream aberto; um stream que não
permite seek precisa das opções size e duration_seconds. As opções usam
chaves de array em snake_case, e os resultados usam propriedades em
camelCase. $hs->balance(), $hs->transcripts()->list() e
$hs->buy('300min', true) cobrem o saldo, a lista de transcrições e as
compras. No Laravel, vincule um único Client em um service provider e
execute as transcrições em um job em fila, com uma opção idempotency_key
estável.
CLI
npm install --global @hushscript/cli
hushscript login
hushscript transcribe meeting.mp3 --format srt --out meeting.srt
A CLI pega o token de --token, depois de HUSHSCRIPT_TOKEN e, por fim, do
que hushscript login armazenou. O login pede o token sem exibi-lo na tela
e o guarda em um arquivo que só o seu usuário consegue ler; hushscript logout o apaga. Em CI, prefira a variável de ambiente.
| Comando | O que faz |
|---|---|
login |
Pede um token e o armazena. |
logout |
Apaga o token armazenado. |
balance |
Mostra os minutos que você pode gastar. |
transcribe <file> |
Envia uma gravação, espera e imprime a transcrição. Flags: --language, --translate, --format srt|vtt|txt|json, --out, --key. |
resume <token> <file> |
Conclui uma transcrição que o transcribe deixou pela metade. |
transcripts |
Lista as transcrições concluídas, da mais recente para a mais antiga. |
transcript <id> |
Imprime uma transcrição. |
jobs |
Lista os jobs; --active para os que ainda não terminaram. |
packs |
Lista os pacotes de minutos que você pode comprar, com os preços. |
buy <pack> |
Compra um pacote com o cartão padrão salvo. Flags: --yes, --key. |
--json imprime um único documento JSON no stdout e nada além disso, e
transforma o stderr em JSON Lines. O código de saída é 0 em caso de sucesso,
1 quando a API ou o SDK reportou um erro, 2 para um erro de uso (nada foi
enviado) e 130 quando a execução foi interrompida.
Arquivos compatíveis
MP3, M4A, MP4 e MOV (usa-se a trilha de áudio do vídeo), WAV, FLAC e OGG com Vorbis ou Opus, de 15 segundos a 10 horas. Os SDKs verificam o formato pelos bytes do arquivo e medem a duração antes de qualquer minuto ser reservado. Eles não convertem mídia, então converta qualquer outro formato antes:
ffmpeg -i input -vn -c:a libopus output.opus
Erros
Todo erro lançado por um SDK pertence a uma única família, então um só
catch cobre tudo: HushscriptError em TypeScript e Python,
*hushscript.Error em Go e HushscriptException em PHP. Um erro traz um
code em formato de slug, como insufficient_balance, o código numérico, o
status HTTP, uma mensagem, uma hint que diz o que fazer em seguida, os
detalhes e retryAfter (em PHP o slug é errorCode; em 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;
}
Um PreflightError significa que o SDK recusou o arquivo antes de qualquer
crédito ser reservado. Se o seu saldo cobre um arquivo é decisão do servidor:
um 402 volta quando o envio é criado, antes de qualquer parte ser enviada.
Cobrança e novas tentativas
Todo envio e toda compra levam uma chave de idempotência, e as novas tentativas a reutilizam, de modo que uma chamada repetida reproduz a primeira em vez de iniciar uma segunda.
buy() cobra o seu cartão padrão salvo. Comprar por código fica desativado
até que três chaves o permitam: o token tem o escopo billing, o token está
com “Permitir que este token compre minutos” ativado e “Permitir que aplicativos
conectados comprem minutos” está ativado na conta. Se qualquer uma faltar, a
chamada falha com pat_scope_missing. Mostre ao seu comprador o aviso de
não reembolso antes de chamá-lo.
Uma compra é repetida no máximo uma vez, após um erro de rede, um 502 ou um
503, com a mesma chave. Algumas respostas provam que nada foi cobrado: um
400, 402, 404 ou 422, e um 403 com o código 4021 (pat_purchase_requires_app,
o cartão foi recusado ou não pode ser cobrado sem você) ou 4023
(pat_purchase_requires_authentication, o banco quer confirmar o
pagamento). Depois de 4021 ou 4023, compre o pacote no app. Qualquer outra
falha depois de a requisição ter sido enviada, inclusive um 401 ou um 429,
significa que o cartão pode ter sido cobrado. Esse erro traz a chave de
idempotência: peça de novo com a mesma chave, e a compra nunca poderá
acontecer duas vezes. Em 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)
Uma compra que falhou antes de a requisição ser enviada não traz chave:
nada foi cobrado. Uma chave que você mesmo passa deve ter de 1 a 128
caracteres de A-Za-z0-9_-; não reutilize uma para outro pacote. A CLI
imprime a chave quando uma compra pode ter sido enviada:
hushscript buy 300min --yes --key <key>
Tokens de retomada
Quando um job já existe, um erro traz um token de retomada junto com a chave
de idempotência. Uma espera que estoura o tempo lança WaitTimeoutError com
o token, e o job continua em execução. Passe o token de volta a resume()
para seguir adiante sem uma segunda cobrança: um job que já passou do envio
não precisa do arquivo, e um que ainda está sendo enviado continua com o mesmo
arquivo. Em PHP:
try {
$hs->transcribe($path, ['wait_timeout' => 60]);
} catch (\Hushscript\Exception\WaitTimeoutError $timeout) {
$transcript = $hs->resume($timeout->resumeToken, $path);
}
Na CLI, Ctrl-C durante o transcribe imprime o token de retomada do job e o
comando que o continua:
hushscript resume <token> meeting.mp3 --format srt --out meeting.srt
Logs e ocultação de dados
Os SDKs não enviam telemetria; o cabeçalho User-Agent é a única
identificação do cliente. O registro de logs vem desativado por padrão.
HUSHSCRIPT_LOG=debug escreve uma linha por requisição no erro padrão, com o
método, o caminho, o status e o tempo, e nunca um cabeçalho, corpo, título ou
texto de transcrição.
O token é ocultado em todo erro, linha de log e forma impressa do cliente.
Em mensagens de erro, dicas e causas, uma URL mantém o host e o caminho, mas
a query string vira ?[redacted], então uma URL de envio assinada nunca é
impressa. Resultados que entregam um segredo, como um segredo de
reivindicação ou um novo token, o mantêm legível como campo, mas mostram
[redacted] quando impressos; uma exportação em JSON é sua e traz o valor. A
CLI remove do stderr todo token que conhece; os resultados dela no stdout são
a sua saída e não são limpos.
Configuração
| Configuração | Variável de ambiente | Padrão |
|---|---|---|
| Token | HUSHSCRIPT_TOKEN |
nenhum |
| URL base | HUSHSCRIPT_BASE_URL |
https://api.hushscript.com |
| Nível de log | HUSHSCRIPT_LOG |
off |
| Timeout da requisição | nenhuma | 60 segundos |
| Novas tentativas | nenhuma | 3 |
Uma opção passada no código vale mais que a variável de ambiente correspondente, e um valor vazio conta como não definido. Os minutos vêm do mesmo saldo do app; pacotes e preços estão na página de preços.