DEV Community

Cover image for Comment utiliser l'API Batch OpenAI
Antoine Laurent
Antoine Laurent

Posted on • Originally published at apidog.com

Comment utiliser l'API Batch OpenAI

À la fin de ce guide, vous saurez utiliser l’API de lot d’OpenAI (Batch API) pour exécuter des milliers de requêtes de modèle dans une tâche asynchrone unique, récupérer les résultats et réduire le coût des jetons de 50 %. Vous préparerez un fichier JSONL, téléverserez ce fichier, créerez un lot, interrogerez son état, téléchargerez la sortie, puis testerez le flux dans Apidog avant de l’automatiser. Si votre cas d’usage est interactif, utilisez plutôt le chemin synchrone et consultez comment tester l’API ChatGPT avec Apidog.

Essayez Apidog aujourd’hui

Qu’est-ce que l’API de lot et quand l’utiliser

L’API de lot permet d’exécuter un grand volume d’appels de modèles de manière asynchrone. Au lieu d’envoyer une requête HTTP par invite, vous regroupez les requêtes dans un fichier JSONL, vous soumettez ce fichier comme une tâche unique, puis vous interrogez son état jusqu’à la fin du traitement.

OpenAI exécute le lot hors du chemin synchrone et renvoie les résultats dans un fichier de sortie.

Les deux bénéfices principaux sont :

  • 50 % de réduction sur les jetons d’entrée et de sortie par rapport aux points d’accès synchrones.
  • Un débit séparé, car les lots utilisent un pool de limites distinct de votre trafic en direct.

Le compromis est la latence : OpenAI indique une fenêtre de complétion pouvant aller jusqu’à 24 heures.

Utilisez l’API de lot pour des traitements hors ligne comme :

  • classer ou étiqueter un arriéré d’enregistrements ;
  • générer des embeddings pour un corpus entier ;
  • produire du contenu en volume : descriptions de produits, résumés, traductions ;
  • exécuter des suites d’évaluation ou comparer des modèles sur un dataset.

Évitez-la pour les parcours utilisateur interactifs : chat, autocomplétion, agents en direct ou toute fonctionnalité qui attend une réponse immédiate. Pour des cas comme la génération de nombreuses configurations d’agents, le traitement par lots est adapté ; voir aussi le guide sur la génération de plus de 100 configurations d’agents avec le traitement par lots.

Prérequis

Vous allez utiliser deux points d’accès :

  • /v1/files
  • /v1/batches

Le flux complet contient quatre étapes :

Étape Point d’accès Action
1. Téléverser POST /v1/files Envoyer le fichier .jsonl avec purpose: "batch" et récupérer un ID de fichier
2. Créer POST /v1/batches Soumettre l’ID du fichier, le point d’accès cible et la fenêtre de complétion
3. Interroger GET /v1/batches/{id} Lire le status jusqu’à completed
4. Récupérer GET /v1/files/{id}/content Télécharger les résultats via output_file_id

Avant de commencer, préparez :

  • une clé API OpenAI exportée dans OPENAI_API_KEY ;
  • un fichier JSONL contenant vos requêtes ;
  • un outil pour exécuter et inspecter les appels HTTP, par exemple Apidog ou curl.
export OPENAI_API_KEY="sk-..."
Enter fullscreen mode Exit fullscreen mode

Étape 1 : construire le fichier JSONL

Le fichier d’entrée est un fichier JSONL : une requête par ligne.

Chaque ligne doit contenir :

  • custom_id : un identifiant unique que vous choisissez ;
  • method : généralement POST ;
  • url : le point d’accès cible, par exemple /v1/chat/completions ;
  • body : les paramètres réels de la requête.

Exemple requests.jsonl :

{"custom_id": "req-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-4.1-mini", "messages": [{"role": "user", "content": "Classify the sentiment of: 'shipping was slow but the product is great'"}]}}
{"custom_id": "req-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-4.1-mini", "messages": [{"role": "user", "content": "Classify the sentiment of: 'returned it the same day'"}]}}
Enter fullscreen mode Exit fullscreen mode

