Comment utiliser l'API OpenAI Décisions ?

Comment utiliser l'API Decisions d'OpenAI : premier appel en curl, Python et JavaScript, réponses de prédicat, de choix et de score, entrée d'image et tests Apidog.

Ashley Innocent

Ashley Innocent

10 October 2026

Comment utiliser l'API OpenAI Décisions ?

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Découvrir Apidog Enterprise

Pour utiliser l'API Decisions d'OpenAI, envoyez une requête POST à https://api.openai.com/v1/decisions avec "model": "gpt-6-luna", une input (texte, images, ou les deux), et un tableau questions où chaque question est un predicate, un choice ou un score. Vous recevez des réponses typées avec des probabilités au lieu de texte à analyser, et vous payez 0,10 $ par million de tokens d'entrée, sans frais de sortie, de lecture ou d'écriture de cache. Le point de terminaison est en bêta publique à partir du 6 octobre 2026.

Ce guide couvre l'obtention d'une clé, le premier appel en curl, Python et JavaScript, la lecture de chaque type de réponse, trois questions sur un seul ticket de support, l'entrée d'images, les seuils et une configuration de test dans Apidog. Pour savoir quand choisir ce point de terminaison, commencez par qu'est-ce que l'API Decisions d'OpenAI.

button

Vue d'ensemble de la requête de l'API Decisions

Champ Ce qu'il accepte
model gpt-6-luna (le seul modèle disponible en bêta)
input Une chaîne de caractères, ou un tableau de messages user dont le content est une chaîne de caractères ou des parties de type input_text et input_image
questions[].type predicate, choice, ou score
questions[].instructions Obligatoire ; la question en mots simples
questions[].name Facultatif ; renvoyé dans la réponse (null si omis)
questions[].choices Uniquement pour choice ; 2 à 255 objets {value, description} uniques, value étant une chaîne de caractères ou un booléen
questions[].levels Uniquement pour score ; objets {label, description} ordonnés, du plus bas au plus haut, indices à partir de 0
safety_identifier ID opaque facultatif de l'utilisateur final, jusqu'à 128 caractères

Source : la référence de l'API Decisions. Il n'y a pas de temperature, stream, tools ou text.format sur ce point de terminaison.

Obtenir une clé et faire le premier appel

Créez une clé dans le tableau de bord d'OpenAI (le guide des clés API OpenAI le couvre), exportez-la en tant que OPENAI_API_KEY et ne la collez jamais dans le code. Posez ensuite une question oui/non :

curl https://api.openai.com/v1/decisions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-luna",
    "input": "The box arrived crushed and the screen is cracked.",
    "questions": [
      {"type": "predicate", "name": "damaged",
       "instructions": "Does the customer report a damaged item?"}
    ]
  }'

La réponse contient trois champs de premier niveau : model, answers et usage. C'est la structure de la référence d'OpenAI, avec output_tokens à 0 car le point de terminaison ne facture aucune sortie :

{
  "model": "gpt-6-luna",
  "answers": [
    {"type": "predicate", "name": "damaged", "probability": 0.95}
  ],
  "usage": {
    "input_tokens": 42,
    "input_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0},
    "output_tokens": 0,
    "output_tokens_details": {"reasoning_tokens": 0},
    "total_tokens": 42
  }
}

Le même appel en Python (SDK 3.26.0 ou ultérieur) :

from openai import OpenAI

client = OpenAI()  # reads OPENAI_API_KEY from the environment

decision = client.decisions.create(
    model="gpt-6-luna",
    input="The box arrived crushed and the screen is cracked.",
    questions=[
        {"type": "predicate", "name": "damaged",
         "instructions": "Does the customer report a damaged item?"}
    ],
)
print(decision.answers[0].probability)

Et en JavaScript (SDK 7.30.0 ou ultérieur) :

import OpenAI from "openai";

const client = new OpenAI();

const decision = await client.decisions.create({
  model: "gpt-6-luna",
  input: "The box arrived crushed and the screen is cracked.",
  questions: [
    { type: "predicate", name: "damaged",
      instructions: "Does the customer report a damaged item?" },
  ],
});
console.log(decision.answers[0].probability);

Lire la réponse par type

Les réponses reviennent dans l'ordre de vos questions, chacune avec un type. Utilisez le type, car toute question peut revenir comme un refusal (refus).

for a in decision.answers:
    if a.type == "refusal":
        send_to_review(a.name)
    elif a.type == "predicate":
        flag = a.probability > 0.9
    elif a.type == "choice":
        route = a.choice if a.confidence > 0.8 else "review"
    elif a.type == "score":
        priority = round(a.score)

