Saltar al contenido principal

Funciones de IA

API de desarrolladores de Hushscript

Una superficie REST hecha para agentes de IA y automatización, sobre la misma cuenta, el mismo saldo y los mismos tokens que todo lo demás.

Hushscript también responde a llamadas REST simples, para agentes y scripts que prefieren llamar a un endpoint HTTP antes que ejecutar un cliente MCP. Es la misma cuenta, el mismo saldo y los mismos tokens bearer en todo momento: nada aquí cambia cómo se cobra o se almacena la transcripción.

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:

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
  }
}

Eso responde el saldo en segundos, los segundos retenidos por jobs en curso, la fecha de vencimiento de los créditos, 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ó). Una cuenta nueva empieza con saldo cero. POST /v1/uploads verifica el saldo, no la tarjeta: sin minutos, responde 3001 insufficient_balance. La tarjeta es cómo llega el saldo, ya que la verificación única de tarjeta en la aplicación libera los 30 minutos gratis, y los paquetes se compran con una tarjeta guardada.

Automatizar de principio a fin

Todo lo que ocurre después de que la cuenta existe funciona sin ninguna persona, sin importar si una persona abrió esa cuenta en la aplicación o un agente la abrió mediante /v1/agent/accounts (consulta Uso automatizado). Queda un único paso de navegador, y un agente puede manejarlo él mismo.

  1. Lee la cuenta. GET /v1/account. Si card_on_file es false, guarda una tarjeta primero.

  2. Guarda una tarjeta, una sola vez. POST /v1/billing/setup-session devuelve un checkout_url, un session_id y un expires_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/cards la lista con su id. POST /v1/billing/cards/default cambia la predeterminada si la cuenta tiene varias.

  3. Compra minutos. GET /v1/billing/packs lista los cinco paquetes con id, seconds, amount y currency:

    curl https://api.hushscript.com/v1/billing/packs \
      -H "Authorization: Bearer hsr1:eu:pat.7f3a9c.2b6e1d4a9f2c88b1a3d4e5f60718293"

    POST /v1/billing/purchase con pack, quick_payment_method_id (el id de la tarjeta guardada) y un idempotency_key cobra la tarjeta fuera de sesión y responde el nuevo balance_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 en el token y la facturación activada para la cuenta. Un cuerpo sin id de tarjeta, o una tarjeta rechazada, se rechaza con 4021 pat_purchase_requires_app; una tarjeta que el emisor quiere verificar se rechaza con 4023 pat_purchase_requires_authentication. Ninguno de los dos abre una página que nadie pueda completar.

  4. Sube el archivo. POST /v1/uploads con size_bytes, duration_seconds (de 15 segundos a 10 horas), un title opcional, transcription_options y un idempotency_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"
      }'

    Coloca una retención de crédito y responde un job_id má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 PUT de 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.bin

    Obtén más páginas desde GET /v1/uploads/{job}/part-urls?start=<n>, y llama a POST /v1/uploads/{job}/heartbeat bien 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; un PUT repetido reemplaza la parte, así que los reintentos son seguros. Solo audio: mp3, m4a, wav, flac, ogg u opus, como máximo 5 GB, verificado en el servidor; extrae la pista de audio de un video antes de subirlo.

  5. Inicia y espera. POST /v1/uploads/{job}/complete con el n y el etag de cada parte que enviaste a una URL prefirmada (omite parts cuando 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}: state pasa por uploading, queued y processing hasta done o failed, y un job terminado trae un transcript_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"
    }
  6. 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/transcripts pagina 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 ajustes preestablecidos de mensajes, 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 ajustes preestablecidos de mensajes
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
export Solicita una exportación completa de la cuenta, consulta su estado y descárgala
billing Guarda una tarjeta y compra paquetes de minutos

Una llamada fuera de los scopes del token falla con pat_scope_missing, en 403. El scope billing también está inerte hasta que el propietario de la cuenta activa la facturación para la cuenta en la aplicación; una llamada de facturación en una cuenta donde ese interruptor está apagado falla con el mismo pat_scope_missing, y volver a generar el token no lo soluciona. Un token no puede crear, listar ni revocar tokens, y una cuenta tiene como máximo 25 activos.

Endpoints

Disponibles hoy, cada uno protegido por el scope indicado:

Method Path Scope
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 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 revoca, 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 responde 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 51 herramientas en lugar de estos endpoints, para un cliente que ya habla MCP en vez de REST.

Límites

Las solicitudes hechas con un token están limitadas a 1.200 por minuto por token. POST /v1/billing/setup-session y POST /v1/billing/purchase comparten un presupuesto más estricto de 60 por minuto por cuenta, antes de la llamada a Stripe que harían. Una solicitud rechazada responde 429 rate_limited con un encabezado Retry-After que indica la espera en segundos; espera ese tiempo antes de reintentar. Las subidas están limitadas a 5 GB y 10 horas, con un mínimo de 15 segundos, y los límites de admisión propios de la cuenta (max_active_jobs, max_daily_seconds) se reportan en GET /v1/account.

Entorno de pruebas

No existe un modo de simulación: toda llamada /v1/ se ejecuta contra una cuenta real, y comprar minutos gasta dinero real.

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 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.

Empieza a transcribir – 30 minutos para probar

Un bloqueo de $1 confirma tu tarjeta y se libera de inmediato — nunca se te cobra, y tus 30 minutos gratis llegan al instante.

Comenzar – 30 minutos gratis