Points à vérifier avant le téléversement :

  • custom_id doit être unique dans le fichier ;
  • url doit correspondre au point d’accès que vous indiquerez dans le lot ;
  • chaque ligne doit être un JSON valide ;
  • ne comptez pas sur l’ordre des résultats : utilisez toujours custom_id pour faire la correspondance.

Un lot peut contenir jusqu’à 50 000 requêtes et le fichier peut atteindre 200 Mo.

Étape 2 : téléverser le fichier

Envoyez le fichier à l’API Files avec purpose="batch" :

curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F purpose="batch" \
  -F file="@requests.jsonl"
Enter fullscreen mode Exit fullscreen mode

La réponse contient un id de fichier :

{
  "id": "file-abc123",
  "object": "file",
  "purpose": "batch"
}
Enter fullscreen mode Exit fullscreen mode

Conservez cette valeur. Elle devient votre input_file_id.

Étape 3 : créer le lot

Créez ensuite la tâche de lot avec POST /v1/batches.

curl https://api.openai.com/v1/batches \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input_file_id": "file-abc123",
    "endpoint": "/v1/chat/completions",
    "completion_window": "24h",
    "metadata": {
      "job": "sentiment-backfill"
    }
  }'
Enter fullscreen mode Exit fullscreen mode

À vérifier :

  • input_file_id doit être l’ID renvoyé par /v1/files ;
  • endpoint doit correspondre au champ url de vos lignes JSONL ;
  • completion_window accepte actuellement "24h" ;
  • metadata est optionnel et peut servir à identifier la tâche.

Les cibles prises en charge incluent notamment :

  • /v1/chat/completions
  • /v1/responses
  • /v1/embeddings
  • /v1/completions
  • /v1/moderations

La réponse renvoie un objet de lot :

{
  "id": "batch_abc123",
  "object": "batch",
  "endpoint": "/v1/chat/completions",
  "input_file_id": "file-abc123",
  "completion_window": "24h",
  "status": "validating",
  "output_file_id": null,
  "error_file_id": null,
  "request_counts": {
    "total": 0,
    "completed": 0,
    "failed": 0
  },
  "created_at": 1733452800,
  "metadata": {
    "job": "sentiment-backfill"
  }
}
Enter fullscreen mode Exit fullscreen mode

Conservez id, par exemple batch_abc123.

Étape 4 : interroger l’état du lot

Un lot démarre généralement avec le statut validating.

Interrogez l’état avec :

curl https://api.openai.com/v1/batches/batch_abc123 \
  -H "Authorization: Bearer $OPENAI_API_KEY"
Enter fullscreen mode Exit fullscreen mode

Surveillez le champ status.

État Signification
validating Le fichier d’entrée est vérifié avant l’exécution
in_progress Les requêtes sont en cours de traitement
finalizing L’exécution est terminée et le fichier de sortie est en préparation
completed Les résultats sont prêts à être téléchargés
failed La validation a échoué ; rien n’a été exécuté
expired La fenêtre de 24 heures s’est fermée avant la fin de toutes les requêtes
cancelling / cancelled Une annulation a été demandée

Pendant in_progress, utilisez request_counts pour suivre l’avancement :

"request_counts": {
  "total": 50000,
  "completed": 32000,
  "failed": 10
}
Enter fullscreen mode Exit fullscreen mode

Il n’y a pas de webhook à attendre dans ce flux. Utilisez donc une boucle d’interrogation à intervalle raisonnable, par exemple toutes les quelques minutes, pas chaque seconde.

Exemple minimal en Bash :

BATCH_ID="batch_abc123"

