Introducción
La transcripción de voz en tiempo real establece una conexión persistente mediante WebSocket (un protocolo que mantiene una conexión de larga duración entre el cliente y el servidor y permite enviar datos de forma bidireccional). Recibe, transcribe y devuelve el flujo de audio de entrada de forma continua, lo que resulta adecuado para escenarios de voz sensibles a la latencia. Su diferencia con la transcripción de archivos STT:
Modelos disponibles:
- gpt-live-transcribe: modelo de transcripción por streaming, admite varios idiomas y produce el texto transcrito en tiempo real a medida que entra el audio.
Inicio rápido
Endpoint de conexión
intent=transcription: obligatorio, declara que se trata de una sesión de transcripción.model=gpt-live-transcribe: obligatorio, el modelo queda fijado por el parámetro de la URL en el momento de la conexión y no se puede cambiar durante la sesión (ver las restricciones más abajo).
Autenticación
Durante el handshake, la clave se pasa mediante la cabecera HTTP estándar:Requisitos del formato de audio
Actualmente solo se admite un formato de entrada. Antes de enviar, convierte el audio a:- Codificación: PCM16 (entero con signo de 16 bits, little-endian)
- Frecuencia de muestreo: 24000 Hz
- Canales: mono (mono)
audio/pcm@24000. Enviar un formato distinto (como G.711/µ-law) provoca el rechazo y el cierre de la sesión.
Las sesiones de transcripción no admiten la detección de actividad de voz (turn_detection / VAD), por lo que debe establecerse explícitamente en
null. Si se omite o se pasa un valor distinto de null, el proveedor de modelos lo rechaza con invalid_value. El gateway fuerza a null el campo turn_detection en la configuración que reenvía, pero se recomienda que lo establezcas en null de forma activa en el cliente para mantener un comportamiento claro.Configuración de la sesión (session.update)
Una vez establecida la conexión, el cliente envía primero un framesession.update para configurar los parámetros de transcripción. Si no lo envías, el gateway inyecta una configuración por defecto de respaldo con el modelo autorizado, pero se recomienda configurarla explícitamente.
Parámetros de configuración
string
requerido
Tipo de sesión; en el escenario de transcripción es fijo
transcription.object
requerido
Formato del audio de entrada, fijo en
{ "type": "audio/pcm", "rate": 24000 }.string
requerido
Modelo de transcripción. Debe coincidir con el parámetro
model de la URL de conexión (gpt-live-transcribe). Pasar otro modelo se considera un uso no autorizado y la sesión se cierra con 1008.string[]
Lista de idiomas esperados, en forma de array (por ejemplo,
["en", "zh"]). gpt-live-transcribe usa la forma plural languages, que permite declarar varios idiomas de una vez; especificar el idioma mejora la precisión y reduce la latencia. El diccionario de valores admitidos está más abajo en Códigos de idioma.string
Forma singular, un único código ISO-639-1 (por ejemplo,
"en"). Es una u otra con languages, no las pases a la vez (pasar ambas se rechaza con invalid_value). Para gpt-live-transcribe se recomienda oficialmente usar la forma plural languages; el gateway también acepta la forma singular language para facilitar la migración desde código antiguo.string
Prompt de texto libre que describe el escenario de la grabación (por ejemplo, «llamada de atención al cliente» o «consulta médica con terminología médica»), para ayudar al modelo a ajustarse al registro. En las pruebas, el servidor lo devuelve tal cual en
session.updated, ya está en efecto.string[]
Array de palabras clave literales, para nombres de producto, siglas, nombres propios y otras palabras propensas a error (por ejemplo,
["AiHubMix", "gpt-live-transcribe"]). Es una sugerencia, no una salida forzada; cada palabra debe ir como un elemento independiente y conviene evitar que incluya <, > o saltos de línea. En las pruebas se devuelve y está en efecto.string
Nivel de latencia / precisión; valores posibles:
minimal, low, medium, high, xhigh. Cuanto más alto el nivel, mayor precisión pero también mayor latencia. Nota: el gateway acepta este campo (no da error), pero en las pruebas no se devuelve en session.updated; su efectividad se rige por la documentación oficial y de momento no está confirmada por el eco de respuesta.null
requerido
Detección de actividad de voz. En las sesiones de transcripción debe ser
null.object
Configuración opcional de reducción de ruido, como
{ "type": "near_field" } (campo cercano, adecuado cuando el micrófono está cerca de quien habla) o { "type": "far_field" } (campo lejano).Códigos de idioma (language codes)
Los valores delanguages / language siguen los formatos siguientes, distinguen mayúsculas y minúsculas y deben tener una de las formas admitidas más abajo; pasar un código no admitido o con formato erróneo lo rechaza la API de realtime:
Envío de audio
Divide el audio PCM16 en fragmentos pequeños (por ejemplo, uno cada 100ms), codifícalos en base64 y envíalos de forma continua mediante el eventoinput_audio_buffer.append:
input_audio_buffer.commit para marcar el fin de ese segmento, lo que desencadena el cierre de la transcripción y devuelve el resultado completed:
Recepción de los resultados de transcripción
El servidor envía eventos de forma continua. Tipos de evento clave:event
Confirmación de la creación de la sesión y de la actualización de la configuración.
event
Resultado incremental de la transcripción; el campo
delta es el fragmento de texto añadido en esta ocasión. Se devuelve mientras se habla, adecuado para mostrarlo en pantalla en tiempo real.event
Transcripción de un segmento de voz completada; el campo
transcript es el texto completo de ese segmento.event
Evento de error, incluye el código de error y su descripción.
Ejemplo completo
A continuación se presentan dos enfoques; elige el que prefieras:- SDK oficial de OpenAI (recomendado): no requiere escribir el WebSocket a mano; basta con apuntar
websocket_base_url(el parámetro de la URL base del WebSocket del SDK) al gateway para reutilizar la biblioteca oficial. - websockets nativos: sin instalar el SDK, envía y recibe frames directamente según el protocolo, con dependencias mínimas y fácil de depurar.
¿Por qué la demo oficial no pasa el nombre del modelo y nosotros sí? El intent de transcripción de OpenAI coloca el modelo en
transcription.model dentro de session.update, y la URL de conexión solo lleva ?intent=transcription. El gateway de AiHubMix es distinto: el nombre del modelo debe aparecer en la URL del handshake (?model=gpt-live-transcribe), porque el gateway lo necesita en el instante mismo del handshake del WebSocket para elegir el proveedor de modelos, autenticar y reservar cuota, mientras que session.update llega después de completado el handshake, demasiado tarde. Por eso, al usar el SDK debes pasar model explícitamente a connect() (el SDK lo incorpora al query de la URL); si falta, el gateway responde 400 missing_model_parameter durante el handshake: connect() lanza una excepción directamente, la conexión no llega a establecerse y nunca se alcanza el paso de session.update. Dentro de la sesión, transcription.model debe seguir coincidiendo con la URL.Resultado de ejecución (prueba real en producción)
A continuación se muestra el resultado real de ejecutar el ejemplo anterior en el entorno de producción deaihubmix.com (modelo gpt-live-transcribe). Se configuró languages: ["en", "zh"] + prompt + keywords + delay: "low" + noise_reduction: { "type": "near_field" }:
En las pruebas, el servidor devuelve tal cual
languages, prompt, keywords y noise_reduction en session.updated, lo que indica que la configuración está realmente en efecto (no que simplemente se acepte sin procesar). El campo delay lo acepta el gateway pero no se devuelve; su efectividad se rige por la documentación oficial. De language (singular) y languages (plural) solo se puede pasar una de las dos.Notas de facturación
- Precio unitario:
gpt-live-transcribese factura a $0.017 / minuto (rige el precio de lista en tiempo real de la página de detalle del modelo). - Se factura por la duración del audio transcrito: rige el número de segundos de audio realmente reenviados al modelo de transcripción, redondeado hacia arriba al segundo entero. Por ejemplo, transcribir 90 segundos de audio se factura como
90 ÷ 60 × $0.017 = $0.0255. - La facturación no se ve afectada por el ida y vuelta de red ni por la espera en inactividad; solo se cronometra el audio que realmente entra en la transcripción.
- Liquidación sobre la marcha: es una conexión de larga duración, por lo que el coste no se liquida de una sola vez al terminar la sesión, sino que se descuenta en tiempo real por segmentos durante la sesión. Al establecer la sesión se hace primero una reserva de cuota por un consumo de aproximadamente 1 minuto (solo como validación de acceso, no es un cargo real); durante la sesión, la reserva se renueva de forma continua cada 20 segundos, y el coste real se descuenta por segmentos según los segundos realmente reenviados; al terminar la sesión se libera la reserva restante. Por lo tanto, el saldo disponible de la cuenta debe cubrir al menos un consumo de aproximadamente 1 minuto para que la sesión pueda establecerse.
- En el detalle de consumo de Uso y facturación, la nota de cada registro de transcripción en tiempo real indica el «precio por minuto» y los «segundos realmente cobrados en esta ocasión», para facilitar la conciliación registro a registro.

