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

Téléphonie et SIP

Connectez vos appels téléphoniques à OpenAI via SIP.

Choisissez votre API pour consulter la procédure de connexion et les événements de session correspondants.

Connectez vos appels téléphoniques entrants et sortants à GPT-Live via un trunk SIP. Votre opérateur échange les flux audio de l’appel avec OpenAI, tandis que votre backend gère la configuration de la session, les commandes d’appel et la logique métier. La signalisation SIP utilise TLS et GPT-Live exige SRTP pour l’audio des appels.

  • Gérez un appel entrant : recevez un webhook d’appel entrant, puis acceptez ou rejetez l’appel.
  • Passez un appel sortant : créez une session pour composer un numéro de téléphone via votre opérateur. Un appel sortant ne nécessite ni webhook d’appel entrant ni requête d’acceptation.

Utilisez une connexion auxiliaire lorsque votre backend doit recevoir des événements de session ou envoyer des commandes. Cette connexion se rattache à la conversation en cours, tandis que SIP transporte l’audio. Confiez chaque action à un seul gestionnaire pour éviter qu’un outil ne s’exécute deux fois si un webhook est livré plusieurs fois ou si plusieurs connexions reçoivent le même événement.

Gérez un appel entrant

Acheminez les appels entrants de votre opérateur SIP vers votre projet OpenAI. Pour chaque appel, votre backend reçoit un webhook et décide d’accepter ou de rejeter l’appel.

Configurez votre numéro de téléphone et votre trunk SIP

Faites appel à un opérateur de trunk SIP, par exemple Twilio, pour connecter un numéro de téléphone à GPT-Live. Après avoir acheté un numéro auprès de votre opérateur, procédez comme suit :

  1. Ouvrez votre projet dans les paramètres OpenAI. Sous Webhooks, créez un point de terminaison de webhook abonné à live.transport.incoming.
  2. Relevez l’identifiant de votre projet sous Général. Il commence par proj_. Utilisez le projet auquel appartient le webhook.
  3. Dirigez le trunk SIP de votre opérateur vers l’URI SIP mondial sip:$PROJECT_ID@sip.api.openai.com;transport=tls ou utilisez l’un des points de terminaison régionaux suivants :
    • Pour la résidence des données en Europe, utilisez sip:$PROJECT_ID@sip-eu.api.openai.com;transport=tls.
    • Pour les hôtes SIP physiquement situés en Inde, utilisez sip:$PROJECT_ID@sip-in.api.openai.com;transport=tls.

Avant de suivre cette procédure, vérifiez que la prise en charge de SIP par GPT-Live est activée pour votre projet et que le trunk SIP de votre opérateur achemine les appels vers ce projet.

Recevez l’appel entrant

Lorsqu’OpenAI reçoit un appel destiné à votre projet, il envoie un événement live.transport.incoming au point de terminaison de votre webhook. Vérifiez la signature du webhook et dédupliquez les notifications reçues, puis acceptez ou rejetez l’appel.

Le webhook identifie un appel SIP par data.type: "sip" et fournit data.session_id. Utilisez cet identifiant de session tel quel pour chaque action sur l’appel Live. Traitez data.sip_headers comme des métadonnées non fiables fournies par l’appelant. Ne les utilisez pas pour accorder une autorisation.

Voici un exemple de corps de webhook :

{
  "object": "event",
  "id": "evt_abc123",
  "type": "live.transport.incoming",
  "created_at": 1750287018,
  "data": {
    "type": "sip",
    "session_id": "live_123",
    "sip_headers": [
      { "name": "From", "value": "sip:+14155550123@sip.example.com" },
      { "name": "To", "value": "sip:+18005550100@sip.example.com" },
      { "name": "Call-ID", "value": "call-123@example.com" }
    ]
  }
}

Le champ created_at contient un horodatage Unix exprimé en secondes. Parmi les en-têtes du webhook, webhook-id permet de dédupliquer les notifications, webhook-timestamp indique l’heure de la tentative d’envoi et webhook-signature permet de vérifier la signature. Consultez les exemples de vérification des webhooks pour voir comment effectuer cette vérification côté serveur.

Les intégrations existantes peuvent encore recevoir l’événement obsolète live.call.incoming, qui ne contient pas de champ data.type. Pendant la migration, gérez les deux noms d’événement et conservez l’ancien abonnement jusqu’à ce que toutes les livraisons et tentatives de renvoi de l’ancien événement soient terminées. Un même appel en attente peut aussi déclencher un webhook Realtime. Confiez la décision d’accepter ou de rejeter l’appel à un seul gestionnaire pour éviter de l’accepter via les deux API.

Acceptez ou rejetez l’appel

Appliquez les règles d’autorisation et de routage de votre application. Pour accepter l’appel, envoyez une requête authentifiée POST /v1/live/sessions/{session_id}/accept avec un objet session à la racine :

