API de Whisper-1: tu primera transcripción de audio
Envía una grabación a Whisper-1, guarda su ID de tarea y descarga texto o subtítulos. Ejemplo Python con validación, marcas de tiempo y precios actuales.
Leer en MarkdownUna primera solicitud a la API de Whisper-1 necesita un archivo de audio, un ID de modelo explícito y un formato de salida. En SeedRouter, subes la grabación, guardas el ID de tarea devuelto y descargas la transcripción cuando termina esa tarea. Empieza con una grabación corta cuyas palabras ya conozcas: así detectarás más fácilmente palabras omitidas y grafías inusuales.
Esta guía sigue el contrato asíncrono de SeedRouter. No es un ejemplo síncrono del SDK de OpenAI que puedas usar sin cambios. La página del modelo Whisper-1 tiene el Playground y el precio actual; la referencia de la API enumera cada campo y las verificaciones de compatibilidad pendientes. [1]
Prepara una grabación
Usa voz que tengas permiso para procesar. Un WAV o MP3 corto es un buen punto de partida. El límite de carga actual es de 26.214.400 bytes; el archivo debe contener audio legible con una duración medible. La extensión .mp3 no convierte un archivo de texto renombrado en audio válido. La referencia distingue los nueve formatos de entrada documentados de los que superaron pruebas reales. [1]
La grabación siguiente contiene voz sintética original en inglés, creada para este tutorial. Su forma de onda aparece en la portada. La frase citada en la portada procede del guion de la grabación, no de una afirmación de precisión.
Descarga la muestra de 10,31 segundos. El guion dice: “This is a sample recording for an audio transcription tutorial. Our meeting starts at nine thirty on Monday. Please bring the project notes and review the final checklist before we begin.”
Guarda una clave de API en una variable de entorno del servidor. No la pongas en una página web pública, un paquete de aplicación móvil o una captura compartida. El ejemplo Python siguiente usa requests y lee SEEDROUTER_API_KEY del entorno.
Envía la solicitud a la API de Whisper-1 una sola vez
Elige json para la primera solicitud. Así podrás leer el campo text del archivo descargado sin manejar códigos de tiempo de subtítulos. La parte multipart file debe contener bytes reales; proporcionar una URL como valor no equivale a subir el archivo. Deja que el cliente establezca el tipo de contenido multipart y el delimitador. [1]
Guarda esto como transcribe.py. Escribe un marcador de envío antes del POST y guarda el ID de tarea aceptado después. Al ejecutarlo otra vez, lee esa tarea existente. Si el resultado del POST es incierto, el marcador impide que el script cree un duplicado accidental.
import json
import os
from pathlib import Path
import requests
base = "https://api.seedrouter.ai/v1"
headers = {"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"}
state = Path("whisper-task.json")
audio = Path("recording.wav")
if not state.exists():
if not 0 < audio.stat().st_size <= 26_214_400:
raise ValueError("Choose a nonempty recording within the upload limit")
with state.open("x") as marker:
json.dump({"status": "submission_unconfirmed"}, marker)
with audio.open("rb") as recording:
response = requests.post(
f"{base}/audio/transcriptions",
headers=headers,
files={"file": (audio.name, recording, "audio/wav")},
data={"model": "whisper-1", "response_format": "json"},
timeout=180,
allow_redirects=False,
)
response.raise_for_status()
accepted = response.json()
task_id = accepted.get("id")
if not isinstance(task_id, str) or not task_id.startswith("task_"):
raise RuntimeError("Submission could not be confirmed; check task history")
state.write_text(json.dumps({"id": task_id}), encoding="utf-8")
saved = json.loads(state.read_text(encoding="utf-8"))
if "id" not in saved:
raise RuntimeError("Check task history before submitting another recording")
response = requests.get(
f"{base}/tasks/{saved['id']}", headers=headers, timeout=30,
allow_redirects=False,
)
response.raise_for_status()
task = response.json()
print(task["status"])
if task["status"] == "completed":
result = requests.get(task["output"]["url"], timeout=60)
result.raise_for_status()
print(result.json()["text"])
elif task["status"] == "failed":
print(task["error"])Ejecuta python transcribe.py. Si muestra processing, espera unos segundos y ejecuta el mismo comando otra vez. Leerá el ID guardado en lugar de volver a subir el archivo. Guarda un archivo de estado distinto para cada grabación nueva que quieras enviar. Un tiempo de espera agotado en el cliente no demuestra por sí solo que la tarea haya fallado.
Lee la transcripción completada
La respuesta de aceptación contiene id, model, status y created_at. Al completarse se añaden output.url y output.format. Esa URL apunta al archivo de resultado; no es una tarea de generación de medios que requiera otra solicitud pagada. Un GET descarga el archivo. [1]
Lee las palabras mientras escuchas la grabación. Comprueba nombres, números y límites entre frases antes de usar el texto como subtítulos o como cita exacta. Una transcripción es un borrador de lo que se dijo, y las marcas de tiempo no eliminan la necesidad de revisarla.
Las pruebas locales de extremo a extremo del 19 de octubre de 2026 completaron los cinco formatos de transcripción y una traducción con entrada en inglés. Esas pruebas establecen el comportamiento de entrega y facturación para las grabaciones probadas. No establecen un porcentaje de precisión ni calidad de traducción entre idiomas.
Elige texto, marcas de tiempo o subtítulos
| Tu siguiente paso | Elige | Lee el archivo descargado como |
|---|---|---|
| Incorporar las palabras a una aplicación | json | JSON; empieza por text |
| Editar una transcripción plana | text | Texto plano |
| Importar subtítulos en un editor | srt o vtt | Texto de subtítulos |
| Alinear palabras o segmentos individuales | verbose_json | JSON con las marcas de tiempo solicitadas |
Para marcas de tiempo por palabra, envía response_format=verbose_json y un campo multipart repetido llamado timestamp_granularities[] con valor word. Añade otra parte con valor segment si necesitas ambos. En Python requests, usa una lista de pares (name, value) para campos repetidos. Cada marca de tiempo está en segundos. [2]
Las marcas de tiempo por palabra y las etiquetas de hablante son salidas distintas. Whisper-1 no convierte una reunión en una transcripción con hablantes identificados solo porque solicites segmentos. Tampoco transmite texto parcial: stream se ignora en este modelo. Omite chunking_strategy para el flujo verificado; seleccionar auto explícitamente no superó la prueba real de compatibilidad. [1]
Añade contexto de idioma y ortografía cuando sea necesario
Un language=en opcional indica a la solicitud de transcripción que la entrada está en inglés. Omítelo si quieres detección. Si un nombre de producto puede confundirse al escucharlo, pon su grafía correcta en prompt, usando el mismo idioma que el audio. Los prompts de Whisper aportan contexto; no funcionan como instrucciones de chat que puedan imponer de forma fiable un diseño concreto. [3]
Mantén el contexto relevante para el clip. Whisper solo considera los últimos 224 tokens de su propio tokenizador. Enviar un documento largo no da a la grabación un glosario ilimitado, y contar caracteres no sustituye de forma fiable esa regla de tokens.
Para traducir al inglés, cambia el endpoint a /audio/translations. Sus cinco campos de solicitud son file, model, prompt, response_format y temperature. La traducción produce inglés; no tiene selector de idioma de destino. Usa un prompt en inglés si proporcionas uno. [4]
Revisa el costo antes de ampliar el flujo
La tabla de precios actuales siguiente usa la duración medida del audio. Una transcripción más larga no aumenta el cargo por duración para la misma grabación. La duración de cada archivo se redondea hacia arriba a segundos enteros y después se convierte en unidades de medición de audio. La referencia de la API incluye el cálculo exacto y el Playground muestra una estimación cuando puede leer la duración. Las solicitudes fallidas no se cobran.
| Model | USD per minute | USD per million audio metering units |
|---|---|---|
| whisper-1 | $0.036 | $36 |
For each recording: units = round(ceil(duration in seconds) × 1000 / 60). Multiply these audio units by the live unit rate. These are duration units, not transcript tokens. Both transcription and English translation use this rule. Failed requests are not charged.
Antes de procesar muchos archivos, valida una grabación representativa e inspecciona el resultado. Conserva el ID de tarea de cada grabación para recuperarte de una interrupción consultando su estado existente. Consulta la referencia completa de parámetros antes de añadir subtítulos o combinaciones de formatos menos probadas.
Preguntas de una primera integración
¿Puedo usar el ejemplo del SDK Python de OpenAI sin cambios?
No. Los campos de entrada multipart son conocidos, pero SeedRouter devuelve un ID de tarea asíncrono. Un cliente síncrono que espera que la respuesta POST contenga text necesita adaptación. El ejemplo hace explícitos el envío y la lectura del resultado.
¿Por qué no hay marcas de tiempo por palabra en mi resultado JSON?
El formato predeterminado json es una respuesta orientada a texto. Solicita verbose_json junto con la granularidad de tiempo word. Los tiempos por segmento no crean por sí solos una entrada por palabra.
¿Debo enviar otro POST después de agotar el tiempo de espera?
Primero revisa el ID de tarea guardado o el historial de tareas. La respuesta puede haberse perdido después de la aceptación. Leer una tarea existente evita crear otra solicitud para la misma grabación.
¿Se va a retirar Whisper-1?
OpenAI ha anunciado el 26 de febrero de 2027 como fecha de retirada de Whisper en su propia API. Ese aviso no establece una fecha de retirada para este servicio. Incluye los avisos del ciclo de vida en tu lista de mantenimiento al crear una nueva integración. [5]
Fuentes
[1] Referencia de la API Whisper-1 de SeedRouter y estado de verificación, consultados el 19 de octubre de 2026.
[2] Referencia de transcripción de OpenAI.
[3] Guía de prompts de Whisper de OpenAI.