Le guide d'OpenAI établit la distinction ainsi : choice pour les catégories sans ordre, comme les départements ; score pour les niveaux ordonnés, comme la gravité.

Trois questions sur un seul ticket de support

Les questions indépendantes partagent une requête et une seule input, et chaque question peut utiliser un type différent. Voici un prédicat, un choix et un score sur un seul ticket :

{
  "model": "gpt-6-luna",
  "input": "I was charged twice for my order.",
  "questions": [
    {"type": "predicate", "name": "refund_requested",
     "instructions": "Is the customer asking for money back?"},
    {"type": "choice", "name": "department",
     "instructions": "Which team should handle this ticket?",
     "choices": [
       {"value": "billing", "description": "Charges, refunds, invoices"},
       {"value": "technical", "description": "Bugs and errors in the product"},
       {"value": "shipping", "description": "Delivery and tracking"},
       {"value": "other", "description": "Anything else"}
     ]},
    {"type": "score", "name": "urgency",
     "instructions": "How urgent is this ticket?",
     "levels": [
       {"label": "low", "description": "No time pressure"},
       {"label": "medium", "description": "Needs a reply this week"},
       {"label": "high", "description": "Customer is blocked or losing money"}
     ]}
  ]
}

Le tableau answers revient dans le même ordre. Les valeurs choice ci-dessous sont les valeurs de référence d'OpenAI pour cette entrée exacte ; les valeurs de prédicat et de score sont illustratives :

"answers": [
  {"type": "predicate", "name": "refund_requested", "probability": 0.88},
  {"type": "choice", "name": "department", "choice": "billing",
   "probabilities": [
     {"value": "billing", "probability": 0.95},
     {"value": "technical", "probability": 0.02},
     {"value": "shipping", "probability": 0.01},
     {"value": "other", "probability": 0.02}
   ],
   "confidence": 0.93},
  {"type": "score", "name": "urgency", "score": 1.6,
   "probabilities": [
     {"value": 0, "label": "low", "probability": 0.05},
     {"value": 1, "label": "medium", "probability": 0.30},
     {"value": 2, "label": "high", "probability": 0.65}
   ],
   "confidence": 0.65}
]

Deux règles du guide : incluez une option de repli telle que other lorsque vos catégories ne couvrent pas toutes les entrées, et formulez les questions autour de critères observables afin que les niveaux de score adjacents signifient des choses différentes. Si une deuxième décision dépend de la première réponse, envoyez une requête séparée.

Entrée d'image

Passez une image comme partie de contenu à l'intérieur d'un message user. Le guide documente les URL de données base64 en ligne :

{
  "model": "gpt-6-luna",
  "input": [{
    "role": "user",
    "content": [
      {"type": "input_text", "text": "Photo attached to a return request."},
      {"type": "input_image", "image_url": "data:image/jpeg;base64,/9j/4AAQ..."}
    ]
  }],
  "questions": [
    {"type": "predicate", "name": "visible_damage",
     "instructions": "Is the product visibly damaged?"}
  ]
}

La référence de l'API liste également les URL HTTP(S) accessibles publiquement, jusqu'à 128 images dans tous les messages d'une requête, et un champ detail facultatif (low, high, auto, original). Testez donc les URL hébergées avec votre propre compte avant de vous y fier. Les entrées file_id ne sont prises en charge sur aucune des pages.

Choisir des seuils à partir d'exemples étiquetés

OpenAI ne publie aucune donnée de précision ou de calibration pour ce point de terminaison. Ses recommandations sont d'utiliser des exemples étiquetés de votre propre application pour définir des seuils de routage, de filtrage ou de révision, en fonction du coût des faux positifs par rapport aux faux négatifs. En pratique, cela signifie un petit fichier CSV de tickets réels avec le département choisi par un humain, traités par la même requête, afin que vous puissiez voir où la confidence sépare les routes claires de celles qui nécessitent une intervention humaine. La section suivante construit cette boucle.

Tester l'API Decisions dans Apidog

