# Aide-mémoire API OpenAI

Formes de requête et de réponse de la Responses API en Python et TypeScript, état de conversation, streaming, mode background, sorties structurées, outils, reasoning effort, caching, batch, erreurs et limites.

import { Tabs, TabItem, Steps } from '@prosefly/astro-components';

La **Responses API** est l’interface principale pour les nouveaux travaux. **Chat Completions est hérité** — elle fonctionne toujours, mais c’est dans la Responses API que vivent l’état de conversation, le mode background, les reasoning items et la surface d’outils intégrés, alors développez sur elle. Tout ce qui figure ici reflète la surface de septembre 2026 décrite dans les [pistes OpenAI](/fr/openai/) ; revérifiez les formes auprès de [developers.openai.com/api/docs](https://developers.openai.com/api/docs).

## Requête minimale

<Tabs>
<TabItem label="Python">
```python
from openai import OpenAI

client = OpenAI()  # lit OPENAI_API_KEY

resp = client.responses.create(
    model="gpt-5.6-terra",
    input="Donne trois risques du verrouillage fournisseur.",
    reasoning={"effort": "medium"},
)
print(resp.output_text)
```
</TabItem>
<TabItem label="TypeScript">
```typescript
import OpenAI from 'openai';

const client = new OpenAI(); // lit OPENAI_API_KEY

const resp = await client.responses.create({
  model: 'gpt-5.6-terra',
  input: 'Donne trois risques du verrouillage fournisseur.',
  reasoning: { effort: 'medium' },
});
console.log(resp.output_text);
```
</TabItem>
</Tabs>

`input` accepte une chaîne ou un tableau d’items typés (messages, sorties d’outils, fichiers). `output_text` est un agrégat de commodité ; le contenu de référence se trouve dans le tableau `output` d’items.

## Champs de requête

| Champ | Notes |
| --- | --- |
| `model` | ID épinglé : `gpt-6-astra`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` |
| `input` | Chaîne ou tableau d’items d’entrée typés |
| `instructions` | Guidage de niveau système pour cette réponse |
| `reasoning.effort` | `none`…`max` (5.6), `low`…`max` (Astra) ; le plus bas qui fonctionne |
| `max_output_tokens` | Plafond de sortie ; surveillez le statut `incomplete` s’il est atteint |
| `tools` / `tool_choice` | Outils intégrés et vos fonctions |
| `text.format` | Sortie structurée (JSON Schema) |
| `previous_response_id` | État de conversation côté serveur |
| `store` | Persiste la réponse pour récupération / état ultérieurs |
| `stream` | `true` pour SSE |
| `background` | `true` pour exécuter de façon asynchrone |
| `metadata` | Vos étiquettes clé/valeur (p. ex. identifiant utilisateur haché) |

## Forme de la réponse

```json
{
  "id": "resp_01",
  "object": "response",
  "model": "gpt-5.6-terra",
  "status": "completed",
  "output": [
    { "type": "reasoning", "id": "rs_01", "summary": [] },
    { "type": "message", "role": "assistant",
      "content": [{ "type": "output_text", "text": "The notice period is 60 days." }] }
  ],
  "usage": {
    "input_tokens": 1200,
    "input_tokens_details": { "cached_tokens": 1024 },
    "output_tokens": 42,
    "output_tokens_details": { "reasoning_tokens": 18 },
    "total_tokens": 1242
  }
}
```

### status — branchez dessus

| `status` | Signification | Action |
| --- | --- | --- |
| `completed` | Terminé normalement | Lire `output` |
| `incomplete` | Arrêté tôt (p. ex. `max_output_tokens`) | Inspecter `incomplete_details` ; continuer ou relever le plafond |
| `in_progress` | Background/streamé, pas terminé | Interroger ou continuer le streaming |
| `failed` | En erreur | Inspecter `error` ; réessayer seulement si transitoire |

`output_tokens_details.reasoning_tokens` sont facturés comme de la sortie — un effort élevé y dépense de l’argent réel.

## État de conversation

Deux façons de porter l’état ; ne les mélangez pas pour le même thread.

| Approche | Comment | À utiliser quand |
| --- | --- | --- |
| Côté serveur | Mettre `store: true`, puis passer `previous_response_id` à l’appel suivant | Vous voulez qu’OpenAI garde le thread ; moins à envoyer à chaque tour |
| Côté client | Renvoyez vous-même le tableau `input` complet | Vous avez besoin d’un contrôle total / de votre propre stockage |

```python
first = client.responses.create(model="gpt-5.6-terra", input="Je m'appelle Dana.", store=True)
second = client.responses.create(
    model="gpt-5.6-terra",
    input="Quel est mon nom ?",
    previous_response_id=first.id,
)
```

## Streaming

Les server-sent events émettent des événements **sémantiques**, pas des deltas de tokens bruts — branchez sur le `type` de l’événement.

<Tabs>
<TabItem label="Python">
```python
stream = client.responses.create(
    model="gpt-5.6-terra", input="Écris un haïku sur la latence.", stream=True,
)
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)
    elif event.type == "response.completed":
        print("\n", event.response.usage)
