Les agents vocaux nécessitaient auparavant trois composants : la reconnaissance vocale (speech-to-text), un modèle linguistique, puis la synthèse vocale (text-to-speech). Chaque étape ajoutait de la latence et altérait le ton. L'API Realtime d'OpenAI regroupe cela en un seul modèle de parole à parole, et gpt-realtime-2.1-mini est le niveau le moins cher et le plus rapide de cette famille. Il écoute l'audio, réfléchit et répond via une seule connexion de streaming.
Ce guide vous montre comment l'utiliser de bout en bout : quel ID de modèle utiliser, comment se connecter via WebSocket et WebRTC, comment configurer une session, et comment tester l'ensemble avec Apidog avant de l'intégrer à une application. Tout ce qui est présenté ici correspond au guide officiel OpenAI Realtime.
D'abord, assurez-vous d'utiliser le bon nom de modèle
La nomenclature prête à confusion, alors clarifions-la avant tout code. Il existe deux identifiants pour le même modèle mini :
gpt-realtime-2.1-mini: l'ID versionné. C'est celui qui apparaît sur la page de tarification d'OpenAI et vous lie à la génération 2.1.gpt-realtime-mini: l'alias de famille. Il pointe toujours vers le dernier instantané, actuellementgpt-realtime-mini-2025-12-15.
Les instantanés vous permettent de figer le comportement en production :
| Identifiant | Ce à quoi il pointe |
|---|---|
gpt-realtime-mini |
Dernier instantané mini (mises à jour automatiques) |
gpt-realtime-2.1-mini |
Le mini de la génération 2.1 |
gpt-realtime-mini-2025-12-15 |
Instantané épinglé (actuel) |
gpt-realtime-mini-2025-10-06 |
Instantané épinglé (précédent) |
Utilisez l'alias pendant le développement, puis épinglez un instantané daté avant le déploiement afin qu'une mise à jour du modèle ne modifie jamais le comportement de votre agent du jour au lendemain.

