---
title: "Gebruik ThunderPhone met OpenAI Realtime-clients"
description: "Laat een serverclient die compatibel is met OpenAI Realtime naar ThunderPhone verwijzen met een opgeslagen agent of een inline sessieconfiguratie."
---

ThunderPhone implementeert een gerichte subset van het OpenAI Realtime-gebeurtenismodel.
Een bestaande client aan de serverzijde kan zijn eventstroom voor WebSocket, audio, sessies en
reacties behouden terwijl deze een ThunderPhone-spraakagent gebruikt.

## Voordat je verbinding maakt

Je hebt een geheime API-sleutel voor je ThunderPhone-organisatie nodig en een serverruntime die
WebSockets kan openen. Maak geen verbinding vanuit browsercode en stel de sleutel niet bloot aan
een browser. Als je een opgeslagen agent wilt gebruiken, implementeer je deze eerst en kopieer je
de numerieke agent-ID.

Maak verbinding met:

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

Verifieer de WebSocket-upgrade vanaf je server:

```http
Authorization: Bearer sk_live_YOUR_API_KEY
```

Authenticatie via querystrings is beschikbaar voor clients die geen handshakeheaders
kunnen instellen, maar URL's lekken gemakkelijker naar logboeken.

## Kies wie eigenaar is van de configuratie

| Modus | Verbinden met | Configuratiebron |
| --- | --- | --- |
| Opgeslagen agent | `?agent_id=12` | Geïmplementeerde prompt, stem, product, talen, kennis en compatibele tools die op de server worden uitgevoerd |
| Inline | Geen `agent_id` | De eerste geaccepteerde `session.update` van je client |

### Opgeslagen agent

Maak verbinding met de ID van de geïmplementeerde agent:

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

De agent start terwijl de socket verbinding maakt. De begroeting blijft beschikbaar,
maar Realtime schakelt de gesproken controles bij stilte uit en laat `transfer_call`
en `send_keypad_input` weg. Andere compatibele tools worden uitgevoerd op ThunderPhone. Verstuur
geen inline-instructies of door de client uitgevoerde tools voor deze modus.

Stel de audio voor overdracht in voordat de agent start met de queryparameters
`input_audio_format`, `output_audio_format`, `input_rate` en `output_rate`. Je
kunt de opgeslagen configuratie of audioformaten na verbinding niet wijzigen.

### Inline-sessie

Wacht zonder `agent_id` op `session.created` en verstuur vervolgens `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"
    }
  }
}
```

De eerste geaccepteerde update richt de oproep in. `session.updated` betekent dat de
sessie actief is. Instructies, stem, product, tools en audioformaten kunnen
daarna niet meer worden gewijzigd.

Inline-sessies hebben geen automatische begroeting of gesproken controles bij stilte. Als je wilt
dat de agent als eerste spreekt, voeg je een systeem- of gebruikersbericht toe en verstuur je
`response.create`. Een volledig inactieve sessie eindigt nog steeds bij de limiet voor stille oproepen
van het platform, standaard 600 seconden.

## Gebruik de officiële OpenAI SDK

Geef een WebSocket-basis-URL door die eindigt op `/v1`; de SDK voegt `/realtime` toe. De waarde van
`model` is een compatibiliteitsnaam en selecteert niet het ThunderPhone-product.
Kies het product in de sessieconfiguratie of de opgeslagen agent.

Deze verbindingscontrole maakt een inline Bolt-sessie, toont gebeurtenissen tot de
eerste `session.updated` en sluit vervolgens. Gebruik de [minimale Python-
client](/api-reference/realtime#minimal-python-client) om audio te streamen.

```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())
```

Behoud je bestaande verwerking voor het toevoegen van invoeraudio, respons-audiodelta's,
onderbrekingen, functieaanroepen, fouten en het netjes sluiten van de socket. Inline aangepaste
functies worden uitgevoerd in je client; stuur hun resultaten terug via het Realtime-
protocol. Tools van opgeslagen agents worden uitgevoerd op ThunderPhone.

## Sessielevenscyclus en fouten

Eén WebSocket vertegenwoordigt één oproep. Een ongeldige agent-ID of afgewezen inline
configuratie veroorzaakt een `error`-gebeurtenis. Wacht op `session.updated` voordat je
de sessie als actief beschouwt. Geef de daadwerkelijke invoer- en uitvoerformaten en
samplefrequenties op: een afwijkende PCM-frequentie speelt audio te snel of te langzaam
af in plaats van een validatiefout te veroorzaken.

Sluit de socket netjes wanneer je toepassing klaar is nadat de sessie is gestart. Inline
sessies kunnen functies gebruiken die door de client worden uitgevoerd. Sessies met
opgeslagen agents gebruiken compatibele tools die op ThunderPhone worden uitgevoerd en
bieden geen doorschakeling of toetsenbordinvoer.

## Test de integratie

Begin met de [minimale Python WAV-client](/api-reference/realtime#minimal-python-client)
en een mono PCM16 WAV met de opgegeven frequentie. Controleer het volgende:

1. De server accepteert de configuratie en stuurt `session.updated`.
2. Invoer produceert transcriptie- en respons-audiogebeurtenissen met de verwachte snelheid.
3. Onderbreking en annulering van een respons stoppen resterende uitvoeraudio.
4. Resultaten van inline functies of tools van opgeslagen agents worden teruggestuurd naar het model.
5. Ongeldige invoer veroorzaakt een `error`-gebeurtenis die je client verwerkt.
6. Je client sluit de socket en de oproep verschijnt in de [Oproepgeschiedenis](/nl/guides/review-calls).

De [Realtime WebSocket-referentie](/api-reference/realtime) bevat de geaccepteerde
gebeurtenissen, audioformaten, sessievelden en volledige voorbeelden.

## Kosten

Realtime-oproepen gebruiken het normale tarief per minuut van het geselecteerde product.
Het inschakelen van live transcriptdelta's voegt een toeslag per minuut toe voor de hele
sessie; zie [Live transcripties](/api-reference/realtime#live-transcripts) voor het tarief
en [Prijzen](/nl/guides/pricing) voor producttarieven.

`POST /v1/realtime/sessions` is een afzonderlijk beheerd LiveKit-pad. Het maakt een
ruimte en een scoped deelnemertoken; het is niet vereist voor een directe WebSocket-
verbinding.

Zie voor frameworkintegraties [Gebruik ThunderPhone vanuit Pipecat](/nl/guides/use-with-pipecat)
en [Gebruik ThunderPhone vanuit LiveKit Agents](/nl/guides/use-with-livekit).