while true; do
  RESPONSE=$(curl -s https://api.openai.com/v1/batches/$BATCH_ID \
    -H "Authorization: Bearer $OPENAI_API_KEY")

  STATUS=$(echo "$RESPONSE" | jq -r '.status')
  echo "Status: $STATUS"

  if [ "$STATUS" = "completed" ] || [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ] || [ "$STATUS" = "cancelled" ]; then
    echo "$RESPONSE" > batch-status.json
    break
  fi

  sleep 180
done
Enter fullscreen mode Exit fullscreen mode

Vous pouvez aussi annuler un lot en cours :

curl -X POST https://api.openai.com/v1/batches/batch_abc123/cancel \
  -H "Authorization: Bearer $OPENAI_API_KEY"
Enter fullscreen mode Exit fullscreen mode

Étape 5 : télécharger la sortie

Quand status vaut completed, l’objet de lot contient un output_file_id.

Téléchargez le fichier de sortie :

curl https://api.openai.com/v1/files/file-output456/content \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  > results.jsonl
Enter fullscreen mode Exit fullscreen mode

La sortie est aussi en JSONL : une ligne par requête.

Chaque ligne contient notamment :

  • le custom_id d’origine ;
  • un objet response ;
  • le code d’état ;
  • le corps de réponse.

Exemple simplifié :

{"custom_id":"req-1","response":{"status_code":200,"body":{"choices":[{"message":{"content":"mixed positive"}}]}}}
{"custom_id":"req-2","response":{"status_code":200,"body":{"choices":[{"message":{"content":"negative"}}]}}}
Enter fullscreen mode Exit fullscreen mode

Important : les résultats ne sont pas garantis dans le même ordre que les lignes d’entrée. Faites toujours la jointure via custom_id.

Si certaines requêtes échouent, vérifiez aussi error_file_id dans l’objet de lot et téléchargez ce fichier avec /v1/files/{id}/content.

Coût, délai et limites pratiques

Le modèle opérationnel est simple : vous économisez 50 % sur les jetons, mais vous acceptez une fenêtre pouvant aller jusqu’à 24 heures.

C’est adapté pour :

  • des traitements nocturnes ;
  • des backfills ;
  • des enrichissements de données ;
  • des évaluations hors ligne.

Ce n’est pas adapté pour :

  • une interface de chat ;
  • une action utilisateur bloquante ;
  • une autocomplétion ;
  • un agent qui doit répondre immédiatement.

Quelques points à intégrer dans votre implémentation :

  • La réduction s’applique aux jetons d’entrée et de sortie sur les modèles pris en charge.
  • La fenêtre de 24 heures est un plafond, pas un SLA de rapidité.
  • Si un lot passe à expired, les requêtes terminées sont renvoyées et facturées ; les autres ne le sont pas.
  • Les lots utilisent une limite de jetons en file d’attente distincte et ne consomment pas les mêmes limites que le trafic synchrone.
  • Les volumes élevés restent coûteux même avec 50 % de réduction : utilisez metadata pour suivre les jobs et attribuer les dépenses.

Si vous atteignez déjà les plafonds côté synchrone, consultez le guide sur les limites de taux de l’API GPT et comment les tester. Pour l’attribution des coûts, voir aussi ce guide d’attribution des dépenses OpenAI.

Tester le flux dans Apidog

L’API de lot est plus facile à casser qu’un appel de chat synchrone : un JSONL mal formé, un endpoint qui ne correspond pas à url, un custom_id dupliqué ou une mauvaise boucle d’interrogation peuvent faire échouer tout le workflow.

Apidog vous permet d’exécuter chaque étape comme une requête API, de chaîner les appels et d’ajouter des assertions sur les réponses. Ce n’est pas un SDK OpenAI ; c’est une plateforme pour tester, documenter et simuler des API.

Un plan de test utile :

  1. Valider localement le JSONL

Vérifiez que chaque ligne contient :

  • custom_id
  • method
  • url
  • body
  • body.model
  • les messages ou paramètres attendus
  1. Tester le téléversement multipart

