🎁 Nuevo Regístrate gratis, 10 llamadas de regalo. Hasta 1 $, sin tarjeta.

Voz a texto

POST /v1/audio/transcriptions

Transcribe audio a texto. Compatible con la API de OpenAI Audio Transcriptions — el mismo endpoint sirve los modelos OpenAI Whisper / GPT-4o-transcribe y los modelos de Google Gemini, y el gateway enruta al upstream correcto según el ID del modelo. Acepta o bien un multipart/form-data (compatible con el SDK de OpenAI) o un cuerpo application/json con audio codificado en base64.

Cuerpo de la solicitud

ParámetroTipoDescripción
model*stringID del modelo de transcripción (p. ej. whisper-1, gpt-4o-transcribe, chirp-3, seed-asr-bigmodel, fun-asr, qwen3-asr-flash). Consulta «Modelos compatibles» más abajo.
file*filesolo multipart — el archivo de audio a transcribir. Obligatorio salvo que se proporcione input_audio (JSON).
input_audio*objectSolo JSON — { "data": "<base64>", "format": "mp3" }, o { "url": "<fetchable URL>" } para modelos sin conexión (seed-asr-bigmodel). Úsalo en lugar de file para solicitudes application/json.
response_formatstringFormato de salida: json (predeterminado; devuelve {text, usage}), text (cadena de transcripción sin formato), verbose_json (segmentos con marcas de tiempo), diarized_json (segmentos etiquetados por hablante — diarización de hablantes). Los valores permitidos dependen del modelo; consulta «Formatos de respuesta» más abajo.
languagestringSugerencia ISO-639-1 opcional (p. ej. "en") para mejorar la precisión y la latencia.
promptstringTexto opcional para guiar el estilo de transcripción / la ortografía de nombres propios.
temperaturenumberTemperatura de muestreo 0–1. Por defecto: 0.
streambooleanSi es true, devuelve eventos SSE de transcripción parcial (compatible con gpt-4o-transcribe y Gemini). Por defecto: false.
providerobjectConfiguración de pass-through del provider. Consulta Pass-through del provider más abajo.

Modelos compatibles

¿No sabes qué modelo elegir? Elige según lo que necesites

NecesitasActívalo conModelos recomendados
Chino / cantonés, bajo costo seed-asr-bigmodel fun-asr
Inglés, alta calidad gpt-4o-transcribe chirp-3
Diarización de hablantes: quién dijo qué response_format=diarized_json seed-asr-bigmodel chirp-3 gpt-4o-transcribe-diarize
Marcas de tiempo por palabra response_format=verbose_json whisper-1
Subtítulos en tiempo real (mientras hablas) stream=true gpt-4o-transcribe
Grabaciones largas / reuniones pass a public URL in input_audio.url seed-asr-bigmodel fun-asr
ModeloProveedor · facturaciónEntradaDiarizaciónStreamingIdeal para
whisper-1 OpenAI · $0.006/min file Marcas de tiempo por palabra (verbose_json); el idioma debe ser ISO-639-1
gpt-4o-transcribe OpenAI · token file Inglés, alta precisión; admite streaming
gpt-4o-mini-transcribe OpenAI · token file Multilingüe más económico; admite streaming
gpt-4o-transcribe-diarize OpenAI · token file Diarización en inglés; known_speaker_names opcional
chirp-3 Google · $0.016/min file Alta calidad; una sola llamada ≤60 s
chirp-2 Google · $0.016/min file USM multilingüe; usa chirp-3 para la diarización
seed-asr-bigmodel BytePlus · $0.002/min URL / file Chino, grabaciones largas; el más económico
fun-asr Alibaba · $0.0021/min URL / file Chino · cantonés · dialectos; grabaciones largas
fun-asr-mtl Alibaba · $0.0021/min URL / file Multilingüe + diarización
fun-asr-flash Alibaba · $0.0021/min file Multilingüe rápido; ≤10 MB, sincrónico
qwen3-asr-flash Alibaba · $0.0021/min file Multilingüe; ≤5 min/llamada, facturación exacta

