Format de réponse : id, choices et finish_reason
Mis à jour le 30 juillet 2026
Anatomie d’une réponse Chat Completions
Chaque appel à l’endpoint Chat Completions retourne un objet JSON structuré avec des champs standardisés. Comprendre cette structure est essentiel pour extraire correctement les données, gérer les cas limites et déboguer vos intégrations.

Structure complète de la réponse
Voici un exemple de réponse typique retournée par l’API :
{
"id": "chatcmpl-abc123xyz",
"object": "chat.completion",
"created": 1712345678,
"model": "grok-4.20-0309-reasoning",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Le deep learning est une branche du machine learning..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 42,
"completion_tokens": 156,
"total_tokens": 198
},
"system_fingerprint": "fp_abc123"
}
Les champs de premier niveau
id: identifiant unique de la complétion (formatchatcmpl-...). Utile pour le suivi et le débogage.object: toujours"chat.completion". Permet de distinguer ce type de réponse d’autres endpoints.created: timestamp Unix de la création de la réponse.model: le modèle qui a génère la réponse. Peut différer légèrement du modèle demande si vous utilisez un alias.choices: tableau contenant la où les réponses générées.usage: compteurs de tokens pour la facturation.system_fingerprint: empreinte de la configuration système utilisée.
Le tableau choices
Le champ choices est un tableau qui contient généralement un seul élément (index 0). Chaque élément possède :
index: position dans le tableau (commence à 0)message: objet avecrole(toujours"assistant") etcontent(le texte génère)finish_reason: la raison pour laquelle la génération s’est arretee
Pour extraire la réponse textuelle :
# Python
reponse_texte = response.choices[0].message.content
// JavaScript
const reponseTexte = response.choices[0].message.content;
Les valeurs de finish_reason
Le champ finish_reason est crucial pour comprendre pourquoi le modèle à arrête de générer du texte :
stop
"finish_reason": "stop"
Le modèle a terminé sa réponse naturellement. C’est le cas le plus courant et le plus souhaitable : le modèle a dit tout ce qu’il avait à dire.
length
"finish_reason": "length"
La génération a été interrompue parce que max_tokens a été atteint. La réponse est donc tronquée. Vous devez soit augmenter max_tokens, soit faire une requête de continuation.
tool_calls
"finish_reason": "tool_calls"
Le modèle souhaité appeler un outil (function calling). Au lieu de générer du texte, il a produit un appel de fonction que votre application doit exécuter avant de renvoyer le résultat.
content_filter
"finish_reason": "content_filter"
La génération a été bloquée par les filtres de sécurité de xAI. Le contenu demande ou généré a été juge inapproprié. Le champ content peut être vide ou partiellement rempli.
Gérer les différents cas
En production, vous devez vérifier finish_reason pour adapter votre comportement :
choice = response.choices[0]
if choice.finish_reason == "stop":
# Réponse complete — afficher normalement
print(choice.message.content)
elif choice.finish_reason == "length":
# Réponse tronquée — prévenir l'utilisateur ou continuer
print(choice.message.content)
print("[Réponse tronquee — augmentez max_tokens]")
elif choice.finish_reason == "tool_calls":
# Le modèle veut appeler un outil
for tool_call in choice.message.tool_calls:
print(f"Outil demande : {tool_call.function.name}")
elif choice.finish_reason == "content_filter":
# Contenu filtre
print("La reponse a été bloquée par les filtres de securite.")
Points clés à retenir
- La réponse contient un
idunique, un tableauchoiceset un objetusage - Le texte généré se trouve dans
choices[0].message.content finish_reasonindique pourquoi la génération s’est arretee :stop,length,tool_callsoucontent_filter- Vérifiez toujours
finish_reasonen production pour gérer les réponses tronquées ou filtrées - Le
system_fingerprintidentifie la configuration système utilisée pour la génération