A API de fala para texto do Hushscript recebe áudio gravado por /v1/, e
depois seu script consulta o job e lê a transcrição. É um fluxo de
transcrição online, não um endpoint de streaming ao vivo nem de modelo de
reconhecimento bruto. O servidor MCP usa a mesma conta, o mesmo saldo
e o mesmo token de portador, quando seu cliente prefere ferramentas a
chamadas HTTP.
Transcrição de áudio e vídeo pela API
A API de transcrição de áudio aceita arquivos de áudio já preparados, inclusive voz gravada. Para uma integração de STT (fala para texto), envie arquivos gravados; não há streaming ao vivo pelo microfone. Para transcrever vídeo, envie um arquivo MP4 ou MOV com trilha de áudio como está: o servidor lê a trilha de áudio e ignora o vídeo. Extraia antes o áudio de qualquer outro formato de vídeo; a API não aceita a URL de um vídeo. O fluxo no navegador está explicado em vídeo para texto.
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. Este exemplo representa uma conta pessoal nova antes da verificação de cartão ou de uma compra; uma conta criada por um agente começa com o pacote de minutos que ela pagou:
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": 50,
"max_daily_seconds": 144000,
"active_jobs": 0,
"used_today_seconds": 0
}
}
A resposta traz o saldo em segundos, os segundos reservados por jobs em
execução, credits_expire_at (sempre null, porque os minutos não expiram), 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). O limite diário é o limite efetivo atual da conta, não um valor para fixar no código. POST /v1/uploads verifica os minutos disponíveis, não o cartão: sem minutos suficientes, ele retorna 3001 insufficient_balance.
A API de fala para texto é grátis?
Não há um nível gratuito geral da API, mas você pode testar o fluxo antes de escrever qualquer código: a prévia pública transcreve até cinco minutos de uma gravação antes do login. Uma conta pessoal elegível recebe então 30 minutos grátis após a verificação do cartão (veja os preços para entender como funciona); uma conta criada por um agente não recebe os minutos de boas-vindas e começa com o pacote que compra no cadastro. Um job completo da API exige uma conta e minutos, de qualquer forma.
Automatizando do início ao fim
As mesmas chamadas /v1/ funcionam com um token criado por uma pessoa no aplicativo ou reivindicado por um agente após o cadastro pago (veja Uso automatizado). Salvar um cartão exige o Checkout hospedado em um navegador; um agente pode conduzi-lo. Compras posteriores fora de sessão ainda podem ser recusadas se o emissor do cartão exigir autenticação.
-
Leia a conta.
GET /v1/account. Se você precisa comprar minutos ecard_on_filefor false, 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 retorna 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
billing, o faturamento habilitado no 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 em que o emissor exige autenticação adicional é 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_options,matter_codee 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" }'matter_codeé texto livre de até 64 caracteres, e só tem significado para um token que pertence a um espaço de trabalho: aparece junto ao job no extrato e nos relatórios de uso desse espaço de trabalho. Um espaço de trabalho cuja política de casos esteja definida como obrigatória recusa um envio que chegue sem um, comorg_matter_code_required.client_codeé aceito e ignorado, porque o cliente é um atributo do caso, definido por um administrador do espaço de trabalho.Isso coloca uma reserva de crédito e retorna 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 URL dela (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. Formatos aceitos: mp3, m4a, mp4 ou mov (a trilha de áudio é usada, as trilhas de vídeo são ignoradas), wav, flac, ogg ou opus, verificados no servidor; extraia o áudio de qualquer outro formato de 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 reservas |
settings:write |
Alterar as configurações da conta |
org:read |
Ler membros do espaço de trabalho, extrato, faturas e log de auditoria |
org:write |
Alterar os direitos dos membros, agendar a transição para a custódia institucional (permanente), e aplicar ou remover bloqueios legais |
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 a menos que o faturamento esteja habilitado tanto
no token quanto na conta. Uma chamada de faturamento com qualquer uma das chaves
desligada falha com o mesmo pat_scope_missing; gerar um novo token não liga a chave
da conta. Um token não pode criar, listar nem revogar tokens, e uma conta mantém no
máximo 25 ativos.
Esses 11 escopos são selecionáveis por quem chama. pat:rotate é um escopo separado,
concedido ao primeiro token de uma conta de agente e a seus sucessores rotacionados;
ele permite que esse token substitua a si mesmo, não que gerencie outros tokens. Você
não pode selecioná-lo ao criar um token no aplicativo.
Endpoints
O documento OpenAPI de produção lista 38 operações método/caminho em 37 caminhos. Cada operação abaixo é protegida 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 |
pat:rotate |
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 |
org:read |
GET |
/v1/org/members |
org:read |
PATCH |
/v1/org/members/{user_id} |
org:write |
GET |
/v1/org/matters |
org:read |
GET |
/v1/org/transcripts |
org:read |
POST |
/v1/org/transcripts/{id}/hold |
org:write |
DELETE |
/v1/org/transcripts/{id}/hold |
org:write |
POST |
/v1/org/custody |
org:write |
GET |
/v1/org/invoices |
org:read |
GET |
/v1/org/ledger |
org:read |
GET |
/v1/org/ledger.csv |
org:read |
GET |
/v1/org/usage |
org:read |
GET |
/v1/org/usage.csv |
org:read |
GET |
/v1/org/audit |
org:read |
GET |
/v1/org/audit.csv |
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 aposenta quando o sucessor
é usado pela primeira vez, 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 retorna 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, com prioridade sobre esta 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 56 ferramentas em vez desses endpoints, para um cliente que já fala MCP em vez de REST. Ele anuncia apenas as ferramentas que os escopos do token conectado permitem.
Limites
Requisições feitas com o token de uma conta humana são limitadas a 1.200 por minuto por token. Os tokens rotacionados de uma conta de agente compartilham esse orçamento em toda a conta. As rotas de faturamento que chamam o Stripe compartilham uma cota mais apertada de 60 por minuto por conta para chamadores PAT: sessão de configuração, compra, troca do cartão padrão, remoção de cartão e falhas de cache da lista de cartões. A limitação comum retorna 429 rate_limited com Retry-After em segundos; aguarde esse tempo antes de tentar de novo. Compras de uma conta de agente ou feitas com o PAT de uma conta humana compartilham um teto de 3 tentativas a cada 24 horas móveis por conta. A compra de cadastro do agente conta; recusas ou erros após a reserva também contam. Uma compra feita em uma sessão de navegador humana é isenta. Uma recusa pelo teto retorna HTTP 429 com 4038 agent_purchase_capped e Retry-After. As gravações podem ter de 15 segundos a 10 horas. GET /v1/account informa os limites de admissão atuais da conta (max_active_jobs, max_daily_seconds).
Sandbox
Não existe um sandbox geral de transcrição: chamadas /v1/ comuns rodam contra contas de verdade, e compras gastam dinheiro de verdade. A exceção é a validação de cadastro: POST /v1/agent/accounts aceita dry_run: true, retorna um id de cadastro dry_ que não pode ser reivindicado e não abre nenhuma sessão do Stripe nem conta.
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 |
O emissor do cartão exige um desafio que quem chamou não consegue completar; o cartão em si não tem problema |
| 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 banco de horas compartilhado do espaço de trabalho que financia esse envio não tem saldo suficiente |
| 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 | 4038 | agent_purchase_capped |
A conta usou sua cota de tentativas de compra por token; aguarde Retry-After |
| 429 | 5000 | rate_limited |
Requisições demais; aguarde Retry-After |
| 502 | 6001 | provider_error |
Um serviço externo 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.