O Hushscript também responde a chamadas REST simples, para agentes e scripts que preferem chamar um endpoint HTTP a rodar um cliente MCP. É a mesma conta, o mesmo saldo e os mesmos tokens de portador do início ao fim: nada aqui muda como a transcrição é cobrada ou armazenada.
Início rápido
A API exige um token de acesso pessoal, e há duas formas de conseguir um.
Uma pessoa cria um em Tokens, na página MCP da conta,
escolhe os escopos dele e decide se ele pode comprar minutos. Ou um agente
abre a própria conta sem nenhuma pessoa envolvida: POST /v1/agent/accounts
inicia um cadastro pago, e POST /v1/agent/accounts/{signup_id}/claim troca
o segredo de reivindicação de uso único por uma conta de verdade e um
primeiro token. De um jeito ou de outro, o token é exibido uma única vez e
tem o formato hsr1:<region>:pat.<id>.<secret>. Um token gerado pelo login
OAuth do servidor MCP também funciona aqui; veja Conectar.
Um token nunca pode gerar, listar ou revogar outros tokens, e uma conta
mantém no máximo 25 ativos; o fluxo completo de conta de agente, incluindo a
rotação de credencial, está no guia Uso automatizado.
Depois de ter um token, chame a API diretamente:
curl https://api.hushscript.com/v1/account \
-H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"
{
"balance_seconds": 0,
"held_seconds": 0,
"credits_expire_at": null,
"card_on_file": false,
"data_region": "eu",
"limits": {
"max_active_jobs": 3,
"max_daily_seconds": 36000,
"active_jobs": 0,
"daily_seconds_used": 0
}
}
Isso responde o saldo em segundos, os segundos retidos por jobs em
execução, a data de expiração do crédito, se há um cartão salvo, a região
de dados, e os limites de admissão (max_active_jobs, max_daily_seconds
e o que já foi usado). Uma conta nova começa com saldo zero.
POST /v1/uploads verifica o saldo, não o cartão: sem minutos, ele retorna
3001 insufficient_balance. O cartão é como o saldo chega até ali, já que
a verificação única de cartão no aplicativo libera os 30 minutos grátis, e
os pacotes são comprados contra um cartão salvo.
Automatizando do início ao fim
Tudo depois que a conta existe roda sem nenhuma pessoa, seja essa conta
aberta por uma pessoa no aplicativo ou por um agente por meio de
/v1/agent/accounts (veja Uso automatizado). Uma única
etapa de navegador permanece, e um agente pode conduzi-la sozinho.
-
Leia a conta.
GET /v1/account. Secard_on_fileforfalse, salve um cartão primeiro. -
Salve um cartão, uma vez.
POST /v1/billing/setup-sessionretorna umcheckout_url, umsession_ide umexpires_at:curl -X POST https://api.hushscript.com/v1/billing/setup-session \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"{ "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4e5F6g7H8", "session_id": "seti_1PxYzQ2eZvKYlo2C", "expires_at": "2026-09-11T15:45:00Z" }Abra a URL em um navegador que você controla e complete a página hospedada do Stripe; nada é cobrado e o Hushscript nunca vê o cartão. Depois,
GET /v1/billing/cardslista o cartão com o id dele.POST /v1/billing/cards/defaulttroca o padrão se a conta mantiver vários. -
Compre minutos.
GET /v1/billing/packslista os cinco pacotes comid,seconds,amountecurrency:curl https://api.hushscript.com/v1/billing/packs \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"POST /v1/billing/purchasecompack,quick_payment_method_id(o id do cartão salvo) e umidempotency_keycobra o cartão fora de sessão e responde o novobalance_seconds:curl -X POST https://api.hushscript.com/v1/billing/purchase \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \ -H "Content-Type: application/json" \ -d '{ "pack": "300min", "quick_payment_method_id": "pm_2QeT4bY7uX9mK3nP", "idempotency_key": "purchase-2026-09-11-02" }'{ "balance_seconds": 18000 }Isso exige o escopo
billingno token e o faturamento habilitado para a conta. Um corpo sem id de cartão, ou um cartão recusado, é rejeitado com4021 pat_purchase_requires_app; um cartão que o emissor quer contestar é rejeitado com4023 pat_purchase_requires_authentication. Nenhum dos dois abre uma página que ninguém consegue concluir. -
Envie o arquivo.
POST /v1/uploadscomsize_bytes,duration_seconds(de 15 segundos a 10 horas), umtitleopcional,transcription_optionse umidempotency_key:curl -X POST https://api.hushscript.com/v1/uploads \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \ -H "Content-Type: application/json" \ -d '{ "size_bytes": 41943040, "duration_seconds": 1200, "title": "Q3 board call", "transcription_options": { "speaker_detection": true }, "idempotency_key": "upload-2026-09-11-02" }'Isso coloca uma retenção de crédito e responde um
job_idmais uma primeira página de URLs de partes pré-assinadas:{ "job_id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8", "part_urls": [ { "n": 1, "url": "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." } ] }Envie cada parte com
PUTpara a sua URL (partes de 32 MiB por padrão, a última menor):curl -X PUT "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." \ --data-binary @part-01.binBusque páginas seguintes em
GET /v1/uploads/{job}/part-urls?start=<n>, e chamePOST /v1/uploads/{job}/heartbeatbem dentro do tempo limite de inatividade de 20 minutos durante uma transferência longa. Quando URLs pré-assinadas não estão disponíveis, ou uma parte falha,PUT /v1/uploads/{job}/parts/{n}envia os bytes dessa parte pela própria API; umPUTrepetido substitui a parte, então repetir a tentativa é seguro. Somente áudio: mp3, m4a, wav, flac, ogg ou opus, no máximo 5 GB, verificado no servidor; extraia a trilha de áudio de um vídeo antes de enviar. -
Inicie e aguarde.
POST /v1/uploads/{job}/completecom one oetagde cada parte enviada para uma URL pré-assinada (omitapartsquando toda parte foi enviada pela API):curl -X POST https://api.hushscript.com/v1/uploads/job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8/complete \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293" \ -H "Content-Type: application/json" \ -d '{ "parts": [ { "n": 1, "etag": "\"9f86d081884c7d65\"" } ] }'Depois, consulte
GET /v1/jobs/{id}:statepassa poruploading,queuedeprocessingatédoneoufailed, e um job concluído traz umtranscript_id:curl https://api.hushscript.com/v1/jobs/job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8 \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"{ "id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8", "state": "done", "transcript_id": "trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9" } -
Leia o resultado.
GET /v1/transcripts/{id}retorna os metadados e o corpo completo, com nomes de falantes, o idioma detectado, tags e a data de exclusão automática:curl https://api.hushscript.com/v1/transcripts/trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9 \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"GET /v1/transcriptspagina a lista.
As opções de transcrição são as mesmas do aplicativo, ao pé da letra:
language_code ou detecção automática, speaker_detection, medical_mode
(exige language_code em en, es, fr ou de, cobrado a +100%),
translation_targets (+25% por idioma), multichannel, keyterms_prompt,
um prompt de texto livre, e os dictionary_ids e o prompt_preset_id
salvos que GET /v1/transcription-context lista.
Parte da conta ainda é exclusiva do MCP. Importar de um link, editar ou
excluir transcrições, Insights, exportações, salvar dicionários e
predefinições de prompt, e as configurações da conta ainda não têm rota
/v1/; o servidor MCP cobre tudo isso com o mesmo token.
Autenticação
Toda chamada /v1/ carrega um token de portador no cabeçalho
Authorization, verificado contra os mesmos escopos que o servidor MCP
usa:
| Escopo | O que ele permite |
|---|---|
transcripts:read |
Ler e exportar transcrições, seus metadados e a lista de excluídas |
transcripts:write |
Editar, marcar, traduzir, restaurar e excluir transcrições |
transcribe |
Enviar gravações, importar de um link e executar transcrições |
insights |
Ler, gerar e excluir Insights |
context |
Gerenciar dicionários salvos e predefinições de prompt |
account:read |
Ler saldo, uso, transações e retenções |
settings:write |
Alterar as configurações da conta |
org:read |
Ler membros do espaço de trabalho, extrato, faturas e log de auditoria |
export |
Solicitar uma exportação completa da conta, verificar o status dela e baixá-la |
billing |
Salvar um cartão e comprar pacotes de minutos |
Uma chamada fora dos escopos do token falha com pat_scope_missing,
em 403. O escopo billing também fica inerte até o titular da conta habilitar
o faturamento para a conta no aplicativo; uma chamada de faturamento em uma
conta com essa chave desligada falha com o mesmo pat_scope_missing, e
gerar um novo token não resolve isso. Um token não pode criar, listar nem
revogar tokens, e uma conta mantém no máximo 25 ativos.
Endpoints
Ativos hoje, cada um protegido pelo escopo indicado:
| Método | Caminho | Escopo |
|---|---|---|
POST |
/v1/agent/accounts |
none |
POST |
/v1/agent/accounts/{signup_id}/claim |
none |
POST |
/v1/agent/credentials/rotate |
none |
GET |
/v1/account |
account:read |
POST |
/v1/billing/setup-session |
billing |
GET |
/v1/billing/cards |
billing |
POST |
/v1/billing/cards/default |
billing |
GET |
/v1/billing/packs |
billing |
POST |
/v1/billing/purchase |
billing |
GET |
/v1/billing/transactions |
account:read |
GET |
/v1/billing/ledger |
account:read |
GET |
/v1/billing/holds |
account:read |
POST |
/v1/uploads |
transcribe |
GET |
/v1/uploads/{job}/part-urls |
transcribe |
PUT |
/v1/uploads/{job}/parts/{n} |
transcribe |
POST |
/v1/uploads/{job}/heartbeat |
transcribe |
POST |
/v1/uploads/{job}/complete |
transcribe |
GET |
/v1/jobs |
transcribe |
GET |
/v1/jobs/{id} |
transcribe |
GET |
/v1/transcripts |
transcripts:read |
GET |
/v1/transcripts/deleted |
transcripts:read |
GET |
/v1/transcripts/{id} |
transcripts:read |
GET |
/v1/transcription-context |
context |
GET |
/v1/org/members |
org:read |
GET |
/v1/org/invoices |
org:read |
GET |
/v1/org/ledger |
org:read |
GET |
/v1/org/audit |
org:read |
/v1/agent/accounts abre um cadastro sem interface e ainda sem token,
/v1/agent/accounts/{signup_id}/claim transforma um cadastro pago em uma
conta de verdade e seu primeiro token, e /v1/agent/credentials/rotate
gera um sucessor para o token que fez a chamada e o revoga, sem tocar em
nenhuma outra credencial da conta. O guia Uso automatizado
cobre os três, do início ao fim.
Toda listagem aceita um limit e um cursor opaco, e responde um
next_cursor que é nulo na última página. Devolva o cursor sem alterá-lo;
ele codifica a posição, então nenhuma página é pulada ou repetida quando
linhas chegam entre chamadas.
A definição completa e atual, com parâmetros e esquemas de resposta para toda operação, é o documento OpenAPI: trate-o como a fonte da verdade acima desta tabela. Ele é servido a qualquer token de portador, independentemente do escopo, então um cliente pode buscá-lo com as credenciais que já tem.
Interface MCP
Prefere ferramentas a HTTP puro? O servidor MCP coloca a mesma conta atrás de 51 ferramentas em vez desses endpoints, para um cliente que já fala MCP em vez de REST.
Limites
Requisições feitas com um token são limitadas a 1.200 por minuto por
token. POST /v1/billing/setup-session e POST /v1/billing/purchase
compartilham uma cota mais apertada de 60 por minuto por conta, antes da
chamada ao Stripe que fariam. Uma requisição recusada responde
429 rate_limited com um cabeçalho Retry-After informando a espera em
segundos; aguarde esse tempo antes de tentar de novo. Envios são limitados
a 5 GB e 10 horas, com um mínimo de 15 segundos, e os limites de admissão
da própria conta (max_active_jobs, max_daily_seconds) são informados
por GET /v1/account.
Sandbox
Não existe modo de simulação: toda chamada /v1/ roda contra uma conta de
verdade, e comprar minutos gasta dinheiro de verdade.
Erros
Um erro é um corpo JSON com um code numérico estável e um slug error,
no status HTTP indicado abaixo. Os corpos de erro /v1/ são uma projeção
congelada: error, code e um conjunto fixo de chaves de detalhe. O
formato de erro de /api não é congelado e pode trazer mais campos. Os
códigos que quem chama de forma automatizada precisa tratar:
| Status | Código | Slug | Significado |
|---|---|---|---|
| 401 | 2000 | unauthorized |
Token de portador ausente ou inválido |
| 403 | 2022 | pat_forbidden |
A rota não aceita nenhum token |
| 403 | 2023 | pat_scope_missing |
O token não tem o escopo que essa chamada exige, ou o faturamento está desligado para a conta |
| 403 | 4021 | pat_purchase_requires_app |
Nenhum cartão salvo foi indicado, ou a cobrança foi recusada; nada foi cobrado |
| 403 | 4023 | pat_purchase_requires_authentication |
A emissora do cartão exige um desafio que quem chamou não consegue completar; o cartão em si está normal |
| 402 | 3001 | insufficient_balance |
Saldo insuficiente para admitir o job |
| 402 | 3002 | card_declined |
O cartão salvo foi recusado |
| 402 | 3003 | org_insufficient_balance |
O pool do espaço de trabalho que financia esse envio está baixo |
| 404 | 4000 | not_found |
Não existe esse job, envio ou recurso |
| 409 | 4001 | wrong_state |
O recurso não está em um estado que permite isso |
| 422 | 1021 | duration_out_of_range |
A duração informada é menor que 15 segundos ou maior que 10 horas |
| 429 | 5000 | rate_limited |
Requisições demais; aguarde Retry-After |
| 502 | 6001 | provider_error |
Um serviço upstream falhou |
| 500 | 9000 | internal_error |
Um erro inesperado do servidor |
O documento OpenAPI nomeia o código exato que cada operação pode retornar,
e o servidor MCP publica o catálogo completo como o recurso
hushscript://error-codes.