Diarization = define response_format=diarized_json para obtener segments[].speaker. Límite de subida predeterminado 25 MB (ver Formatos de audio).

Los modelos de Google pueden servirse a través de la API de Gemini o, con una clave de cuenta de servicio BYOK de Vertex, a través de Google Cloud Vertex AI. La disponibilidad depende de los canales habilitados para tu espacio de trabajo — llama a /v1/models para ver qué puedes usar.

Errores comunes. (1) El streaming (stream=true) funciona solo en gpt-4o-transcribe / gpt-4o-mini-transcribe — cualquier otro modelo devuelve 400. (2) input_audio.url (entrada por URL) solo es compatible con seed-asr-bigmodel; todos los demás modelos requieren una carga de file o base64. (3) El parámetro language en los modelos de OpenAI (whisper-1, gpt-4o-*) debe ser un código ISO-639-1 como en o zh — los códigos de configuración regional como yue-CN se rechazan; Chirp / Seed ASR / Qwen aceptan códigos de configuración regional, o bien omite language para detectar automáticamente. (4) Si el audio supera el límite por solicitud de un modelo, divídelo en fragmentos — o usa seed-asr-bigmodel (mediante URL) para grabaciones largas (~20 min/solicitud). (5) El audio en silencio / sin habla devuelve 200 con una cadena vacía {"text":""}, no un error.

Formatos de audio compatibles

  • mp3
  • wav
  • ogg
  • flac
  • m4a

Para cargas multipart, el formato se infiere de la extensión del nombre de archivo. Para solicitudes base64 (JSON), establece input_audio.format explícitamente. Tamaño máximo de carga: 25 MB.

Formatos de respuesta

El valor response_format los valores aceptados dependen del modelo. json es el valor predeterminado para todos los modelos (devuelve { text, usage }); text devuelve la cadena de transcripción en bruto.

  • whisper-1json, text, verbose_json
  • gpt-4o-transcribe, gpt-4o-mini-transcribejson, text
  • chirp-3, chirp-2, seed-asr-bigmodel, qwen3-asr-flash, fun-asr-flashjson, text
  • gpt-4o-transcribe-diarize, chirp-3, seed-asr-bigmodel, fun-asr, fun-asr-mtl — also diarized_json (segmentos etiquetados por hablante; ver más abajo)

verbose_json (marcas de tiempo de segmentos) es solo para whisper-1;

Diarización de hablantes

Define response_format=diarized_json para obtener segmentos etiquetados por hablante: la respuesta añade un arreglo segments donde cada entrada lleva una etiqueta speaker más marcas de tiempo start/end (en segundos). Compatible con gpt-4o-transcribe-diarize (OpenAI), chirp-3 (Google), seed-asr-bigmodel (BytePlus: la mejor relación calidad-precio para chino y grabaciones largas) y fun-asr / fun-asr-mtl (Alibaba: archivo de grabación sin conexión, acepta una URL o un archivo). Otros modelos ignoran diarized_json y devuelven texto plano; chirp-2 lo rechaza (usa chirp-3).

Las etiquetas de hablante son nativas del proveedor (p. ej., "0"/"1" para chirp-3 y seed-asr, "A"/"B" para gpt-4o-transcribe-diarize); identifican hablantes distintos, pero no son identidades reales estables. En gpt-4o-transcribe-diarize puedes pasar known_speaker_names para orientar el etiquetado.

# Chinese meeting, cheapest diarization (BytePlus seed-asr):
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seed-asr-bigmodel",
    "input_audio": { "url": "https://your-bucket/signed/meeting.wav", "language": "zh" },
    "response_format": "diarized_json"
  }'

# English / highest quality (Google chirp-3, <=60 s per request):
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model=chirp-3 \
  -F file=@call.wav \
  -F response_format=diarized_json