```
</TabItem>
<TabItem label="TypeScript">
```typescript
const stream = await client.responses.create({
  model: 'gpt-5.6-terra', input: 'Écris un haïku sur la latence.', stream: true,
});
for await (const event of stream) {
  if (event.type === 'response.output_text.delta') process.stdout.write(event.delta);
  else if (event.type === 'response.completed') console.log('\n', event.response.usage);
}
```
</TabItem>
</Tabs>

Types d’événements courants : `response.created`, `response.output_item.added`, `response.output_text.delta`, `response.function_call_arguments.delta`, `response.output_item.done`, `response.completed`, `response.error`. Les arguments d’appel d’outil arrivent en fragments — mettez-les en tampon et ne les analysez qu’au `done`.

## Mode background

Pour les jobs longs, démarrez avec `background: true`, récupérez un id immédiatement, puis interrogez ou abonnez-vous à un webhook.

```python
job = client.responses.create(model="gpt-6-astra", input=big_task, background=True)
# plus tard
resp = client.responses.retrieve(job.id)
while resp.status in ("queued", "in_progress"):
    time.sleep(2)
    resp = client.responses.retrieve(job.id)
```

Le mode background s’associe aux webhooks pour ne pas maintenir une connexion ouverte pendant des minutes. C’est l’analogue, au niveau de l’API, des sessions durables de l’Agents API pour du travail long ponctuel.

## Sorties structurées

```python
schema = {
  "type": "object",
  "properties": {
    "vendor": {"type": "string"},
    "total": {"type": "number"},
    "currency": {"type": "string", "enum": ["USD", "EUR", "GBP"]},
  },
  "required": ["vendor", "total", "currency"],
  "additionalProperties": False,
}
resp = client.responses.create(
    model="gpt-5.6-terra",
    input="Extract the invoice: Acme, 1240.50 USD.",
    text={"format": {"type": "json_schema", "name": "invoice", "schema": schema, "strict": True}},
)
```

`strict: true` contraint la génération au schéma. Validez tout de même en aval et réessayez en réinjectant l’erreur précise — une sortie structurée garantit la forme, pas l’exactitude métier.

## Function calling

```python
tools = [{
  "type": "function",
  "name": "get_order",
  "description": "Look up one order by ID. Returns status and ETA.",
  "parameters": {
    "type": "object",
    "properties": {"order_id": {"type": "string"}},
    "required": ["order_id"], "additionalProperties": False,
  },
  "strict": True,
}]