Les requêtes sauvegardées rendent l'ajustement des seuils et les vérifications de régression reproductibles. Voici la configuration dans Apidog :

  1. Stockez la clé comme variable d'environnement. Créez un environnement, ajoutez OPENAI_API_KEY comme variable secrète (Environnements et variables secrètes Apidog montre la configuration), et définissez l'en-tête Authorization à Bearer {{OPENAI_API_KEY}}. La clé n'atterrit jamais dans le corps d'une requête partagée.
  2. Sauvegardez une requête par type de question. Créez une requête POST vers https://api.openai.com/v1/decisions avec Content-Type: application/json, collez la question de type choice de l'exemple de ticket ci-dessus seule, et sauvegardez-la. Dupliquez-la pour les versions prédicat et score.
  3. Ajoutez des assertions JSONPath. Sur la requête de type `choice` : le statut est 200, `$.answers[0].type` est égal à `choice`, `$.answers[0].choice` est égal à `billing`, `$.answers[0].confidence` est supérieur à 0.8, et `$.usage.output_tokens` est égal à 0. Pour le prédicat de dommage, affirmez que `$.answers[?(@.name=='damaged')].probability` est supérieur à 0.9. Un changement de formulation dans vos instructions, ou un changement de comportement du modèle, fera désormais échouer un test au lieu de mal acheminer les tickets.
  4. Exécutez-le sur des tickets étiquetés. Construisez un scénario de test à partir de la requête sauvegardée et attachez un petit fichier CSV avec deux colonnes, ticket_text et expected_department. Mappez {{ticket_text}} dans input et affirmez que $.answers[0].choice est égal à {{expected_department}}. Le rapport d'exécution affiche la confidence pour chaque ligne, ce sont les données qu'OpenAI vous dit d'utiliser pour définir les seuils. Le point en dessous duquel chaque erreur de routage se situe devient votre seuil de "routage automatique" dans le code.
  5. Simulez le tableau answers pour le frontend. Orientez le routeur ou l'interface utilisateur vers une simulation du même point de terminaison qui renvoie une réponse choice avec une confidence supérieure et inférieure à votre seuil, plus un refusal, afin que le chemin de la file d'attente de révision soit construit avant que vous ne dépensiez un token d'entrée. Les réponses de simulation conditionnelles dans Apidog couvrent la commutation des simulations en fonction du contenu de la requête.
  6. Exécutez le scénario en CI. Exportez un jeton d'accès, puis ajoutez une étape à votre pipeline :
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
  -t "$SCENARIO_ID" -e "$ENV_ID" -r cli,junit

Une assertion échouée fait échouer la build, donc une baisse silencieuse de la confidence est détectée avant le déploiement plutôt que dans la file d'attente du support. Pour des modèles plus larges, consultez le test des applications LLM.

Gérer les erreurs et les cas limites

FAQ

Combien coûte l'API Decisions ? 0,10 $ par million de tokens d'entrée sur gpt-6-luna, sans frais de sortie, de lecture ou d'écriture de cache. Un ticket de 500 tokens avec trois questions coûte 500 / 1 000 000 x 0,10 $ = 0,00005 $, donc un million de ces tickets coûte 50 $. Une entrée de contexte long de plus de 272K tokens est 2 fois plus chère, et le traitement régional ajoute 10 %.

L'API Decisions est-elle gratuite ? Non. Il n'y a pas de niveau gratuit pour Decisions. Si vous souhaitez essayer GPT-6 Luna sans payer, l'article Routes gratuites de GPT-6 Luna liste ce qui existe.

Quelle est sa rapidité ? OpenAI indique qu'elle est environ 10 fois plus rapide que l'API Responses et ne publie aucun chiffre de latence absolu. Un développeur sur le forum OpenAI a signalé des décisions d'image en environ 0,8 seconde.

Quels modèles fonctionnent avec l'API Decisions ? Seulement gpt-6-luna aujourd'hui. C'est un point de terminaison sur Luna, pas un modèle séparé. Voir qu'est-ce que GPT-6 Luna pour le modèle lui-même.

Quand devrais-je utiliser les sorties structurées à la place ? Lorsque vous avez besoin d'un objet dans votre propre schéma JSON, comme des champs extraits ou une explication écrite, ou l'appel de fonction lorsque le modèle doit demander un outil avec des arguments. L'article API Decisions vs API Responses montre le même ticket traité des deux manières.

Comment se compare-t-elle à Jev ? Les deux renvoient des réponses typées avec des probabilités et ne facturent que l'entrée ; Jev est textuel uniquement à 0,042 $ par million. La comparaison API Decisions vs Jev contient le tableau complet.

Prochaine étape

Envoyez la requête de ticket à trois questions de ce guide, puis exécutez-la sur 20 de vos propres tickets étiquetés et voyez où la confidence sépare les routes correctes des mauvaises. Ensuite, téléchargez Apidog pour conserver ensemble la requête, le scénario CSV et les assertions, afin que le seuil que vous choisissez aujourd'hui soit revérifié à chaque déploiement.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API