For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navigation principale

WebSockets

Connectez des flux audio gérés par le serveur via WebSockets.

Choisissez l’API utilisée par votre application. Chaque API a ses propres mécanismes d’authentification et de création de sessions, ainsi que son propre contrat d’événements.

Connectez un serveur à GPT-Live

Utilisez une connexion WebSocket principale lorsque votre serveur capture de l’audio ou relaie un flux audio pour un client. Elle transporte l’audio et les événements JSON dans les deux sens. Conservez la clé API du projet sur ce serveur de confiance. Pour les applications mobiles et les applications exécutées dans un navigateur, commencez par WebRTC.

Ce guide traite de la connexion audio principale. Une connexion auxiliaire permet à un serveur d’observer et de contrôler une session Live existante. Une connexion WebSocket Responses relie votre backend à l’API Responses pour le raisonnement et les outils. Aucune des deux ne remplace la connexion audio principale.

Authentifiez-vous et démarrez la session

  1. Connectez-vous à wss://api.openai.com/v1/live/sessions sans paramètres de requête. Authentifiez-vous avec Authorization: Bearer $OPENAI_API_KEY et incluez les en-têtes de connexion présentés dans l’exemple.
  2. Envoyez session.start comme premier message. Placez le modèle, les instructions de conversation, le format audio, la voix et la configuration de délégation dans l’objet session.
  3. Attendez session.started avant d’envoyer de l’audio ou des commandes de l’application. Cet événement contient la configuration effective de la session et son identifiant.

L’exemple ci-dessous utilise Marin, de l’audio PCM16 à 24 kHz et un backend Responses avec recherche web. Gardez les instructions de conversation courtes. Configurez les instructions du backend, les outils et leurs autorisations en suivant le guide Délégation et outils.

Transmettez de l’audio en continu avec un SDK

Pour Node.js, installez openai et ws avec npm install openai ws, puis enregistrez l’exemple JavaScript dans client.mjs. Pour Python sur macOS ou Linux, installez openai[realtime] et enregistrez l’exemple Python dans client.py. Définissez OPENAI_API_KEY dans l’environnement du serveur. Ces exemples nécessitent une version du SDK prenant en charge Live. L’exemple lit de l’audio brut mono PCM16 à 24 kHz depuis l’entrée standard et écrit l’audio renvoyé dans le même format sur la sortie standard. Reliez ces flux aux fonctions de capture et de lecture audio de votre application. Les journaux et les événements de transcription sont écrits sur la sortie d’erreur standard afin de ne pas corrompre le flux audio.

import OpenAI from "openai";
import { LiveWS } from "openai/resources/live/ws";

// stdin and stdout carry raw mono PCM16 audio at 24 kHz, not WAV files.
// Supply microphone bytes continuously and play stdout in the same format.
process.stdin.pause();
const ws = new LiveWS(new OpenAI());
let started = false;
let closing = false;
let finalized = false;
let pendingByte = Buffer.alloc(0);

let closeTimeout;

ws.socket.on("open", () => {
  ws.send({
    type: "session.start",
    event_id: "event_start",
    session: {
      model: "gpt-live-1",
      instructions:
        "Be concise. Delegate requests needing current information to the backend, which can search the web.",
      audio: {
        format: { type: "audio/pcm", rate: 24000 },
        output: { voice: "marin" },
      },
      delegation: {
        type: "responses",
        responses: {
          model: "gpt-5.6-luna",
          tools: [{ type: "web_search" }],
          tool_choice: "auto",
        },
      },
    },
  });
});

process.stdin.on("data", (chunk) => {
  if (!started || closing || ws.socket.readyState !== 1) return;
  const bytes = Buffer.concat([pendingByte, chunk]);
  const completeLength = bytes.length - (bytes.length % 2);
  pendingByte = bytes.subarray(completeLength);
  if (completeLength) {
    ws.send({
      type: "session.input_audio.append",
      audio: bytes.subarray(0, completeLength).toString("base64"),
    });
  }
});

// Register the final-event handler before any close command can be sent.
ws.on("event", (event) => {
  if (event.type === "session.started") {
    started = true;
    console.error("Session ready", event.session.id);
    process.stdin.resume();
  } else if (event.type === "session.output_audio.delta") {
    process.stdout.write(Buffer.from(event.delta, "base64"));
  } else if (event.type === "session.closed") {
    finalized = true;
    clearTimeout(closeTimeout);
    process.stdin.pause();
    console.error("Final session usage", event.usage);
    ws.close();
  } else {
    // Includes transcript deltas and nested response.event usage.
    console.error(JSON.stringify(event));
  }
});

process.on("SIGINT", () => {
  if (closing) return;
  if (!started || ws.socket.readyState !== 1) {
    ws.socket.platformSocket.terminate();
    return;
  }
  closing = true;
  process.stdin.pause();
  ws.send({ type: "session.close" });
  closeTimeout = setTimeout(() => {
    console.error("Incomplete finalization: session.closed was not received");
    process.exitCode = 1;
    ws.socket.platformSocket.terminate();
  }, 15_000);
});
ws.on("error", (error) => {
  console.error(error.message);
  process.exitCode = 1;
});
ws.socket.on("close", () => {
  clearTimeout(closeTimeout);
  process.stdin.pause();
  if (!finalized) {
    console.error("Connection closed without final session usage");
    process.exitCode = 1;
  }
});

