La API de voz a texto de Hushscript acepta audio grabado a través de /v1/, y
luego tu script consulta el job y lee la transcripción. Es un flujo de
transcripción en línea, no un endpoint de streaming en vivo ni de un modelo de
reconocimiento sin procesar. El servidor MCP usa la misma cuenta, el
mismo saldo y el mismo token bearer cuando tu cliente prefiere herramientas a
llamadas HTTP.
Transcripción de audio y video mediante la API
La API de transcripción de audio acepta archivos de audio ya preparados, incluida la voz grabada. Para una integración de STT (voz a texto), envía archivos grabados; no hay transmisión en vivo desde el micrófono. Para transcribir video, sube tal cual un archivo MP4 o MOV con pista de audio: el servidor lee la pista de audio y omite el video. Extrae primero el audio de cualquier otro formato de video; la API no acepta la URL de un video. El flujo en el navegador se explica en video a texto.
Inicio rápido
La API necesita un token de acceso personal, y hay dos formas de conseguir
uno. Una persona crea uno en Tokens, en la página de MCP de la
cuenta, elige sus scopes y decide si
puede comprar minutos. O un agente abre su propia cuenta sin ninguna persona
involucrada: POST /v1/agent/accounts inicia un registro pagado, y
POST /v1/agent/accounts/{signup_id}/claim cambia su secreto de reclamo de
un solo uso por una cuenta real y un primer token. De cualquier forma, el
token se muestra una sola vez y tiene la forma
hsr1:<region>:pat.<id>.<secret>. Un token generado mediante el inicio de
sesión OAuth del servidor MCP también funciona aquí; consulta
Conéctate. Un token nunca puede generar, listar ni revocar
otros tokens, y una cuenta tiene como máximo 25 activos; el flujo completo de
cuenta de agente, incluida la rotación de credenciales, está en la guía de
Uso automatizado.
Una vez que tienes un token, llama a la API directamente. Este ejemplo representa una cuenta personal nueva antes de la verificación de tarjeta o de una compra; una cuenta creada por un agente empieza con el paquete de minutos que pagó:
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
}
}
Eso devuelve el saldo en segundos, los segundos retenidos por jobs en curso,
credits_expire_at (siempre null, porque los minutos no caducan), si hay una tarjeta guardada, la
región de datos y los límites de admisión (max_active_jobs,
max_daily_seconds, y lo que ya se usó). El límite diario es el límite efectivo actual de la cuenta, no un valor para codificar a mano. POST /v1/uploads verifica los minutos disponibles, no la tarjeta: sin minutos suficientes, devuelve 3001 insufficient_balance.
¿La API de voz a texto es gratuita?
No hay un nivel gratuito general de la API, pero puedes probar el flujo antes de escribir código: la vista previa pública transcribe hasta cinco minutos de una grabación antes de iniciar sesión. Una cuenta personal elegible recibe después 30 minutos gratis tras la verificación de la tarjeta (consulta los precios para ver cómo funciona); una cuenta creada por un agente omite los minutos de bienvenida y empieza con el paquete que compra al registrarse. Un job completo de la API necesita una cuenta y minutos en cualquier caso.
Automatizar de principio a fin
Las mismas llamadas /v1/ funcionan con un token creado por una persona en la aplicación o con uno reclamado por un agente tras el registro pagado (consulta Uso automatizado). Guardar una tarjeta requiere el Checkout alojado en un navegador; un agente puede manejarlo. Las compras posteriores fuera de sesión aún pueden ser rechazadas si el emisor de la tarjeta exige autenticación.
-
Lee la cuenta.
GET /v1/account. Si necesitas comprar minutos ycard_on_filees false, guarda una tarjeta primero. -
Guarda una tarjeta, una sola vez.
POST /v1/billing/setup-sessiondevuelve uncheckout_url, unsession_idy unexpires_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" }Abre la URL en un navegador que controles y completa la página alojada de Stripe; no se cobra nada y Hushscript nunca ve la tarjeta. Luego
GET /v1/billing/cardsla lista con su id.POST /v1/billing/cards/defaultcambia la predeterminada si la cuenta tiene varias. -
Compra minutos.
GET /v1/billing/packslista los cinco paquetes conid,seconds,amountycurrency:curl https://api.hushscript.com/v1/billing/packs \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"POST /v1/billing/purchaseconpack,quick_payment_method_id(el id de la tarjeta guardada) y unidempotency_keycobra la tarjeta fuera de sesión y devuelve el nuevobalance_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 }Esto necesita el scope
billing, la facturación activada en el token y la facturación activada para la cuenta. Un cuerpo sin id de tarjeta, o una tarjeta rechazada, se rechaza con4021 pat_purchase_requires_app; una tarjeta que el emisor quiere verificar se rechaza con4023 pat_purchase_requires_authentication. Ninguno de los dos abre una página que nadie pueda completar. -
Sube el archivo.
POST /v1/uploadsconsize_bytes,duration_seconds(de 15 segundos a 10 horas), untitleopcional,transcription_options,matter_codey unidempotency_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_codees texto libre de hasta 64 caracteres, y solo tiene sentido para un token que pertenece a un espacio de trabajo: aparece junto al job en el historial de movimientos y los informes de uso de ese espacio de trabajo. Un espacio de trabajo cuya política de asuntos esté configurada como obligatoria rechaza una subida que llegue sin uno, conorg_matter_code_required.client_codese acepta y se ignora, porque el cliente es un atributo del asunto, establecido por un administrador del espacio de trabajo.Coloca una retención de crédito y devuelve un
job_idmás una primera página de URLs de parte prefirmadas:{ "job_id": "job_5e2a91cf4d7b6081a9f3c2e4b5d6a7c8", "part_urls": [ { "n": 1, "url": "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." } ] }Haz
PUTde cada parte a su URL (partes de 32 MiB por defecto, la última más pequeña):curl -X PUT "https://r2.hushscript.com/uploads/job_5e2a91cf.../part-1?X-Amz-Signature=..." \ --data-binary @part-01.binObtén más páginas desde
GET /v1/uploads/{job}/part-urls?start=<n>, y llama aPOST /v1/uploads/{job}/heartbeatbien dentro de los 20 minutos de tiempo de espera por inactividad durante una transferencia larga. Cuando las URLs prefirmadas no están disponibles, o una parte falla,PUT /v1/uploads/{job}/parts/{n}envía los bytes de esa parte a través de la API en su lugar; unPUTrepetido reemplaza la parte, así que los reintentos son seguros. Formatos compatibles: mp3, m4a, mp4 o mov (se usa la pista de audio y se omiten las pistas de video), wav, flac, ogg u opus, verificados en el servidor; extrae el audio de cualquier otro formato de video antes de subirlo. -
Inicia y espera.
POST /v1/uploads/{job}/completecon elny eletagde cada parte que enviaste a una URL prefirmada (omitepartscuando todas las partes se enviaron por la 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\"" } ] }'Luego consulta
GET /v1/jobs/{id}:statepasa poruploading,queuedyprocessinghastadoneofailed, y un job terminado trae untranscript_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" } -
Lee el resultado.
GET /v1/transcripts/{id}devuelve los metadatos y el cuerpo completo, con los nombres de los hablantes, el idioma detectado, las etiquetas y la fecha de eliminación automática:curl https://api.hushscript.com/v1/transcripts/trs_2b6e1d4a9f7c3088a1b2c3d4e5f6a7b9 \ -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"GET /v1/transcriptspagina la lista.
Las opciones de transcripción son las mismas que en la aplicación,
textualmente: language_code o detección automática, speaker_detection,
medical_mode (necesita language_code en en, es, fr o de; suma un
100 %), translation_targets (suma un 25 % por idioma), multichannel,
keyterms_prompt, un prompt de texto libre, y los dictionary_ids y
prompt_preset_id guardados que lista GET /v1/transcription-context.
Parte de la cuenta sigue siendo solo para MCP. Importar desde un enlace,
editar o eliminar transcripciones, Insights, exportaciones, guardar
diccionarios y preajustes de indicaciones, y la configuración de la
cuenta todavía no tienen ruta /v1/; el servidor MCP cubre todo eso
con el mismo token.
Autenticación
Cada llamada /v1/ lleva un token bearer en el encabezado Authorization,
verificado contra los mismos scopes que usa el servidor MCP:
| Scope | Qué permite |
|---|---|
transcripts:read |
Lee y exporta las transcripciones, sus metadatos y la lista de eliminadas |
transcripts:write |
Edita, etiqueta, traduce, restaura y elimina transcripciones |
transcribe |
Sube grabaciones, importa desde un enlace e inicia transcripciones |
insights |
Lee, genera y elimina Insights |
context |
Administra diccionarios guardados y preajustes de indicaciones |
account:read |
Lee el saldo, el uso, las transacciones y las retenciones |
settings:write |
Cambia la configuración de la cuenta |
org:read |
Lee los miembros, el historial de movimientos, las facturas y el registro de auditoría del espacio de trabajo |
org:write |
Cambia los permisos de los miembros, programa el paso a la custodia corporativa (permanente), e impone o levanta retenciones legales |
export |
Solicita una exportación completa de la cuenta, consulta su estado y la descarga |
billing |
Guarda una tarjeta y compra paquetes de minutos |
Una llamada fuera de los scopes del token falla con pat_scope_missing, con estado 403. El scope billing no tiene efecto a menos que la facturación esté activada tanto
en el token como en la cuenta. Una llamada de facturación con cualquiera de los dos
interruptores apagado falla con el mismo pat_scope_missing; volver a generar el
token no activa el interruptor de la cuenta. Un token no puede crear, listar ni
revocar tokens, y una cuenta tiene como máximo 25 activos.
Estos 11 scopes los elige quien llama. pat:rotate es un scope aparte que se concede
al primer token de una cuenta de agente y a sus sucesores rotados; permite que ese
token se reemplace a sí mismo, no que gestione otros tokens. No puedes seleccionarlo
al crear un token en la aplicación.
Endpoints
El documento OpenAPI de producción lista 38 operaciones método/ruta sobre 37 rutas. Cada operación de abajo está protegida por el scope indicado:
| Método | Ruta | Scope |
|---|---|---|
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 un registro sin interfaz y sin token todavía,
/v1/agent/accounts/{signup_id}/claim convierte un registro pagado en una
cuenta real y su primer token, y /v1/agent/credentials/rotate genera un
sucesor para el token que hace la llamada y lo retira cuando el sucesor se usa por primera vez,
sin tocar ninguna otra credencial de la cuenta. La guía de Uso automatizado cubre los
tres de principio a fin.
Todo listado toma un limit y un cursor opaco, y devuelve un
next_cursor que es null en la última página. Devuelve el cursor sin
cambios; codifica la posición, así que nunca se salta ni se repite una
página cuando llegan filas entre llamadas.
La definición completa y actual, con parámetros y esquemas de respuesta para cada operación, está en el documento OpenAPI: trátalo como la fuente de verdad por encima de esta tabla. Se sirve a cualquier token bearer sin importar el scope, así que un cliente puede obtenerlo con las credenciales que ya tiene.
Interfaz MCP
¿Prefieres herramientas antes que HTTP puro? El servidor MCP pone la misma cuenta detrás de 56 herramientas en lugar de estos endpoints, para un cliente que ya habla MCP en vez de REST. Solo anuncia las herramientas que permiten los scopes del token conectado.
Límites
Las solicitudes hechas con el token de una cuenta humana están limitadas a 1,200 por minuto por token. Los tokens rotados de una cuenta de agente comparten ese presupuesto en toda la cuenta. Las rutas de facturación que llaman a Stripe comparten un presupuesto más estricto de 60 por minuto por cuenta para quienes llaman con PAT: sesión de configuración, compra, cambios de tarjeta predeterminada, eliminación de tarjeta y fallos de caché de la lista de tarjetas. La limitación ordinaria devuelve 429 rate_limited con Retry-After en segundos; espera ese tiempo antes de reintentar. Las compras de una cuenta de agente o hechas con el PAT de una cuenta humana comparten un tope de 3 intentos por cada 24 horas móviles por cuenta. La compra de registro del agente cuenta; los rechazos o errores posteriores a la reserva también cuentan. Una compra desde una sesión de navegador humana está exenta. Un rechazo por el tope devuelve HTTP 429 con 4038 agent_purchase_capped y Retry-After. Las grabaciones pueden durar de 15 segundos a 10 horas. GET /v1/account informa los límites de admisión actuales de la cuenta (max_active_jobs, max_daily_seconds).
Entorno de pruebas
No existe un entorno de pruebas general para transcripción: las llamadas /v1/ ordinarias se ejecutan contra cuentas reales, y las compras gastan dinero real. La excepción es la validación de registro: POST /v1/agent/accounts acepta dry_run: true, devuelve un id de registro dry_ que no se puede reclamar, y no abre ninguna sesión de Stripe ni cuenta.
Errores
Un error es un cuerpo JSON con un code numérico estable y un slug error,
en el estado HTTP que se muestra abajo. Los cuerpos de error de /v1/ son
una proyección congelada: error, code y un conjunto fijo de claves de
detalle. La forma de error de /api no está congelada y puede traer más.
Los códigos que quien llama de forma automatizada debe manejar:
| Status | Code | Slug | Significado |
|---|---|---|---|
| 401 | 2000 | unauthorized |
Token bearer ausente o inválido |
| 403 | 2022 | pat_forbidden |
La ruta no acepta ningún token |
| 403 | 2023 | pat_scope_missing |
Al token le falta el scope que esta llamada necesita, o la facturación está desactivada para la cuenta |
| 403 | 4021 | pat_purchase_requires_app |
No se indicó ninguna tarjeta guardada, o el cargo fue rechazado; no se cobró nada |
| 403 | 4023 | pat_purchase_requires_authentication |
El emisor de la tarjeta pide una verificación que quien llama no puede completar; la tarjeta en sí está bien |
| 402 | 3001 | insufficient_balance |
Saldo insuficiente para admitir el job |
| 402 | 3002 | card_declined |
Se rechazó la tarjeta guardada |
| 402 | 3003 | org_insufficient_balance |
Al fondo compartido del espacio de trabajo que financia esta subida le falta saldo |
| 404 | 4000 | not_found |
No existe ese job, subida o recurso |
| 409 | 4001 | wrong_state |
El recurso no está en un estado que permita esto |
| 422 | 1021 | duration_out_of_range |
La duración declarada es menor a 15 segundos o mayor a 10 horas |
| 429 | 4038 | agent_purchase_capped |
La cuenta agotó su cupo de intentos de compra con token; espera el Retry-After |
| 429 | 5000 | rate_limited |
Demasiadas solicitudes; espera el Retry-After |
| 502 | 6001 | provider_error |
Falló un servicio externo |
| 500 | 9000 | internal_error |
Un error inesperado del servidor |
El documento OpenAPI indica el código exacto que puede devolver cada
operación, y el servidor MCP publica el catálogo completo como el recurso
hushscript://error-codes.