Un registro de facturación de transcripción en tiempo real de gpt-live-transcribe en la vista Activity de Uso y facturación; la nota indica 7 s de audio cobrados a $0.017 / min = $0.001982, conforme al formato descrito arriba.
Límites y restricciones
- Duración de una sesión: una conexión WebSocket dura como máximo 62 minutos; al cumplirse, el servidor la cierra de forma activa; si necesitas más tiempo, reconéctate por segmentos.
- Saldo insuficiente: hay dos casos. Al establecer la sesión, si el saldo disponible no cubre la reserva de cuota de aproximadamente 1 minuto, el handshake se rechaza directamente (HTTP 403) y la sesión no se establece; durante la sesión, si se agota el saldo (detectado en la validación de renovación cada 20 segundos o en la revisión tras un descuento por segmento), la conexión ya establecida se cierra de inmediato.
- Solo del lado del servidor: no se admite la conexión directa desde el navegador (se valida la cabecera
Origin); realiza la integración en el servidor. - Bloqueo del modelo: el modelo queda fijado en la URL de conexión; cambiar el modelo durante la sesión mediante
session.updatese rechaza y se cierra la sesión. - Bloqueo del formato: solo se admite
audio/pcm@24000en mono; cualquier otro formato se rechaza.
Errores frecuentes
Última actualización: 2026-09-16