{
  "session": {
    "type": "live",
    "model": "gpt-live-1",
    "instructions": "You are answering an inbound support call.",
    "audio": { "output": { "voice": "marin" } },
    "delegation": { "type": "client" }
  }
}

Utilisez Authorization: Bearer $OPENAI_API_KEY depuis votre backend de confiance pour les requêtes de contrôle d’appel. Choisissez la voix et le mode de délégation au moment d’accepter l’appel. SIP négocie le format audio, donc omettez audio.format. L’exemple utilise la délégation au client. Votre backend doit donc prendre en charge les tâches déléguées. Consultez la section Délégation et outils pour connaître les configurations de délégation au client et à Responses.

Si l’appel est accepté, l’API renvoie 200 OK avec un corps vide après l’initialisation de la session. Traitez les erreurs HTTP avant de considérer l’appel comme accepté.

Pour rejeter l’appel, envoyez POST /v1/live/sessions/{session_id}/reject avec un code d’état SIP, par exemple { "status_code": 486 } pour indiquer que la ligne est occupée. Le code doit être un entier compris entre 300 et 699 inclus. La première décision d’acceptation ou de rejet prévaut. Pour toute requête concurrente reçue ensuite, l’API renvoie decision_already_made.

Rattachez votre backend à la session

Une fois l’appel accepté, ouvrez une connexion WebSocket auxiliaire à l’adresse wss://api.openai.com/v1/live/sessions/{session_id}/attach. Utilisez l’identifiant de la session acceptée ainsi que les mêmes en-têtes d’authentification du projet et de connexion. Ne renvoyez pas session.start.

SIP transporte l’audio de l’appel. Utilisez la connexion auxiliaire pour les transcriptions, la délégation, les outils, les commandes et la copie du flux audio. Confiez chaque action ayant un effet de bord à un seul gestionnaire, même si plusieurs connexions reçoivent le même événement.

Une fois la connexion établie, utilisez les commandes d’appel en cours pour envoyer des tonalités de clavier, transférer l’appel ou raccrocher.

Passez un appel sortant

Appelez un numéro de téléphone via votre opérateur SIP avec l’opération Créer une session. Votre opérateur gère la connexion au réseau téléphonique et GPT-Live assure la conversation.

Toutes les organisations peuvent passer des appels SIP sortants via l’API Live. Le point de terminaison de création d’appels de Realtime API ne les prend pas en charge.

Configurez votre trunk SIP

Utilisez un trunk qui prend en charge la signalisation TLS et le transport des flux multimédias avec SDES-SRTP. Activez SRTP dans les paramètres de votre opérateur avant de passer un appel.

Fournissez la configuration du trunk à chaque requête :

Champ Valeur
transport.destination Numéro de téléphone à appeler au format E.164, par exemple +14155550123. Les destinations sous forme d’URI SIP ne sont pas prises en charge.
transport.trunk.provider_url Point de terminaison de l’opérateur, par exemple sips:sip.example.com:5061. Le port par défaut est 5061. Le paramètre ;transport=tcp est facultatif.
transport.trunk.auth.type digest pour l’authentification SIP Digest.
transport.trunk.auth.username Nom d’utilisateur SIP fourni par votre opérateur.
transport.trunk.auth.password Mot de passe SIP fourni par votre opérateur.
transport.trunk.caller_number Numéro de téléphone de l’appelant à transmettre à votre opérateur, au format E.164.

Le point de terminaison de l’opérateur doit utiliser sips: pour la signalisation TLS. N’incluez ni identifiants, ni chemins, ni en-têtes d’URI, ni autres paramètres d’URI dans l’URL. Les noms d’hôtes locaux et les adresses IP privées ou locales indiquées sous forme littérale sont rejetés. Conservez votre clé API OpenAI et vos identifiants SIP sur votre serveur.

Créez la session

Envoyez POST /v1/live/sessions avec la configuration de votre session et transport.type: "sip". Choisissez la voix et le mode de délégation lors de la création de la session. Omettez audio.format, car SIP négocie le format audio.

Cet exemple utilise curl et jq. Définissez OPENAI_API_KEY, SIP_USERNAME et SIP_PASSWORD dans l’environnement de votre serveur, puis remplacez le point de terminaison de l’opérateur et les numéros de téléphone de l’exemple par vos propres valeurs. L’exemple utilise la délégation au client. Votre backend doit donc prendre en charge les tâches déléguées.

jq -n \
  --arg username "$SIP_USERNAME" \
  --arg password "$SIP_PASSWORD" \
  '{
    "session": {
      "model": "gpt-live-1",
      "instructions": "Help the user schedule an appointment.",
      "audio": { "output": { "voice": "marin" } },
      "delegation": { "type": "client" }
    },
    "transport": {
      "type": "sip",
      "destination": "+14155550123",
      "trunk": {
        "provider_url": "sips:sip.example.com:5061",
        "auth": {
          "type": "digest",
          "username": $username,
          "password": $password
        },
        "caller_number": "+14155550100"
      }
    }
  }' | curl https://api.openai.com/v1/live/sessions \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H "Content-Type: application/json" \
    --data-binary @-