Exécutez node client.mjs ou python client.py après avoir raccordé votre source audio et votre lecteur. Une fois Session ready affiché, fournissez un flux continu provenant du microphone, au rythme de sa fréquence d’échantillonnage à l’enregistrement. Envoyer un fichier entier d’un seul coup via un pipe ne simule pas un microphone en direct. La fin de fichier (EOF) sur la source audio ne met pas fin à la conversation. Envoyez SIGINT au processus pour demander une fermeture propre.

L’exemple relie les flux audio ; votre application gère la capture, la mise en mémoire tampon, la lecture et le rééchantillonnage si nécessaire. Testez ces éléments avec vos appareils et votre réseau avant d’évaluer le comportement du modèle.

Choisissez le format audio

Définissez session.audio.format au démarrage. Un même format s’applique à l’entrée et à la sortie et ne peut pas être modifié pendant la session.

  • {"type":"audio/pcm","rate":24000} : PCM mono signé sur 16 bits, en petit-boutiste, à 24 kHz ; format par défaut.
  • {"type":"audio/pcm","rate":16000} : PCM mono signé sur 16 bits, en petit-boutiste, à 16 kHz.
  • {"type":"audio/pcmu","rate":8000} : G.711 μ-law à 8 kHz, un octet par échantillon.
  • {"type":"audio/pcma","rate":8000} : G.711 A-law à 8 kHz, un octet par échantillon.

Encodez les octets bruts en base64, sans en-tête WAV ni en-tête d’un autre conteneur. Les blocs PCM doivent contenir des échantillons complets de 16 bits ; leur taille en octets doit donc être paire. L’exemple reporte tout octet restant à la fin d’un bloc dans le bloc d’entrée suivant. En dehors de cette contrainte, les limites des blocs sont arbitraires : conservez un flux continu et ordonné.

Rééchantillonnez l’audio lorsque sa fréquence d’échantillonnage diffère de la fréquence configurée. Modifier le paramètre de format ne convertit pas les octets d’entrée. Pour adapter l’exemple à G.711, transmettez les octets encodés de chaque bloc sans appliquer la logique d’alignement sur deux octets propre au PCM, et configurez le lecteur de sortie pour le même codec. Un flux G.711 correspondant peut être transmis sans conversion en PCM. Consultez Intégrations téléphoniques pour connecter un appel téléphonique.

Envoyez et recevez des événements

Envoyez chaque événement sous forme de message texte JSON. L’audio est transmis en base64 dans ces messages.

  • Envoi audio : envoyez session.input_audio.append avec les octets bruts encodés en base64 dans audio. Les ajouts audio ne font l’objet d’aucun accusé de réception.
  • Réception audio : décodez delta dans chaque événement session.output_audio.delta et placez l’audio dans une file d’attente pour le lire dans l’ordre, au format configuré.
  • Réception des transcriptions : ajoutez le texte contenu dans delta des événements session.input_transcript.delta et session.output_transcript.delta à la transcription correspondante.
  • Réception des événements du backend : lorsque vous utilisez la délégation à Responses, traitez le champ event imbriqué dans chaque enveloppe response.event.
  • Gestion des erreurs : traitez les commandes rejetées et les erreurs de session signalées par les événements error. Utilisez error.client_event_id, lorsqu’il est présent, pour identifier la commande.

Les événements audio de sortie ne comportent aucun champ temporel, et GPT-Live n’émet pas d’événement output-audio-done. Suivez votre file d’attente de lecture pour savoir quelles données audio reçues ont été lues. Les horodatages des transcriptions décrivent des intervalles sur la chronologie de la session ; ils n’indiquent pas la fin de la lecture audio. La fin d’une réponse du backend ne signifie pas non plus que l’assistant a fini de parler.

GPT-Live détermine quand écouter et quand parler pendant la transmission audio en continu. Il n’utilise pas la boucle de tours de parole de Realtime, fondée sur la validation du tampon d’entrée et response.create. Dans Live, response.create démarre ou poursuit le travail délégué au backend. Consultez Délégation et outils pour ce workflow.

Configurez une session en cours

Le modèle Live, les instructions initiales de conversation, le format audio, la voix et le mode de délégation sont fixés au démarrage. Utilisez session.update pour modifier les paramètres pris en charge dans le mode de délégation actuel ; les paramètres omis conservent leur valeur actuelle. Une mise à jour réussie renvoie session.updated avec la configuration effective de la session.

Utilisez session.instructions.append pour ajouter des instructions de conversation, et session.input_audio.mute ou session.input_audio.unmute pour contrôler l’audio entrant. Couper l’audio d’entrée n’annule pas le travail du backend et n’arrête pas la parole générée. Consultez Gestion des sessions pour les mises à jour du contexte, les transcriptions, les commandes de contrôle de l’entrée et les données d’utilisation.

Fermez la session

Envoyez session.close lorsque la conversation se termine. Enregistrez d’abord le gestionnaire d’événement session.closed, continuez à recevoir les événements jusqu’à son arrivée, puis libérez la connexion. L’exemple attend jusqu’à 15 secondes et signale une finalisation incomplète si l’événement de fin n’arrive pas.

Conservez les données finales d’utilisation vocale de session.closed ainsi que les événements d’utilisation du backend déjà reçus. Les mises à jour de durée vocale sont des instantanés cumulatifs ; ne les additionnez pas. Une défaillance du transport ou un dépassement du délai avant session.closed laisse l’utilisation finale non confirmée. Consultez Gestion des sessions pour le cycle de vie complet.