Ejemplo de respuesta

{
  "task": "transcribe",
  "text": "喂 你好 我这边是客服 有什么可以帮您",
  "duration": 6.2,
  "segments": [
    { "id": 0, "start": 0.10, "end": 0.90, "speaker": "0", "text": "喂 你好" },
    { "id": 1, "start": 1.20, "end": 6.20, "speaker": "1", "text": "我这边是客服 有什么可以帮您" }
  ]
}

Solicitud de ejemplo (multipart)

curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model=gpt-4o-transcribe \
  -F file=@meeting.mp3 \
  -F response_format=json \
  -F language=en

Solicitud de ejemplo (JSON base64)

POST /v1/audio/transcriptions
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "model": "gpt-4o-transcribe",
  "input_audio": {
    "data": "UklGRiQAAABXQVZFZm10I...",
    "format": "wav"
  },
  "response_format": "json",
  "language": "en"
}

Ejemplo — ASR sin conexión (seed-asr-bigmodel)

seed-asr-bigmodel (ASR sin conexión internacional de BytePlus) acepta dos entradas mutuamente excluyentes: una input_audio.url accesible (recomendada — tu propia URL firmada de almacenamiento de objetos con tiempo limitado; el audio nunca toca nuestro almacenamiento), o una carga directa de file/bytes (la preparamos en un bucket privado y la eliminamos justo después de la transcripción). Limitaciones: sin streaming (stream=true devuelve 400); las cargas de file admiten hasta 25 MB (usa una URL para grabaciones más grandes); el procesamiento por solicitud está limitado a unos 20 minutos, así que divide los audios muy largos. Facturado por duración del audio ($0.002/min).

# ① Quick test — replace ONLY YOUR_API_KEY and run it (uses our hosted sample audio).
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seed-asr-bigmodel",
    "input_audio": {
      "url": "https://synthorai-asr-sample-360831509259.s3.us-west-1.amazonaws.com/seed-asr-sample.wav",
      "language": "zh"
    }
  }'
# → {"text":"..."}

# ② Your own audio file (<=25 MB) — replace key + file path.
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model=seed-asr-bigmodel \
  -F language=zh \
  -F file=@/path/to/your-audio.wav

# ③ Your own signed URL (recommended for large files / privacy) — replace key + URL.
curl https://synthorai.io/v1/audio/transcriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"seed-asr-bigmodel","input_audio":{"url":"https://your-bucket/signed/meeting.wav","language":"zh"}}'

Notas / detalles: (1) language es opcional — los valores comunes son zh (mandarín), yue-CN (cantonés), en-US; omítelo para detectarlo automáticamente. (2) Al usar input_audio.url, la URL debe ser accesible públicamente por el servicio de transcripción — una URL privada/interna/protegida por autenticación fallará; una URL firmada (pre-firmada) de almacenamiento de objetos con tiempo limitado es la forma recomendada. (3) La carga de file y la URL son mutuamente excluyentes; elige una. (4) El audio sin habla reconocible (silencio) devuelve 200 con una cadena vacía {"text":""}, no un error.

Ejemplo — SDK de OpenAI para Python

El endpoint es compatible con OpenAI, por lo que el SDK oficial de OpenAI funciona directamente al sobrescribir base_url. Funciona igual para whisper-1, gpt-4o-transcribe y cualquier modelo de transcripción Gemini — solo cambia model.

from openai import OpenAI

client = OpenAI(
    base_url="https://synthorai.io/v1",
    api_key="YOUR_API_KEY",
)

with open("meeting.mp3", "rb") as f:
    result = client.audio.transcriptions.create(
        model="gpt-4o-transcribe",
        file=f,
        language="en",
        # prompt="Synthorai, BYOK, transcribe",   # optional vocabulary hint
        response_format="json",
    )

print(result.text)
# Token-level usage on gpt-4o-*:
if getattr(result, "usage", None):
    print(result.usage)