Ce que fait gpt-realtime-2.1-mini
C'est un modèle de parole à parole. Vous lui envoyez de l'audio en streaming, et il renvoie de l'audio en streaming avec une intonation naturelle, sans étape de transcription ou de synthèse vocale (TTS) séparée. Il gère également le texte, vous pouvez donc mélanger des entrées textuelles et des sorties vocales dans la même session.
Voici la fiche technique de la page du modèle :
| Propriété | Valeur |
|---|---|
| Modalités d'entrée | Texte, image, audio |
| Modalités de sortie | Texte, audio |
| Fenêtre de contexte | 32 000 tokens |
| Sortie maximale | 4 096 tokens |
| Connexions | WebRTC, WebSocket, SIP |
| Voix | alloy, ash, ballad, coral, echo, sage, shimmer, verse, marin, cedar |
marin et cedar sont les voix les plus récentes et sont exclusives à l'API Realtime ; OpenAI les recommande pour la sortie la plus naturelle. Les voix plus anciennes fonctionnent toujours si vous souhaitez un timbre spécifique.
Le niveau « mini » sacrifie un peu de profondeur de raisonnement pour une latence plus faible et une facture bien moins élevée. Pour la plupart des bots de support, des flux de prise de commande et des interfaces vocales, c'est le bon choix par défaut. N'utilisez le `gpt-realtime-2.1` complet que lorsque la conversation nécessite un raisonnement plus poussé.
Ce que cela coûte
Le modèle Mini coûte environ un tiers du prix du modèle complet. Tarifs des tokens à partir de la page de tarification :
| Modèle | Entrée texte | Entrée en cache | Entrée audio | Sortie audio |
|---|---|---|---|---|
gpt-realtime-2.1-mini |
0,60 $ / 1M | 0,30 $ / 1M | 10 $ / 1M | 20 $ / 1M |
gpt-realtime-2.1 (complet) |
4,00 $ / 1M | 0,40 $ / 1M | 32 $ / 1M | 64 $ / 1M |
L'audio domine la facture, et le principal levier de coût est la quantité de paroles de votre agent. Un agent qui parle 35 secondes par minute coûte environ deux fois plus qu'un agent qui parle 15 secondes par minute. Les coûts réels par minute pour le modèle mini se situent autour de 0,06 $ à 0,15 $ selon la verbosité, alors demandez à votre modèle d'être concis dans les instructions et vous réduirez directement la facture. Les tarifs changent, alors confirmez-les sur la page de tarification en direct avant de faire vos prévisions.
Prérequis
Vous avez besoin de trois choses :
- Une clé API OpenAI avec accès Realtime, définie comme
OPENAI_API_KEY. - Node.js 18+ pour les exemples de serveur (le package
wspour WebSocket brut, ou le SDKopenaiofficiel). - Pour l'audio du navigateur, une page servie via HTTPS ou
localhostpour quegetUserMediafonctionne.
Une règle avant de toucher au navigateur : n'envoyez jamais votre véritable clé API au client. Les applications de navigateur et mobiles utilisent plutôt des tokens éphémères de courte durée. Plus d'informations ci-dessous.
Choisissez une méthode de connexion
Le modèle mini prend en charge trois transports. Choisissez en fonction de l'emplacement de votre audio.
| Transport | Quand l'utiliser | Authentification |
|---|---|---|
| WebRTC | L'audio est capturé ou lu dans un navigateur ou une application mobile | Secret client éphémère |
| WebSocket | Votre serveur gère déjà l'audio brut d'un pipeline multimédia | Clé API (côté serveur) |
| SIP | Vous connectez un téléphone ou un système de téléphonie | Clé API |
La plupart des gens commencent avec WebSocket pour prototyper côté serveur, puis passent à WebRTC pour le client réel. Faisons les deux.
Démarrage rapide 1 : WebSocket depuis votre serveur
WebSocket est le moyen le plus rapide de voir le modèle répondre. Le point d'accès est une URL unique avec le modèle dans la chaîne de requête :
wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1-mini
Puisqu'il s'agit de l'interface GA (Disponibilité Générale), vous vous authentifiez avec un simple en-tête `Authorization: Bearer` et vous n'avez plus besoin de l'ancien en-tête `OpenAI-Beta`. Voici un exemple « hello world » texte-en, texte-sortant pour que vous puissiez tester sans microphone :
import WebSocket from "ws";
const url = "wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1-mini";
const ws = new WebSocket(url, {
headers: { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
});
ws.on("open", () => {
// 1. Configure the session
ws.send(JSON.stringify({
type: "session.update",
session: {
type: "realtime",
model: "gpt-realtime-2.1-mini",
output_modalities: ["text"],
instructions: "You are a concise API support agent. Keep answers short.",
},
}));
// 2. Add a user message
ws.send(JSON.stringify({
type: "conversation.item.create",
item: {
type: "message",
role: "user",
content: [{ type: "input_text", text: "What is an idempotent request?" }],
},
}));
// 3. Ask for a response
ws.send(JSON.stringify({ type: "response.create" }));
});
ws.on("message", (raw) => {
const event = JSON.parse(raw.toString());
if (event.type === "response.output_text.delta") process.stdout.write(event.delta);
if (event.type === "response.done") ws.close();
});
Le flux est toujours le même : configurer, ajouter une entrée, demander une réponse, écouter les deltas. Les événements du serveur sont diffusés en streaming au format JSON. Ceux qui vous intéressent le plus :
session.created/session.updated: votre configuration a été acceptéeresponse.output_text.delta: un morceau de texteresponse.output_audio.delta: un morceau d'audio base64response.output_audio_transcript.delta: la transcription de ce que dit le modèleresponse.done: le tour est terminé
Pour passer du texte à la voix, basculez `output_modalities` sur `["audio"]` et ajoutez une configuration audio (section suivante). L'audio arrive dans les événements `response.output_audio.delta` sous forme de fragments PCM base64 que vous décodez et lisez.
Démarrage rapide 2 : WebRTC dans le navigateur
Pour une véritable application vocale, le navigateur capture le micro et lit la réponse directement, ce qui maintient une faible latence. Le problème est l'authentification : vous ne pouvez pas exposer votre clé API, votre serveur génère donc d'abord un token de courte durée.
Étape 1 : générez un token éphémère sur votre serveur. Appelez le point d'accès `client-secrets` avec votre clé réelle :
// server side
const r = await fetch("https://api.openai.com/v1/realtime/client_secrets", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
session: { type: "realtime", model: "gpt-realtime-2.1-mini" },
}),
});
const { value } = await r.json(); // clé éphémère, commence par "ek_"
Envoyez `value` au navigateur. Il expire rapidement, donc une fuite présente un faible risque.
Étape 2 : connectez-vous depuis le navigateur avec WebRTC. Vous capturez le micro, ouvrez un canal de données pour les événements et échangez le SDP avec le point d'accès `/v1/realtime/calls` :
// côté navigateur : `EPHEMERAL_KEY` provient de votre serveur
const pc = new RTCPeerConnection();
// lire l'audio du modèle
pc.ontrack = (e) => (document.getElementById("audio").srcObject = e.streams[0]);
// envoyer le micro
const mic = await navigator.mediaDevices.getUserMedia({ audio: true });
pc.addTrack(mic.getTracks()[0]);
// les événements transitent par un canal de données
const channel = pc.createDataChannel("oai-events");
channel.onmessage = (e) => console.log(JSON.parse(e.data));
// Poignée de main SDP
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const sdpResp = await fetch(
"https://api.openai.com/v1/realtime/calls?model=gpt-realtime-2.1-mini",
{
method: "POST",
body: offer.sdp,
headers: {
Authorization: `Bearer ${EPHEMERAL_KEY}`,
"Content-Type": "application/sdp",
},
}
);
await pc.setRemoteDescription({ type: "answer", sdp: await sdpResp.text() });
Une fois la connexion établie, le modèle écoute sur la piste du micro et parle via `pc.ontrack`. Vous envoyez la configuration et le texte via le même canal de données `oai-events` en utilisant les événements JSON exacts de l'exemple WebSocket.
Configuration de la session
L'objet `session` est l'endroit où vous contrôlez le comportement. Voici la version audio complète de ce que vous avez vu ci-dessus :
{
type: "session.update",
session: {
type: "realtime",
model: "gpt-realtime-2.1-mini",
output_modalities: ["audio"],
instructions: "You are a friendly booking assistant. Confirm details before acting.",
audio: {
input: {
format: { type: "audio/pcm", rate: 24000 },
turn_detection: { type: "semantic_vad" },
},
output: {
format: { type: "audio/pcm", rate: 24000 },
voice: "marin",
},
},
},
}
Les champs importants :
instructions: votre prompt système. Définissez la persona, les garde-fous et « soyez bref » si vous vous souciez des coûts.output_modalities:["audio"]pour un agent parlant,["text"]pour un bot basé uniquement sur la transcription.audio.output.voice: choisissez parmi les dix voix ;marinoucedarsemblent les plus naturelles.audio.input.turn_detection: comment le modèle décide que vous avez arrêté de parler.semantic_vadattend une pause naturelle dans le sens ;server_vadse déclenche au silence. La détection sémantique interrompt moins et semble plus fluide en conversation.
Modifiez n'importe quel champ en cours d'appel en envoyant un autre `session.update`. Vous n'avez pas besoin de vous reconnecter.
Ajouter des outils pour que l'agent puisse agir
Un agent vocal qui ne peut que discuter est une démo. Pour réserver une table ou vérifier une commande, le modèle a besoin d'outils. Realtime utilise le même contrat d'appel de fonction que le reste de la plateforme : vous déclarez les fonctions dans la session, le modèle émet un appel, vous l'exécutez et vous renvoyez le résultat. Si vous avez déjà intégré des outils dans l'API de chat, c'est le même modèle mental ; notre présentation de l'appel de fonction OpenAI couvre le schéma en profondeur, et les sorties structurées vous aident lorsque vous avez besoin que les arguments correspondent à une forme stricte.
Déclarez les outils à l'intérieur de la session, puis gérez l'événement `response.function_call_arguments.done`, exécutez votre code et publiez un `conversation.item.create` avec le résultat avant le `response.create` suivant. Pour tout ce qui est plus élaboré que quelques fonctions, l'AgentKit d'OpenAI vous offre un moyen de plus haut niveau d'orchestrer des agents vocaux multi-étapes.
Testez les points d'accès avec Apidog avant de construire
Vous ne voulez pas déboguer un appel REST et une poignée de main WebSocket en lisant les journaux de la console dans une application à moitié construite. Testez d'abord les éléments isolément. C'est là qu'Apidog trouve sa place dans un workflow en temps réel.
Deux choses méritent d'être validées avant d'écrire du code client :
- Le point d'accès du token.
POST https://api.openai.com/v1/realtime/client_secretsest un appel REST ordinaire. Créez une requête dans Apidog, ajoutez votre en-têteAuthorization: Bearer, insérez le corps JSON avec l'ID de votre modèle et envoyez-la. Vous verrez immédiatement le tokenek_et son expiration, vous saurez donc que votre clé et l'accès à votre compte sont valides avant même que WebRTC n'entre en jeu. C'est la même approche que vous utiliseriez pour tester rapidement n'importe quelle surface REST d'OpenAI, comme l'API Responses. - Le flux de messages WebSocket. Apidog dispose d'un client WebSocket, vous pouvez donc ouvrir une connexion à
wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1-mini, ajouter l'en-tête d'authentification et envoyer manuellement les messagessession.update,conversation.item.createetresponse.createun par un. Observer les événements du serveur revenir dans un panneau lisible rend la séquence d'événements évidente, et vous pouvez enregistrer les messages comme exemples pour votre équipe. Si vous vous appuyez déjà sur de solides stratégies de test d'API, cela s'intègre parfaitement.
Tester la couche de transport seule signifie que si quelque chose ne fonctionne pas dans l'application, vous savez déjà que ce n'est pas le contrat d'API. Téléchargez Apidog si vous voulez suivre.
Gardez la facture sous contrôle
La sortie audio est la partie coûteuse, donc quelques habitudes sont rentables :
- Demandez au modèle d'être bref. « Gardez les réponses à une ou deux phrases » dans les instructions réduit directement les tokens de sortie audio.
- Épinglez un instantané en production.
gpt-realtime-mini-2025-12-15ne dérivera pas ; l'aliasgpt-realtime-minile peut. - Utilisez `semantic_vad`. Moins de fausses interruptions signifie moins de demi-réponses inutiles que vous payez.
- Mettez votre prompt système en cache. L'entrée en cache coûte 0,30 $ par 1M contre 0,60 $ pour une nouvelle entrée textuelle, donc un bloc d'instructions stable est moins cher à chaque tour.
- Fermez les sessions inactives. Une connexion ouverte avec un utilisateur inactif reste une session pour laquelle vous pourriez être facturé.
Erreurs courantes et correctifs
- 401 Non autorisé : la clé est incorrecte, ou vous avez envoyé un token éphémère expiré. Les clés éphémères sont de courte durée par conception ; générez-en une nouvelle par session.
- Modèle introuvable : vérifiez l'ID exact. C'est
gpt-realtime-2.1-mini, pasgpt-realtime-mini-2.1. - Pas d'audio dans le navigateur : vous n'avez probablement pas attaché le flux distant dans `pc.ontrack`, ou la page n'est pas sur HTTPS/localhost, donc le micro ne s'est jamais ouvert.
- Le modèle n'arrête pas de parler par-dessus l'utilisateur : basculez `turn_detection` sur `semantic_vad` et confirmez que la piste du micro atteint la connexion.
- Envoi de l'en-tête beta : le point d'accès GA ne souhaite pas
OpenAI-Beta: realtime=v1. Supprimez-le.
FAQ
- gpt-realtime-2.1-mini est-il identique à gpt-realtime-mini ? Oui, en pratique.
gpt-realtime-2.1-miniest l'ID versionné,gpt-realtime-miniest l'alias qui pointe vers le dernier instantané (gpt-realtime-mini-2025-12-15). Utilisez l'alias pour construire, épinglez l'instantané pour déployer. - Puis-je l'utiliser pour de la simple transcription plutôt qu'un agent vocal ? L'API Realtime est conçue pour la parole interactive de parole à parole. Pour une transcription ponctuelle, les modèles de transcription dédiés d'OpenAI sont plus appropriés. Utilisez le modèle mini en temps réel lorsque vous avez besoin d'une conversation bidirectionnelle avec une faible latence.
- Ai-je besoin de WebRTC, ou WebSocket est-il suffisant ? WebSocket est suffisant pour les pipelines côté serveur et les prototypes rapides. Utilisez WebRTC lorsqu'un navigateur ou une application mobile capture et lit l'audio directement, car il gère le flux multimédia et la gigue pour vous.
- Quelle voix dois-je choisir ? `marin` et `cedar` sont les plus récentes et les plus naturelles, et elles sont exclusives à l'API Realtime. Les huit autres (alloy, ash, ballad, coral, echo, sage, shimmer, verse) fonctionnent toujours si vous souhaitez un son particulier.
- Comment la facturation est-elle effectuée ? Par token, répartie par modalité. Pour le mini : 0,60 $ par 1M d'entrée texte, 10 $ par 1M d'entrée audio, et 20 $ par 1M de sortie audio. La sortie audio est le coût dominant, donc la verbosité est votre principal levier.
- Peut-il appeler des fonctions comme les modèles de chat ? Oui. Realtime utilise le même contrat d'appel de fonction, de sorte qu'un agent vocal peut rechercher des commandes, vérifier l'inventaire ou déclencher des actions en cours de conversation.
Où aller ensuite
Vous avez maintenant la boucle complète : le bon ID de modèle, un prototype WebSocket, un client de navigateur WebRTC, la configuration de session, les outils et un moyen de tester chaque élément dans Apidog avant la production. Commencez par l'exemple WebSocket texte uniquement pour confirmer l'accès, basculez `output_modalities` sur l'audio, puis passez à WebRTC lorsque vous êtes prêt pour un vrai microphone. Épinglez un instantané, demandez au modèle d'être concis, et vous aurez un agent vocal à faible latence qui ne vous surprendra pas sur la facture.