Une fois la session initialisée, la requête renvoie 200 OK :

{
  "session": { "id": "live_123" },
  "transport": { "type": "sip" }
}

Cette réponse ne signifie pas que le correspondant a décroché. Elle ne contient ni SDP ni identifiants du trunk. Conservez session.id tel quel pour la connexion auxiliaire et les commandes de contrôle d’appel. Un appel sortant ne nécessite ni webhook d’appel entrant ni requête d’acceptation.

Suivez l’appel et raccrochez

Connectez votre backend à wss://api.openai.com/v1/live/sessions/{session_id}/attach avec votre clé API OpenAI. Ne renvoyez pas session.start. La connexion auxiliaire transmet les événements de conversation, les tâches déléguées et les événements de progression de l’appel, tandis que SIP transporte l’audio.

Événement Signification
transport.ringing L’opérateur signale que le téléphone sonne ou qu’un flux multimédia est transmis avant le décrochage.
transport.answered Le correspondant a décroché et le flux multimédia est établi.
transport.failed L’établissement de l’appel a échoué après l’initialisation de la session. Examinez error.code et error.message.

Chaque événement de progression de l’appel contient event_id et session_id. Ouvrez la connexion auxiliaire dès la création de la session. Elle ne retransmet que les événements des 3 dernières secondes. Si vous vous connectez plus tard, vous risquez de manquer les premiers événements. Les événements retransmis conservent leur identifiant d’origine. Dédupliquez-les à l’aide de event_id.

Une fois la connexion établie, utilisez les commandes d’appel en cours pour envoyer des tonalités de clavier, transférer l’appel ou raccrocher. Gardez la connexion auxiliaire ouverte pour recevoir session.closed et le bilan de consommation, comme indiqué dans la section Consommation et fermeture propre.

Gérez les limites et les erreurs

La sonnerie est limitée à 3 minutes et un appel établi peut durer jusqu’à 2 heures. Ces limites ne sont pas configurables dans la requête de création.

Si la configuration de la session est invalide, l’API signale l’erreur dans la réponse à la requête de création. Un échec de mise en place du transport peut renvoyer 502. Un dépassement du délai d’initialisation renvoie 504. Après la création de la session, surveillez transport.failed pour détecter les échecs asynchrones d’établissement de l’appel.

Gérez un appel en cours

Ces commandes s’appliquent aux appels SIP entrants et sortants.

Envoyez et recevez des événements de clavier téléphonique

La connexion auxiliaire reçoit transport.dtmf.received lorsque l’appelant appuie sur une touche. Pour transmettre une tonalité DTMF au trunk SIP, envoyez un événement client transport.dtmf.send via la connexion WebSocket auxiliaire. Une fois la tonalité envoyée, la connexion auxiliaire reçoit transport.dtmf.sent.

Si vous fournissez un event_id, la notification le reprend dans client_event_id. En cas d’échec, vous recevez un événement error contenant error.client_event_id.

Transférez l’appel ou raccrochez

Pour transférer l’appel, envoyez POST /v1/live/sessions/{session_id}/refer en indiquant la destination sous la forme { "target_uri": "sip:agent@example.com" }. Pour raccrocher, envoyez POST /v1/live/sessions/{session_id}/hangup sans corps de requête. En cas de succès, les deux requêtes renvoient 200 OK avec un corps vide.

La destination du transfert devient la valeur de l’en-tête SIP Refer-To. Elle peut prendre la forme d’un URI téléphonique comme tel:+14155550123 ou d’un URI SIP comme sip:agent@example.com. Votre opérateur se charge de la suite du transfert.

Gardez la connexion auxiliaire ouverte jusqu’à ce que session.closed fournisse le bilan de consommation de la session. Consultez la section Consommation et fermeture propre pour en savoir plus sur les données de consommation et les motifs de fermeture.

Configuration réseau requise pour SIP

Les appels SIP de GPT-Live utilisent des chemins réseau distincts pour la signalisation et les flux multimédias. Configurez votre réseau pour autoriser les deux types de trafic :

  • Signalisation SIP : sip.api.openai.com et sip-eu.api.openai.com sont des points de terminaison dont le routage repose sur GeoIP. Le point de terminaison pour l’Inde, sip-in.api.openai.com, achemine le trafic vers des hôtes SIP situés en Inde. Autorisez le trafic TCP/TLS sortant sur le port 5061 vers les adresses renvoyées par le DNS pour le point de terminaison choisi.
  • Flux multimédias SRTP : dans le SDP négocié, l’API indique une adresse IP distincte pour les flux multimédias ainsi qu’un port UDP. Autorisez le trafic SRTP sur UDP dans les deux sens pour les plages CIDR suivantes :
    • 13.79.45.80/28
    • 20.204.17.112/28
    • 23.98.140.64/28
    • 40.67.149.176/28
    • 40.83.204.240/28

Prochaines étapes avec GPT-Live