resp = client.responses.create(model="gpt-5.6-terra", input="Where is ORD-12345?", tools=tools)
# resp.output contient un item function_call ; exécutez-le, puis renvoyez la sortie :
followup = client.responses.create(
    model="gpt-5.6-terra",
    previous_response_id=resp.id,
    input=[{"type": "function_call_output", "call_id": call_id,
            "output": '{"status":"shipped","eta":"2026-09-17"}'}],
)
```

La boucle : le modèle émet un item `function_call` → vous l’exécutez → vous renvoyez un item `function_call_output` (référençant `previous_response_id` ou en renvoyant l’état) → répétez jusqu’à un simple message.

## Reasoning effort

```python
client.responses.create(model="gpt-5.6-luna", input=simple_transform, reasoning={"effort": "none"})
client.responses.create(model="gpt-6-astra", input=hard_problem, reasoning={"effort": "xhigh"})
```

Utilisez l’**effort le plus bas qui donne le résultat**. Les tokens de raisonnement sont facturés comme de la sortie. Il n’y a pas de correspondance exacte d’effort GPT-5.5 → 5.6 — reréglez par modèle. Voir la [gamme de modèles](/fr/appendix/openai/model-lineup/).

## Entrées de fichiers

```python
f = client.files.create(file=open("contract.pdf", "rb"), purpose="user_data")
resp = client.responses.create(
    model="gpt-5.6-terra",
    input=[{"role": "user", "content": [
        {"type": "input_file", "file_id": f.id},
        {"type": "input_text", "text": "Summarise the termination clause."},
    ]}],
)
```

Les images utilisent `input_image` avec un `file_id` ou une URL. Téléversez une fois et référencez par id à travers de nombreux appels plutôt que de re-téléverser.

## Compaction et comptage de tokens

- **Compaction** résume les tours plus anciens côté serveur afin qu’une longue session reste dans la fenêtre de contexte tout en préservant le fil narratif. C’est le levier côté API contre la croissance non bornée du contexte ; l’Agents API applique automatiquement la synthèse de contexte au sein d’une session.
- **Comptage de tokens** — inspectez `usage.input_tokens`, `usage.output_tokens`, `input_tokens_details.cached_tokens` (hits de cache) et `output_tokens_details.reasoning_tokens` (raisonnement facturé) sur chaque réponse pour garder le coût honnête.

## Outils intégrés

| Outil | Objectif en une ligne |
| --- | --- |
| `web_search` | Répondre à partir du web en direct avec citations |
| `file_search` | Récupérer sur vos fichiers téléversés/indexés |
| retrieval | Réponses ancrées sur un store géré |
| MCP / connectors | Atteindre des systèmes externes via des serveurs MCP |
| secure MCP tunnel | Atteindre des serveurs MCP privés sans les exposer |
| `code_interpreter` | Exécuter du code dans un bac à sable pour données/analyse |
| `image_generation` | Générer des images en ligne |
| `computer_use` | Piloter une interface d’ordinateur/navigateur |
| shell / local shell | Exécuter des commandes shell (bac à sable / local) |
| apply patch | Appliquer des modifications de code |
| tool search | Découvrir des outils dans un large catalogue |
| programmatic tool calling | Invoquer des outils depuis du code généré |
| async tool calling | Outils de longue durée sans bloquer le tour |

## Fonctionnalités de qualité et de coût

| Fonctionnalité | Ce qu’elle fait | À utiliser quand |
| --- | --- | --- |
| **Prompt caching** | Réutilise un préfixe stable ; l’entrée mise en cache est remisée ; les diagnostics de cache rapportent les hits | Le même long system prompt/contexte se répète d’un appel à l’autre |
| **Batch** | Traitement hors ligne à prix remisé, résultats dans une fenêtre | Jobs à fort volume tolérants à la latence |
| **Flex processing** | Palier de latence best-effort à prix réduit | Trafic non urgent qui tolère une latence variable |
| **Fast mode** | Chemin optimisé pour la latence | Appels interactifs, critiques en latence |
| **Predicted outputs** | Fournir le texte attendu pour accélérer les éditions | Régénérer un document avec de petites modifications |

Confirmez les hits de cache via `usage.input_tokens_details.cached_tokens` ; le caching réduit davantage le coût que la pression sur les rate limits.

## Codes d’erreur et politique de réessai

| HTTP | Type | Réessai ? |
| --- | --- | --- |
| 400 | `invalid_request_error` | Non — corrigez la requête |
| 401 | `authentication_error` | Non — clé/identifiants |
| 403 | `permission_error` | Non — droit/région |
| 404 | `not_found_error` | Non — id de modèle/ressource |
| 409 | `conflict` | Parfois — résolvez l’état puis réessayez |
| 422 | `unprocessable` | Non — corrigez le payload |
| 429 | `rate_limit_error` | Oui — backoff, respectez `retry-after` |
| 500 | `server_error` | Oui — backoff |
| 503 | `service_unavailable` | Oui — backoff, envisagez un modèle de repli |

Utilisez un backoff exponentiel avec jitter, respectez `retry-after`, journalisez l’id de requête depuis les en-têtes de réponse, et passez une clé d’idempotence sur les requêtes à effet de bord afin qu’un réessai n’agisse pas deux fois.

```python
import time, random
from openai import OpenAI, RateLimitError, APIStatusError

client = OpenAI()
RETRYABLE = {429, 500, 503}

def call_with_retry(**params):
    for attempt in range(6):
        try:
            return client.responses.create(**params)
        except RateLimitError as e:
            wait = float(e.response.headers.get("retry-after", 0)) or min(60, 2 ** attempt)
            time.sleep(wait + random.uniform(0, 0.5))
        except APIStatusError as e:
            if e.status_code in RETRYABLE:
                time.sleep(min(60, 2 ** attempt) + random.uniform(0, 0.5))
            else:
                raise
    raise RuntimeError("exhausted retries")
```

## Limites de débit et de dépense

- **Rate limits** — s’appliquent aux requêtes et aux tokens par minute ; vous atteignez celle qui contraint en premier. Surveillez les en-têtes de réponse de rate limit et régulez avant un 429 plutôt qu’après.
- **Spend limits** — plafonnent le coût par période au niveau org/projet ; les atteindre renvoie une erreur, pas un arrêt silencieux.
- Gérez les deux depuis le dashboard ; imposez des budgets au niveau projet afin qu’un job emballé ne puisse épuiser l’org.

:::tip[Signal d’évaluation]
« Chat Completions » dans un énoncé sur un *nouveau* travail est généralement le distracteur — la bonne surface est la **Responses API**. « Longue durée », « ne pas garder la connexion », « revenir plus tard » pointe vers le **mode background** ; « le même system prompt à chaque appel » pointe vers le **prompt caching** ; « de nuit, pas cher » pointe vers **Batch**.
:::

## Faits clés à mémoriser

- La Responses API est primaire ; **Chat Completions est hérité** pour les nouveaux travaux.
- État de conversation : `store: true` + `previous_response_id` (côté serveur) ou renvoyer `input` (côté client) — pas les deux.
- Le streaming émet des événements sémantiques ; branchez sur le `type` d’événement, mettez en tampon les fragments d’args d’outil.
- La sortie structurée garantit la forme (`strict: true`), pas l’exactitude métier — validez et réessayez tout de même.
- Ne réessayez que 429/5xx avec backoff et `retry-after` ; corrigez les 4xx. Utilisez des clés d’idempotence sur les appels à effet de bord.
- L’entrée mise en cache, Batch, Flex, Fast mode et predicted outputs sont les leviers de coût/latence.