Envoyez POST /v1/files avec :

  • purpose=batch
  • le fichier requests.jsonl

Capturez l’id retourné dans une variable d’environnement.

  1. Créer le lot

Exécutez POST /v1/batches, puis ajoutez des assertions :

  • status vaut validating
  • endpoint correspond au point d’accès attendu
  • input_file_id correspond au fichier téléversé
  1. Interroger le lot

Appelez GET /v1/batches/{id} jusqu’à un état terminal :

  • completed
  • failed
  • expired
  • cancelled
  1. Télécharger les résultats

Quand output_file_id est présent, appelez :

   GET /v1/files/{output_file_id}/content
Enter fullscreen mode Exit fullscreen mode

Puis vérifiez que chaque ligne de sortie contient un custom_id.

  1. Tester les erreurs

Soumettez un fichier volontairement invalide pour confirmer que votre gestion du statut failed fonctionne. Testez aussi :

   POST /v1/batches/{id}/cancel
Enter fullscreen mode Exit fullscreen mode

Comme la sortie peut arriver plus tard, vous pouvez aussi configurer une API simulée qui renvoie un objet de lot terminé et un fichier de résultats pré-enregistré. Cela permet de développer la logique de récupération et de parsing sans attendre une vraie tâche de 24 heures ni consommer de jetons.

Si votre équipe travaille à partir de spécifications, vous pouvez également générer une collection de tests depuis une spécification OpenAPI et maintenir ce workflow sous tests de régression en CI.

Foire aux questions

Combien de temps prend réellement une tâche par lots ?

OpenAI indique une fenêtre de complétion allant jusqu’à 24 heures. Certaines tâches peuvent se terminer plus vite, mais votre système doit gérer le pire cas.

Si la fenêtre expire, le lot passe à expired. Les requêtes déjà terminées sont renvoyées et facturées ; les autres ne le sont pas.

Quelle est la réduction ?

L’API de lot offre une réduction forfaitaire de 50 % par rapport aux points d’accès synchrones, sur les jetons d’entrée et de sortie.

Si vous devez rattacher ces dépenses à des fonctionnalités ou à des jobs, utilisez metadata et consultez le guide d’attribution des coûts.

Quels points d’accès puis-je exécuter dans un lot ?

Vous indiquez la cible à deux endroits :

  • dans url pour chaque ligne JSONL ;
  • dans endpoint lors de la création du lot.

Les deux doivent correspondre.

Les cibles prises en charge incluent notamment :

  • /v1/chat/completions
  • /v1/responses
  • /v1/embeddings
  • /v1/completions
  • /v1/moderations

OpenAI peut faire évoluer cette liste ; vérifiez la documentation actuelle pour les points d’accès disponibles.

Pourquoi mes résultats ne sont-ils pas dans le même ordre ?

C’est normal. La sortie JSONL ne garantit pas l’ordre des lignes d’entrée.

Utilisez custom_id pour faire correspondre chaque résultat à sa requête source. Si deux lignes partagent le même custom_id, vous ne pourrez pas distinguer leurs réponses de manière fiable.

Conclusion

Le workflow complet est maintenant clair :

  1. préparer un fichier JSONL ;
  2. le téléverser avec purpose=batch ;
  3. créer un lot avec POST /v1/batches ;
  4. interroger l’état jusqu’à un statut terminal ;
  5. télécharger output_file_id ;
  6. traiter les résultats via custom_id.

L’API de lot est utile dès que vous avez un gros volume de requêtes hors ligne et que vous pouvez accepter une fenêtre de traitement pouvant aller jusqu’à 24 heures.

Avant de l’automatiser en production, exécutez le cycle de vie à la main. Téléchargez Apidog pour valider vos requêtes, tester les points d’accès de téléversement, de création, d’interrogation et d’annulation, et ajouter des assertions sur les objets de lot.

Top comments (0)