Chat
Complétions de chat
L’API Chat Completions d’OpenAI, pour tous les modèles de texte : mêmes requêtes et réponses, même streaming, mêmes SDK.
/v1/chat/completionsRequête
modelstringrequis- Un identifiant de modèle de la page des modèles, comme
claude-opus-5-5ougpt-6-sol. messagesarrayrequis- La conversation : des messages
system(oudeveloper),user,assistantettool.contentest une chaîne de caractères, ou un tableau de parties pour ajouter des images, PDF, contenus audio ou vidéos. streamboolean- Envoyez la réponse sous forme de server-sent events à mesure qu’elle est générée. Voir Streaming ci-dessous.
stream_optionsobject{ "include_usage": true }ajoute un dernier fragment contenant l’utilisation des tokens.max_completion_tokensinteger- Le nombre maximal de tokens à générer, raisonnement compris.
max_tokensfonctionne aussi. temperaturenumber- De 0 à 2. Une valeur basse donne des réponses plus ciblées, une valeur haute des réponses plus variées. Certains modèles de raisonnement l’ignorent. Claude à partir d’Opus 4.7 (Opus 5 et 5.5, Fable 5 et 5.1, Sonnet 5.5, Haiku 5.5) ne l’accepte pas, nous l’omettons donc pour ces modèles.
top_pnumber- Échantillonnage par noyau, de 0 à 1. Modifiez ce paramètre ou temperature, pas les deux. Omis pour les mêmes modèles Claude, tout comme top_k pour ces modèles et pour Muse Wonder.
stopstring | array- Jusqu’à 4 séquences qui arrêtent la génération.
toolsarray- Les fonctions que le modèle peut appeler. Voir Appel d’outils ci-dessous.
tool_choicestring | objectauto,none,required, ou une fonction précise. Lorsque le fournisseur du modèle refuse ou ignore une option (un outil imposé sur Claude Opus 5.5, Sonnet 5.5 et Fable 5.1 ; toute option autre queautosur Muse Wonder ;nonesur certains modèles Gemini, DeepSeek Flash, MiMo, HY4 et MiniMax), nous la transmettons sous une forme que le modèle respecte et lui indiquons votre demande ; si une fonction est imposée par son nom, elle est la seule proposée.response_formatobject- Sortie JSON :
{ "type": "json_object" }, oujson_schemaavec un schéma. Voir Sortie structurée ci-dessous. reasoning_effortstring- L’effort de réflexion d’un modèle de raisonnement :
none,minimal,low,medium,high,xhighoumax. Chaque modèle accepte certains de ces niveaux (voir Raisonnement ci-dessous) ; tout autre niveau est ramené au niveau accepté le plus proche. Un niveau plus élevé prolonge la réflexion et consomme davantage de tokens de sortie. seedinteger- Reproductibilité dans la mesure du possible, pour les modèles qui la prennent en charge.
modelsarray- Routage intelligent pour cette requête : les modèles de remplacement à essayer, dans l’ordre, si le modèle est indisponible. Voir Routage intelligent.
user et metadata, qui restent de notre côté. Les paramètres respectés (outils, schémas JSON, raisonnement) dépendent du modèle, comme lorsque vous passez directement par son fournisseur. Avec le SDK Python OpenAI, envoyez models sous la forme extra_body={"models": [...]}.Réponse
{ "id": "chatcmpl-AbC123...", "object": "chat.completion", "created": 1790870400, "model": "claude-opus-5-5", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Here's the summary..." }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 1204, "completion_tokens": 312, "total_tokens": 1516, "prompt_tokens_details": { "cached_tokens": 1024 }, "completion_tokens_details": { "reasoning_tokens": 128 } }}modelest le modèle qui a répondu. C’est celui que vous avez demandé, sauf si le routage intelligent a fait appel à un autre modèle.- Les modèles de raisonnement peuvent ajouter
reasoning_contentau message : il contient le raisonnement du modèle, lorsque celui-ci le partage. usagecorrespond à ce qui vous est facturé.cached_tokenscorrespond aux tokens d’entrée lus dans le cache de prompts du modèle, facturés au tarif de mise en cache si le modèle en propose un.
Chaque réponse contient aussi ces en-têtes :
Streaming
Avec stream: true, la réponse arrive sous forme de server-sent events au format de fragments d’OpenAI, et se termine par data: [DONE]. Chaque SDK les lit pour vous.
import osfrom openai import OpenAIclient = OpenAI( base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"],)stream = client.chat.completions.create( model="claude-sonnet-5-5", messages=[ { "role": "user", "content": "Write a limerick about databases." } ], stream=True, stream_options={ "include_usage": True },)for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True)- Aucune réponse n’est envoyée avant que le modèle ait produit son premier token : une nouvelle tentative ou un changement de voie reste donc invisible pour vous.
- Pendant les périodes sans activité (quand un modèle réfléchit entre deux étapes), des lignes de commentaire SSE (
: keep-alive) sont envoyées toutes les 15 secondes. Les clients les ignorent ; elles empêchent les proxys de fermer la connexion. Si le premier token prend plus de 20 secondes (prompt long, ou voie bloquée en cours de remplacement), le flux s’ouvre à ce moment-là : les en-têtes et les commentaires de maintien de connexion arrivent pendant que vous attendez. Chaque voie dispose de 3 minutes pour démarrer (5 avec un effort de raisonnement élevé) avant de passer à la suivante ; réglez donc le délai d’expiration de votre client sur 10 minutes. - Un flux ouvert avant son premier token ne contient
x-zurelay-modelque si aucun autre modèle ne peut répondre (routage intelligent désactivé), et toute erreur survenant après son ouverture arrive sous forme d’événement d’erreur dans le flux (au même format que le corps d’une réponse d’erreur), plutôt qu’avec un statut d’erreur. - Avec
include_usage, le dernier fragment avant[DONE]contient une listechoicesvide etusage.
Appel d’outils
Décrivez les fonctions dans tools ; lorsque le modèle souhaite en appeler une, il répond avec tool_calls au lieu de texte. Exécutez la fonction, renvoyez le résultat dans un message tool avec l’ID de l’appel, et le modèle poursuit.
import osfrom openai import OpenAIclient = OpenAI( base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"],)response = client.chat.completions.create( model="gpt-6-sol", messages=[ { "role": "user", "content": "What's the weather in Lisbon right now?" } ], tools=[ { "type": "function", "function": { "name": "get_weather", "description": "Current weather for a city", "parameters": { "type": "object", "properties": { "city": { "type": "string" } }, "required": [ "city" ] } } } ],)print(response.choices[0].message.content)Sortie structurée
Demandez du JSON avec response_format. Un json_schema impose votre schéma aux modèles qui le prennent en charge ; json_object demande n’importe quel JSON valide (précisez-le aussi dans votre prompt).
import osfrom openai import OpenAIclient = OpenAI( base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"],)response = client.chat.completions.create( model="gpt-6.1-sol", messages=[ { "role": "user", "content": "Extract the people: 'Ana met Ben and Chloe in Porto.'" } ], response_format={ "type": "json_schema", "json_schema": { "name": "people", "schema": { "type": "object", "properties": { "names": { "type": "array", "items": { "type": "string" } } }, "required": [ "names" ] } } },)print(response.choices[0].message.content)Raisonnement
Les modèles de raisonnement réfléchissent avant de répondre. Réglez reasoning_effort pour trouver le bon équilibre entre vitesse, coût et profondeur : un niveau plus élevé prolonge la réflexion, prend plus de temps et consomme davantage de tokens de sortie. Chaque modèle accepte les niveaux documentés par son fournisseur, de none (sans réflexion) à max, en passant par minimal, low, medium, high et xhigh (très élevé) ; le tableau ci-dessous les répertorie. Si vous omettez ce paramètre, le modèle utilise son réglage par défaut. Il fonctionne de la même façon avec tous les SDK OpenAI, et vous pouvez essayer chaque niveau dans le Playground du tableau de bord.
from openai import OpenAIclient = OpenAI(base_url="https://api.zurelay.com/v1", api_key="YOUR_ZURELAY_KEY")response = client.chat.completions.create( model="zurelay-auto", reasoning_effort="high", messages=[{"role": "user", "content": "How many primes are there below 1,000?"}],)message = response.choices[0].messageprint(getattr(message, "reasoning_content", None)) # the thinking, when the model shares itprint(message.content)Le raisonnement est renvoyé avec la réponse dans message.reasoning_content (en streaming, dans delta.reasoning_content) pour les modèles qui le partagent ; certains nomment ce champ reasoning. Il est facturé comme des tokens de sortie et fait toujours partie de completion_tokens ; completion_tokens_details.reasoning_tokens le comptabilise séparément quand le modèle fournit ce détail. À un niveau d’effort élevé, la réponse peut mettre plusieurs minutes à démarrer : prévoyez donc un délai d’expiration généreux côté client (voir Fiabilité et délais d’expiration).
Niveaux par modèle
Ces niveaux proviennent de la documentation de chaque labo. Si un modèle n’accepte pas le niveau demandé, il utilise le plus proche parmi ceux qu’il accepte (en cas d’égalité, le plus bas ; le raisonnement ne se désactive que si vous envoyez none). Une même requête fonctionne ainsi sur tous les modèles, y compris avec le routage intelligent. L’en-tête de réponse x-zurelay-reasoning-effort indique le niveau utilisé. Un mot qui ne correspond à aucun niveau est refusé avec une erreur 400 qui liste les niveaux du modèle.
Le raisonnement de Claude
Sur cet endpoint, Claude accepte reasoning_effort comme tout autre modèle : low, medium, high, xhigh ou max (Opus 4.6 ne propose pas xhigh). Dans le format natif d’Anthropic, Claude adapte son raisonnement au niveau choisi : envoyez thinking: { type: "adaptive", display: "summarized" } avec output_config: { effort: "xhigh" } et lisez les blocs de raisonnement. Voir Anthropic Messages.
Une question ou un élément manquant ? Contactez notre équipe d’assistance et nous vous répondrons par e-mail, généralement en moins d’une minute.