---
title: "Usa ThunderPhone con clientes de OpenAI Realtime"
description: "Dirige un cliente de servidor compatible con OpenAI Realtime a ThunderPhone mediante un agente guardado o una configuración de sesión en línea."
---

ThunderPhone implementa un subconjunto específico del modelo de eventos Realtime de OpenAI.
Un cliente existente del lado del servidor puede mantener su flujo de eventos de WebSocket, audio, sesión y
respuesta mientras usa un voice agent de ThunderPhone.

## Antes de conectarte

Necesitas una clave secreta de API de organización de ThunderPhone y un entorno de ejecución de servidor que
pueda abrir WebSockets. No te conectes desde código del navegador ni expongas la clave a un
navegador. Para usar un agente guardado, primero debes implementarlo y copiar su ID numérico de agente.

Conéctate a:

```text
wss://api.thunderphone.com/v1/realtime
```

Autentica la actualización de WebSocket desde tu servidor:

```http
Authorization: Bearer sk_live_YOUR_API_KEY
```

La autenticación mediante cadena de consulta está disponible para clientes que no pueden establecer encabezados
de enlace, pero las URL son más fáciles de filtrar en los registros.

## Elige quién controla la configuración

| Modo | Conectar con | Fuente de configuración |
| --- | --- | --- |
| Agente guardado | `?agent_id=12` | Prompt, voz, producto, idiomas, conocimiento y herramientas compatibles ejecutadas en el servidor implementados |
| En línea | Sin `agent_id` | El primer `session.update` aceptado de tu cliente |

### Agente guardado

Conéctate con el ID del agente implementado:

```text
wss://api.thunderphone.com/v1/realtime?agent_id=12
```

El agente se inicia mientras se conecta el socket. Su saludo permanece disponible,
pero Realtime desactiva sus verificaciones de silencio habladas y omite `transfer_call`
y `send_keypad_input`. Otras herramientas compatibles se ejecutan en ThunderPhone. No
envíes instrucciones en línea ni herramientas ejecutadas por el cliente para este modo.

Establece el audio de transmisión antes de que se inicie el agente con los parámetros de consulta
`input_audio_format`, `output_audio_format`, `input_rate` y `output_rate`. No
puedes cambiar la configuración guardada ni los formatos de audio después de conectarte.

### Sesión en línea

Sin `agent_id`, espera a `session.created` y luego envía `session.update`:

```json
{
  "type": "session.update",
  "session": {
    "type": "realtime",
    "instructions": "Answer questions clearly and keep responses brief.",
    "audio": {
      "input": {
        "format": { "type": "audio/pcm", "rate": 24000 }
      },
      "output": {
        "format": { "type": "audio/pcm", "rate": 24000 },
        "voice": "olivia"
      }
    },
    "config": {
      "product": "bolt"
    }
  }
}
```

La primera actualización aceptada aprovisiona la llamada. `session.updated` significa que la
sesión está activa. Las instrucciones, la voz, el producto, las herramientas y los formatos de audio no pueden
cambiar después de ese momento.

Las sesiones en línea no tienen saludo automático ni verificaciones de silencio habladas. Para
hacer que el agente hable primero, agrega un mensaje de sistema o de usuario y envía
`response.create`. Una sesión completamente inactiva aún finaliza al alcanzar el límite de
llamadas silenciosas de la plataforma, 600 segundos de forma predeterminada.

## Usa el SDK oficial de OpenAI

Pasa una URL base de WebSocket que termine en `/v1`; el SDK agrega `/realtime`. El valor de
`model` es un nombre de compatibilidad y no selecciona el producto de ThunderPhone.
Elige el producto en la configuración de la sesión o en el agente guardado.

Esta comprobación de conexión crea una sesión Bolt integrada, imprime eventos hasta el
primer `session.updated` y se cierra. Usa el [cliente mínimo de
Python](/api-reference/realtime#minimal-python-client) para transmitir audio.

```python
import asyncio
import os

from openai import AsyncOpenAI


async def main():
    client = AsyncOpenAI(
        api_key=os.environ["THUNDERPHONE_API_KEY"],
        websocket_base_url="wss://api.thunderphone.com/v1",
    )

    async with client.realtime.connect(
        model="thunderphone-realtime"
    ) as connection:
        await connection.session.update(session={
            "type": "realtime",
            "instructions": "Listen to the caller and help them complete the call.",
            "config": {"product": "bolt"},
        })
        async for event in connection:
            print(event.type)
            if event.type == "session.updated":
                break


if __name__ == "__main__":
    asyncio.run(main())
```

Conserva tu manejo actual para la incorporación de audio de entrada, los deltas de audio de respuesta,
las interrupciones, las llamadas a funciones, los errores y el cierre limpio del socket. Las funciones personalizadas integradas
se ejecutan en tu cliente; devuelve sus resultados mediante el protocolo Realtime.
Las herramientas de agentes guardados se ejecutan en ThunderPhone.

## Ciclo de vida y fallas de la sesión

Un WebSocket representa una llamada. Un ID de agente no válido o una configuración integrada rechazada
produce un evento `error`. Espera `session.updated` antes de considerar que la sesión está activa.
Declara los formatos y las frecuencias de muestreo reales de entrada y salida: una discrepancia en la frecuencia PCM reproduce el audio
demasiado rápido o demasiado lento en lugar de generar un error de validación.

Después de que se inicie la sesión, cierra el socket correctamente cuando tu aplicación haya terminado.
Las sesiones integradas pueden usar funciones ejecutadas por el cliente. Las sesiones de agentes guardados
usan herramientas compatibles ejecutadas por ThunderPhone y no ofrecen transferencia ni entrada por teclado.

## Prueba la integración

Comienza con el [cliente WAV mínimo de Python](/api-reference/realtime#minimal-python-client)
y un WAV PCM16 mono a la frecuencia declarada. Verifica lo siguiente:

1. El servidor acepta la configuración y envía `session.updated`.
2. La entrada produce eventos de transcripción y audio de respuesta a la velocidad esperada.
3. La interrupción y la cancelación de respuesta detienen el audio de salida restante.
4. Los resultados de funciones integradas o de herramientas de agentes guardados regresan al modelo.
5. La entrada no válida produce un evento `error` que tu cliente maneja.
6. Tu cliente cierra el socket y la llamada aparece en el [historial de
   llamadas](/es/guides/review-calls).

La [referencia de WebSocket de Realtime](/api-reference/realtime) enumera los
eventos aceptados, formatos de audio, campos de sesión y ejemplos completos.

## Costo

Las llamadas Realtime usan la tarifa normal por minuto del producto seleccionado. Activar los deltas de
transcripción en vivo agrega un recargo por minuto para toda la sesión; consulta [Transcripciones
en vivo](/api-reference/realtime#live-transcripts) para conocer la tarifa y
[Precios](/es/guides/pricing) para conocer las tarifas de los productos.

`POST /v1/realtime/sessions` es una ruta administrada de LiveKit independiente. Crea una
sala y un token de participante con alcance limitado; no es necesaria para una conexión WebSocket directa.

Para integraciones con frameworks, consulta [Usa ThunderPhone desde Pipecat](/es/guides/use-with-pipecat)
y [Usa ThunderPhone desde LiveKit Agents](/es/guides/use-with-livekit).