Ejemplo — SDK de OpenAI para Node.js

import OpenAI from "openai";
import fs from "node:fs";

const client = new OpenAI({
  baseURL: "https://synthorai.io/v1",
  apiKey: process.env.SYNTHORAI_API_KEY,
});

const result = await client.audio.transcriptions.create({
  model: "gpt-4o-transcribe",
  file: fs.createReadStream("meeting.mp3"),
  language: "en",
  response_format: "json",
});

console.log(result.text);

Streaming (SSE)

Establece stream=true en gpt-4o-transcribe, gpt-4o-mini-transcribe, o cualquier modelo de transcripción Gemini para recibir eventos incrementales a medida que se decodifica el audio. El Content-Type de la respuesta es text/event-stream y los eventos terminan con data: [DONE]. whisper-1 no admite streaming (devuelve 400 si stream=true).

Tipos de eventos que verás para gpt-4o-transcribe:

data: {"type":"transcript.text.delta","delta":"Hello "}

data: {"type":"transcript.text.delta","delta":"world."}

data: {"type":"transcript.text.done","text":"Hello world."}

data: {"type":"usage","usage":{"type":"tokens","input_tokens":689,"output_tokens":287,"total_tokens":976,"input_token_details":{"audio_tokens":689,"text_tokens":0,"cached_tokens":0}}}

data: [DONE]

El streaming de Gemini usa los mismos nombres de eventos SSE, y el gateway emite el mismo objeto canónico usage documentado en Ejemplo de respuesta— idéntico entre OpenAI y Gemini — de modo que el código del cliente sea portable entre providers. El evento final usage siempre lleva el input_token_details desglose completo para una facturación precisa a tarifa de audio.

Errores

Todos los errores siguen el envelope de OpenAI: { error: { message, type, code, param? } }. Casos comunes:

  • 400 model_not_found — el modelo no tiene capacidad de transcripción en los channels de este espacio de trabajo.
  • 400 byok_strict_no_key — el espacio de trabajo es BYOK estricto (byok_fallback_to_pool=false) y no tiene clave de vault para el proveedor resuelto.
  • 400 content_policy_violation — el campo prompt activó una regla de guardrail (p. ej. fuga de clave BYOK).
  • 402 quota_exceeded — el costo estimado supera el cupo restante del espacio de trabajo. BYOK está exento.
  • 408 — el cuerpo de la solicitud no terminó de subirse dentro del tiempo de lectura del servidor. Común con audio grande en una conexión lenta; reintenta o envía un archivo más pequeño.
  • 413 — el audio supera el límite de 25 MB.
  • 502 upstream_error — fallo de red upstream o respuesta no-2xx del proveedor del modelo.

Ejemplo de respuesta

{
  "text": "Thanks for joining today's call. Let's get started.",
  "usage": {
    "type": "tokens",
    "input_tokens": 689,
    "output_tokens": 287,
    "total_tokens": 976,
    "input_token_details": {
      "audio_tokens": 689,
      "text_tokens": 0,
      "cached_tokens": 0
    }
  }
}

Objeto usage uniforme. Cada modelo facturado por token (gpt-4o-*, Gemini, Vertex) devuelve exactamente esta estructura — todos los campos siempre presentes, rellenados con cero cuando un proveedor no informa un subconteo — de modo que el mismo código cliente lee el uso en todos los proveedores. Como la entrada de transcripción es totalmente audio, Gemini/Vertex informan input_token_details.audio_tokens == input_tokens (sin separación de texto); OpenAI informa su separación nativa de audio/texto. cached_tokens es la porción de la entrada servida desde una caché del lado del proveedor.

whisper-1 es la única excepción: se factura por duración de audio, no por tokens, por lo que su respuesta no incluye ningún objeto usage de tokens. Con response_format=text el cuerpo de la respuesta es la cadena de transcripción en bruto en lugar de un objeto JSON.