Serveur d’application Codex
Serveur d’application Codex
Le serveur d’application Codex est l’interface qu’utilise Codex pour alimenter des clients riches (par exemple, l’extension Codex pour VS Code). Utilisez-le lorsque vous souhaitez intégrer étroitement Codex à votre propre produit : authentification, historique des conversations, approbations et événements de l’agent diffusés en continu. L’implémentation du serveur d’application est open source dans le dépôt GitHub de Codex (openai/codex/codex-rs/app-server). Consultez la page Open Source pour obtenir la liste complète des composants open source de Codex.
Connecter l’interface de terminal de la CLI
Le mode d’interface de terminal à distance vous permet d’exécuter le serveur d’application sur une machine et de connecter l’interface de terminal de la CLI Codex depuis une autre. Démarrez un écouteur WebSocket :
codex app-server --listen ws://127.0.0.1:4500Connectez ensuite l’interface de terminal :
codex --remote ws://127.0.0.1:4500Pour une connexion non locale, configurez l’authentification WebSocket et placez la connexion derrière TLS. Stockez le jeton bearer dans une variable d’environnement et transmettez son nom au lieu de placer le jeton sur la ligne de commande :
export CODEX_REMOTE_TOKEN="$(cat "$HOME/.codex/app-server-token")"
codex --remote wss://remote-host:4500 \
--remote-auth-token-env CODEX_REMOTE_TOKENL’option --remote accepte les points de terminaison ws://, wss://, unix:// et
unix://PATH. N’utilisez des WebSockets sans chiffrement que pour localhost ou une connexion
transférée par port SSH.
Connecter un hôte Code Mode distant
Par défaut, le serveur d’application démarre un hôte Code Mode local. Pour utiliser plutôt un hôte distant, transmettez son URL WebSocket sécurisée :
codex app-server --code-mode-host wss://code-mode.example.com/host--code-mode-host contrôle la connexion sortante du serveur d’application vers son hôte Code
Mode. Cela ne modifie pas --listen, qui contrôle la manière dont les clients se connectent au
serveur d’application. Tous les threads d’un même processus de serveur d’application partagent la connexion
à l’hôte Code Mode sélectionné.
Utilisez wss:// pour un hôte distant. N’utilisez ws:// que pour localhost ou une
connexion transférée par SSH. La commande du serveur d’application et le transport WebSocket sont
expérimentaux et ne sont pas pris en charge pour les charges de travail de production.
Protocole
Comme MCP, codex app-server prend en charge la communication bidirectionnelle au moyen de messages JSON-RPC 2.0 (avec l’en-tête "jsonrpc":"2.0" omis lors de la transmission).
Transports pris en charge :
stdio(--listen stdio://, par défaut) : JSON délimité par des retours à la ligne (JSONL).websocket(--listen ws://IP:PORT, expérimental et non pris en charge) : un message JSON-RPC par trame de texte WebSocket.- Socket Unix (
--listen unix://ou--listen unix://PATH) : connexions WebSocket via le socket de contrôle par défaut du serveur d’application de Codex ou un socket Unix personnalisé, en utilisant la négociation HTTP Upgrade standard. off(--listen off) : n’expose aucun transport local.
Lorsque vous exécutez le serveur avec --listen ws://IP:PORT, le même écouteur fournit également des
sondes d’intégrité HTTP élémentaires :
GET /readyzrenvoie200 OKdès que l’écouteur accepte de nouvelles connexions.GET /healthzrenvoie200 OKlorsque la requête ne contient pas d’en-têteOrigin.- Les requêtes comportant un en-tête
Originsont rejetées avec403 Forbidden.
Le transport WebSocket est expérimental et non pris en charge. Les écouteurs locaux tels que
ws://127.0.0.1:PORT conviennent aux workflows localhost et de transfert de port SSH.
Pendant le déploiement, les écouteurs WebSocket qui ne sont pas limités à l’interface loopback autorisent actuellement les connexions
non authentifiées par défaut ; configurez donc l’authentification WebSocket avant
d’en exposer un à distance.
Options d’authentification WebSocket prises en charge :
--ws-auth capability-token --ws-token-file /absolute/path--ws-auth capability-token --ws-token-sha256 HEX--ws-auth signed-bearer-token --ws-shared-secret-file /absolute/path
Pour les jetons bearer signés, vous pouvez également définir --ws-issuer, --ws-audience et
--ws-max-clock-skew-seconds. Les clients présentent l’identifiant comme
Authorization: Bearer <token> pendant la négociation WebSocket, et le serveur d’application
impose l’authentification avant l’opération JSON-RPC initialize.
Préférez --ws-token-file à la transmission de jetons bearer bruts sur la ligne de commande. Utilisez
--ws-token-sha256 uniquement lorsque le client conserve le jeton brut à forte entropie dans un
magasin de secrets local distinct ; le hachage ne sert que de vérificateur et les clients ont toujours besoin
du jeton d’origine.
En mode WebSocket, le serveur d’application utilise des files d’attente de taille limitée. Lorsque la file d’entrée des requêtes est pleine,
le serveur rejette les nouvelles requêtes avec le code d’erreur JSON-RPC -32001 et le message
"Server overloaded; retry later." Les clients doivent réessayer avec un délai
croissant de manière exponentielle et une gigue aléatoire.
Schéma des messages
Les requêtes comprennent method, params et id :
{ "method": "thread/start", "id": 10, "params": { "model": "gpt-5.6-terra" } }Les réponses reprennent le champ id avec soit result, soit error :
{ "id": 10, "result": { "thread": { "id": "thr_123" } } }{ "id": 10, "error": { "code": 123, "message": "Something went wrong" } }Les notifications omettent id et utilisent uniquement method et params :
{ "method": "turn/started", "params": { "turn": { "id": "turn_456" } } }Vous pouvez générer un schéma TypeScript ou un ensemble de schémas JSON depuis la CLI. Chaque sortie est propre à la version de Codex que vous avez exécutée ; les artefacts générés correspondent donc exactement à cette version :
codex app-server generate-ts --out ./schemas
codex app-server generate-json-schema --out ./schemasPrise en main
- Démarrez le serveur avec
codex app-server(transport stdio par défaut),codex app-server --listen ws://127.0.0.1:4500(WebSocket TCP) oucodex app-server --listen unix://(socket Unix par défaut). - Connectez un client au moyen du transport sélectionné, puis envoyez
initialize, suivi de la notificationinitialized. - Démarrez un thread et un tour, puis continuez à lire les notifications dans le flux du transport actif.
Exemple (Node.js / TypeScript) :
const proc = spawn("codex", ["app-server"], {
stdio: ["pipe", "pipe", "inherit"],
});
const rl = readline.createInterface({ input: proc.stdout });
const send = (message: unknown) => {
proc.stdin.write(`${JSON.stringify(message)}\n`);
};
let threadId: string | null = null;
rl.on("line", (line) => {
const msg = JSON.parse(line) as any;
console.log("server:", msg);
if (msg.id === 1 && msg.result?.thread?.id && !threadId) {
threadId = msg.result.thread.id;
send({
method: "turn/start",
id: 2,
params: {
threadId,
input: [{ type: "text", text: "Summarize this repo." }],
},
});
}
});
send({
method: "initialize",
id: 0,
params: {
clientInfo: {
name: "my_product",
title: "My Product",
version: "0.1.0",
},
},
});
send({ method: "initialized", params: {} });
send({ method: "thread/start", id: 1, params: { model: "gpt-5.6-terra" } });Concepts fondamentaux
- Thread : conversation entre un utilisateur et l’agent Codex. Les threads contiennent des tours.
- Tour : requête unique d’un utilisateur et travail effectué ensuite par l’agent. Les tours contiennent des éléments et diffusent des mises à jour incrémentielles.
- Élément : unité d’entrée ou de sortie (message utilisateur, message de l’agent, exécution de commande, modification de fichier, appel d’outil, etc.).
Utilisez les API de thread pour créer, répertorier ou archiver des conversations. Pilotez une conversation avec les API de tour et suivez sa progression grâce aux notifications de tour.
Vue d’ensemble du cycle de vie
- Initialiser une fois par connexion : immédiatement après l’ouverture d’une connexion de transport, envoyez une requête
initializeavec les métadonnées de votre client, puis émettezinitialized. Le serveur rejette toute requête sur cette connexion avant cette négociation. - Démarrer (ou reprendre) un thread : appelez
thread/startpour une nouvelle conversation,thread/resumepour poursuivre une conversation existante outhread/forkpour créer une branche de l’historique avec un nouvel identifiant de thread. - Commencer un tour : appelez
turn/startavec lethreadIdcible et l’entrée utilisateur. Les champs facultatifs remplacent le modèle, la personnalité,cwd, la politique de sandbox, etc. - Orienter un tour actif : appelez
turn/steerpour ajouter une entrée utilisateur au tour actuellement en cours sans créer de nouveau tour. - Diffuser les événements : après
turn/start, continuez à lire les notifications sur stdout :thread/archived,thread/unarchived,item/started,item/completed,item/agentMessage/delta, la progression des outils et d’autres mises à jour. - Terminer le tour : le serveur émet
turn/completedavec l’état final lorsque le modèle a terminé ou après une annulationturn/interrupt.
Initialisation
Les clients doivent envoyer une seule requête initialize par connexion de transport avant d’appeler toute autre méthode sur cette connexion, puis en accuser réception avec une notification initialized. Les requêtes envoyées avant l’initialisation reçoivent une erreur Not initialized, et les appels répétés à initialize sur la même connexion renvoient Already initialized.
Le serveur renvoie la chaîne user-agent qu’il présentera aux services en amont, ainsi que les valeurs platformFamily et platformOs décrivant la cible d’exécution. Définissez clientInfo pour identifier votre intégration.
initialize.params.capabilities prend également en charge les capacités client suivantes :
optOutNotificationMethods- noms exacts des méthodes de notification à supprimer pour cette connexion. La correspondance est exacte (sans caractères génériques ni préfixes) ; les noms inconnus sont acceptés et ignorés.requestAttestation- permet d’accepter la requêteattestation/generateinitiée par le serveur. Les hôtes de bureau qui fournissent une attestation en amont répondent avec une valeur{ "token": "..." }opaque.mcpServerOpenaiFormElicitation- autorise les serveurs MCP en aval à envoyer la variante étendue OpenAI demcpServer/elicitation/request.
Important : utilisez clientInfo.name pour identifier votre client auprès de l’OpenAI Compliance Logs Platform. Si vous développez une nouvelle intégration Codex destinée à un usage en entreprise, veuillez contacter OpenAI afin qu’elle soit ajoutée à la liste des clients connus. Pour plus de contexte, consultez la référence sur les journaux Codex.
Exemple (tiré de l’extension Codex pour VS Code) :
{
"method": "initialize",
"id": 0,
"params": {
"clientInfo": {
"name": "codex_vscode",
"title": "Codex VS Code Extension",
"version": "0.1.0"
}
}
}Exemple avec désactivation de certaines notifications :
{
"method": "initialize",
"id": 1,
"params": {
"clientInfo": {
"name": "my_client",
"title": "My Client",
"version": "0.1.0"
},
"capabilities": {
"experimentalApi": true,
"optOutNotificationMethods": ["thread/started", "item/agentMessage/delta"]
}
}
}Activation de l’API expérimentale
Certaines méthodes et certains champs du serveur d’application sont intentionnellement conditionnés par la capacité experimentalApi.
- Omettez
capabilities(ou définissezexperimentalApisurfalse) pour rester sur la surface d’API stable ; le serveur rejettera alors les méthodes et champs expérimentaux. - Définissez
capabilities.experimentalApisurtruepour activer les méthodes et champs expérimentaux.
{
"method": "initialize",
"id": 1,
"params": {
"clientInfo": {
"name": "my_client",
"title": "My Client",
"version": "0.1.0"
},
"capabilities": {
"experimentalApi": true
}
}
}Si un client envoie une méthode ou un champ expérimental sans l’avoir activé, le serveur d’application le rejette avec :
<descriptor> requires experimentalApi capability
Vue d’ensemble de l’API
thread/start- crée un nouveau thread ; émetthread/startedet vous abonne automatiquement aux événements de tour et d’élément de ce thread.thread/resume- rouvre un thread existant à partir de son id afin que les appelsturn/startultérieurs y ajoutent du contenu.thread/fork- crée un nouveau thread à partir d’un fork en copiant l’historique stocké. TransmettezlastTurnIdpour copier l’historique jusqu’à ce tour et omettre les tours suivants, ouephemeral: truepour créer un fork en mémoire. Émetthread/startedpour le nouveau thread ; les threads renvoyés incluentforkedFromIdlorsqu’il est disponible.thread/read- lit un thread stocké à partir de son id sans le reprendre ; définissezincludeTurnspour renvoyer l’historique complet des tours. Les objetsthreadrenvoyés incluent lestatusd’exécution.thread/list- parcourt par pages les journaux des threads stockés ; prend en charge la pagination par curseur ainsi quemodelProviders,sourceKinds,archived,isPinned,cwd,useStateDbOnly,searchTermet les filtres expérimentauxparentThreadIdouancestorThreadId. Les objetsthreadrenvoyés incluent lestatusd’exécution.thread/turns/list- expérimental ; parcourt par pages l’historique des tours d’un thread stocké sans le reprendre.itemsViewdétermine si les éléments des tours sont omis, résumés ou chargés intégralement.thread/items/list- expérimental ; parcourt par pages les éléments persistants d’un thread, avec la possibilité de limiter les résultats à un seulturnId. Le stockage de threads actif doit prendre en charge la pagination des éléments.thread/loaded/list- répertorie les identifiants des threads actuellement chargés en mémoire.thread/name/set- définit ou met à jour le nom visible par l’utilisateur d’un thread chargé ou d’un rollout persistant ; émetthread/name/updated.thread/goal/set- définit l’objectif d’un thread ; émetthread/goal/updated.thread/goal/get- lit l’objectif actuel d’un thread.thread/goal/clear- efface l’objectif d’un thread ; émetthread/goal/cleared.thread/metadata/update- met à jour les métadonnées des threads stockés adossées à SQLite, y compris les valeurs persistantesgitInfoetisPinned.thread/archive- déplace le fichier journal d’un thread vers le répertoire d’archivage et tente d’archiver les journaux des threads descendants générés qui ne le sont pas encore ; renvoie{}en cas de réussite et émetthread/archivedpour chaque thread archivé.thread/delete- supprime définitivement un thread persistant actif ou archivé ainsi que tous les threads descendants générés ; renvoie{}en cas de réussite et émetthread/deletedpour chaque thread supprimé.thread/unsubscribe- désabonne cette connexion des événements de tour et d’élément du thread. S’il s’agissait du dernier abonné, le serveur décharge le thread après un délai de grâce d’inactivité sans abonné et émetthread/closed.thread/unarchive- restaure le rollout d’un thread archivé dans le répertoire des sessions actives ; renvoie lethreadrestauré et émetthread/unarchived.thread/status/changed- notification émise lorsque lestatusd’exécution d’un thread chargé change.thread/compact/start- déclenche la compaction de l’historique de conversation d’un thread ; renvoie immédiatement{}tandis que la progression est diffusée via les notificationsturn/*etitem/*.thread/shellCommand- exécute une commande shell lancée par l’utilisateur sur un thread. Elle s’exécute hors du bac à sable avec un accès complet et n’hérite pas de la politique de bac à sable du thread.thread/backgroundTerminals/clean- arrête tous les terminaux d’arrière-plan en cours d’exécution pour un thread (expérimental ; nécessitecapabilities.experimentalApi).thread/backgroundTerminals/list- répertorie les terminaux d’arrière-plan en cours d’exécution pour un thread chargé (expérimental ; nécessitecapabilities.experimentalApi).thread/backgroundTerminals/terminate- met fin à un terminal d’arrière-plan en cours d’exécution à partir duprocessIdd’app-server (expérimental ; nécessitecapabilities.experimentalApi).thread/rollback- obsolète ; retire les N derniers tours du contexte en mémoire et conserve un marqueur de restauration ; renvoie lethreadmis à jour.turn/start- ajoute une entrée utilisateur ou une sortie d’outil autonome à un thread et démarre la génération de Codex ; répond avec leturninitial et diffuse les événements. PourcollaborationMode,settings.developer_instructions: nullsignifie « utiliser les instructions intégrées pour le mode sélectionné ».thread/inject_items- ajoute des éléments bruts de Responses API à l’historique visible par le modèle d’un thread chargé sans démarrer de tour utilisateur.turn/steer- ajoute une entrée utilisateur au tour actif en cours d’un thread ; renvoie leturnIdaccepté.turn/interrupt- demande l’annulation d’un tour en cours ; la réussite correspond à{}et le tour se termine avecstatus: "interrupted".review/start- lance le réviseur Codex pour un thread ; émet les élémentsenteredReviewModeetexitedReviewMode.command/exec- exécute une seule commande dans le bac à sable du serveur sans démarrer de thread ni de tour.command/exec/write- écrit des octetsstdindans une sessioncommand/execen cours d’exécution ou fermestdin.command/exec/resize- redimensionne une sessioncommand/execen cours d’exécution adossée à un PTY.command/exec/terminate- arrête une sessioncommand/execen cours d’exécution.command/exec/outputDelta(notification) - émise pour les fragments stdout/stderr encodés en base64 provenant d’une sessioncommand/execdiffusée en continu.process/spawn- démarre une session de processus explicite hors du bac à sable de Codex (expérimental ; nécessitecapabilities.experimentalApi).process/writeStdin- écrit des octets stdin dans une sessionprocess/spawnen cours d’exécution ou ferme stdin (expérimental).process/resizePty- redimensionne une session de processus en cours d’exécution adossée à un PTY (expérimental).process/kill- met fin à une session de processus en cours d’exécution (expérimental).process/outputDeltaetprocess/exited(notification) - émises pour la sortie de processus diffusée en continu et l’état de sortie du processus (expérimental).model/list- répertorie les modèles disponibles (définissezincludeHidden: truepour inclure les entrées avechidden: true), avec les options d’effort, le champ facultatifupgradeetinputModalities.modelProvider/capabilities/read- lit les limites des capacités du fournisseur pour les combinaisons modèle/fournisseur.experimentalFeature/list- répertorie les indicateurs de fonctionnalités avec les métadonnées de leur phase de cycle de vie et une pagination par curseur.experimentalFeature/enablement/set- modifie les paramètres d’exécution en mémoire pour les clés de fonctionnalités prises en charge, telles queappsetplugins.environment/info- expérimental ; se connecte à un environnement d’exécution configuré et renvoie son shell ainsi que son répertoire de travail par défaut.permissionProfile/list- répertorie les profils d’autorisation bêta et indique si les exigences effectives les permettent, avec une pagination par curseur.collaborationMode/list- répertorie les préréglages du mode de collaboration (expérimental, sans pagination).skills/list- répertorie les skills pour une ou plusieurs valeurscwd(prend en chargeforceReloadet le champ facultatifperCwdExtraUserRoots).skills/extraRoots/set- remplace les racines supplémentaires au niveau du processus utilisées pour découvrir des skills autonomes, sans les conserver.skills/changed(notification) - émise lorsque des fichiers de skill locaux surveillés changent.hooks/list- répertorie les hooks de cycle de vie découverts pour une ou plusieurs valeurscwd.marketplace/add- ajoute une marketplace de plugins distante et la conserve dans la configuration des marketplaces de l’utilisateur.marketplace/remove- supprime une marketplace configurée et, s’il existe, le répertoire racine de sa marketplace installée.marketplace/upgrade- actualise une marketplace Git configurée, ou toutes les marketplaces Git configurées si vous omettez le nom de la marketplace.plugin/list- en cours de développement ; répertorie les marketplaces de plugins découvertes et l’état des plugins, notamment les métadonnées des politiques d’installation et d’authentification, les erreurs de chargement des marketplaces, les identifiants des plugins mis en avant et les métadonnées des sources de plugins locales, Git, de registre de paquets ou distantes. Les résumés peuvent inclure les éléments distantsversion, locauxlocalVersion, des icônes structurées pour les thèmes clair et sombre ainsi queinstallPolicySource, qui peut prendre la valeurnull,WORKSPACE_SETTINGouIMPLICIT_CANONICAL_APPpour les lignes distantes actuelles. N’appelez pas encore cette méthode depuis des clients en production.plugin/read- en cours de développement ; lit un plugin à partir du chemin de sa marketplace, ou du nom de la marketplace distante et du nom du plugin, notamment les skills, apps et noms de serveurs MCP inclus, ainsi qu’unshareUrlde plugin distant lorsque le catalogue distant en fournit un. N’appelez pas encore cette méthode depuis des clients en production.plugin/install- en cours de développement ; installe un plugin à partir du chemin d’une marketplace ou du nom d’une marketplace distante. N’appelez pas encore cette méthode depuis des clients en production.plugin/uninstall- en cours de développement ; désinstalle un plugin installé. N’appelez pas encore cette méthode depuis des clients en production.plugin/skill/read- lit à la demande le Markdown d’un skill de plugin distant à partir de la marketplace distante, de l’identifiant du plugin et du nom du skill.app/installed- lit l’état d’exécution des apps installées, notamment l’état effectif d’activation et d’appel de chaque app.app/list- répertorie les apps (connecteurs) disponibles avec pagination et métadonnées d’accessibilité et d’activation.app/read- récupère les métadonnées et, éventuellement, des résumés d’outils destinés uniquement à l’affichage pour des identifiants d’app spécifiques.skills/config/write- active ou désactive des skills à partir de leur chemin.mcpServer/oauth/login- démarre une connexion OAuth pour un serveur MCP configuré ; renvoie une URL d’autorisation et émetmcpServer/oauthLogin/completedà la fin.tool/requestUserInput- invite l’utilisateur à répondre à 1 à 3 questions courtes pour un appel d’outil (expérimental) ; les questions peuvent définirisOtherpour une option de saisie libre.mcpServer/elicitation/request(requête du serveur) - demande au client une saisie structurée dans un formulaire ou la confirmation d’un flux d’URL demandé par un serveur MCP.item/permissions/requestApproval(requête du serveur) - demande au client d’accorder un sous-ensemble des autorisations réseau ou de système de fichiers requises par l’outilrequest_permissionsintégré.config/mcpServer/reload- recharge depuis le disque la configuration des serveurs MCP et place en file d’attente une actualisation pour les threads chargés.mcpServerStatus/list- répertorie les serveurs, outils et ressources MCP ainsi que l’état de l’authentification (pagination par curseur et limite). Utilisezdetail: "full"pour obtenir toutes les données oudetail: "toolsAndAuthOnly"pour omettre les ressources.mcpServer/resource/read- lit une seule ressource MCP au moyen d’un serveur MCP initialisé.mcpServer/tool/call- appelle un outil sur le serveur MCP configuré d’un thread.mcpServer/startupStatus/updated(notification) - émise lorsque l’état de démarrage d’un serveur MCP configuré change pour un thread chargé.windowsSandbox/setupStart- démarre la configuration du bac à sable Windows pour le modeelevatedouunelevated; renvoie rapidement une réponse, puis émet ultérieurementwindowsSandbox/setupCompleted.feedback/upload- envoie un rapport de commentaires (classification, motif/journaux facultatifs et identifiant de conversation, ainsi que des pièces jointesextraLogFilesfacultatives).config/read- récupère la configuration effective sur le disque après résolution des différentes couches de configuration.externalAgentConfig/detect- détecte les artefacts d’agents externes pouvant être migrés avecincludeHomeet, facultativement,cwds; chaque élément détecté inclutcwd(nullpour le répertoire personnel).externalAgentConfig/import- applique les éléments de migration d’agents externes sélectionnés en transmettant explicitementmigrationItemsaveccwd(nullpour le répertoire personnel). Les types d’éléments pris en charge comprennent la configuration, les skills,AGENTS.md, les plugins, la configuration des serveurs MCP, les sous-agents, les hooks, les commandes et les sessions ; les importations non vides émettentexternalAgentConfig/import/progressetexternalAgentConfig/import/completedau fil de l’avancement. Les importations de plugins et de sessions peuvent se terminer de manière asynchrone.config/value/write- écrit une seule clé/valeur de configuration dans le fichierconfig.tomlde l’utilisateur sur le disque.config/batchWrite- applique de manière atomique des modifications de configuration au fichierconfig.tomlde l’utilisateur sur le disque.configRequirements/read- récupère les exigences depuisrequirements.tomlet/ou MDM, notamment la configuration gérée exacte, les listes d’autorisation, lesfeatureRequirementsépinglés et les exigences réseau (ounullsi vous n’en avez configuré aucune).fs/readFile,fs/writeFile,fs/createDirectory,fs/getMetadata,fs/readDirectory,fs/remove,fs/copy,fs/watch,fs/unwatchetfs/changed(notification) - agissent sur des chemins absolus du système de fichiers au moyen de l’API de système de fichiers app-server v2.
Les résumés de plugins incluent une union source. Les plugins locaux renvoient
{ "type": "local", "path": ... }, les entrées de marketplace reposant sur Git renvoient
{ "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... },
les entrées de registre de paquets renvoient
{ "type": "npm", "package": ..., "version": ..., "registry": ... } et
les entrées de catalogue distant renvoient { "type": "remote" }. Pour les entrées de catalogue
uniquement distantes, PluginMarketplaceEntry.path peut valoir null ; transmettez
remoteMarketplaceName au lieu de marketplacePath lors de la lecture ou de l’installation
de ces plugins.
Modèles
Répertorier les modèles (model/list)
Appelez model/list pour découvrir les modèles disponibles et leurs capacités avant d’afficher les sélecteurs de modèle ou de personnalité.
{ "method": "model/list", "id": 6, "params": { "limit": 20, "includeHidden": false } }
{ "id": 6, "result": {
"data": [{
"id": "gpt-5.6-sol",
"model": "gpt-5.6-sol",
"displayName": "GPT-5.6-Sol",
"hidden": false,
"defaultReasoningEffort": "low",
"supportedReasoningEfforts": [{
"reasoningEffort": "low",
"description": "Fast responses with lighter reasoning"
}],
"inputModalities": ["text", "image"],
"supportsPersonality": true,
"isDefault": true
}],
"nextCursor": null
} }Chaque entrée de modèle peut inclure :
supportedReasoningEfforts- options d’effort prises en charge par le modèle.defaultReasoningEffort- effort par défaut suggéré pour les clients.upgrade- identifiant facultatif du modèle de mise à niveau recommandé pour les invites de migration dans les clients.upgradeInfo- métadonnées de mise à niveau facultatives pour les invites de migration dans les clients.hidden- indique si le modèle est masqué dans la liste du sélecteur par défaut.inputModalities- types d’entrée pris en charge par le modèle (par exempletext,image).supportsPersonality- indique si le modèle prend en charge les instructions propres à une personnalité, telles que/personality.isDefault- indique si le modèle est celui recommandé par défaut.
Par défaut, model/list renvoie uniquement les modèles visibles dans le sélecteur. Définissez includeHidden: true si vous avez besoin de la liste complète et souhaitez effectuer le filtrage côté client avec hidden.
Lorsque inputModalities est absent (anciens catalogues de modèles), considérez-le comme ["text", "image"] pour assurer la rétrocompatibilité.
Répertorier les fonctionnalités expérimentales (experimentalFeature/list)
Utilisez ce point de terminaison pour découvrir les indicateurs de fonctionnalité avec leurs métadonnées et leur étape de cycle de vie :
{ "method": "experimentalFeature/list", "id": 7, "params": { "limit": 20 } }
{ "id": 7, "result": {
"data": [{
"name": "unified_exec",
"stage": "beta",
"displayName": "Unified exec",
"description": "Use the unified PTY-backed execution tool.",
"announcement": "Beta rollout for improved command execution reliability.",
"enabled": false,
"defaultEnabled": false
}],
"nextCursor": null
} }stage peut valoir beta, underDevelopment, stable, deprecated ou removed. Pour les indicateurs non bêta, displayName, description et announcement peuvent valoir null.
Inspecter un environnement d’exécution (expérimental)
Utilisez environment/info pour inspecter un environnement distant configuré avant
d’y commencer le travail. La méthode nécessite capabilities.experimentalApi = true.
{ "method": "environment/info", "id": 8, "params": { "environmentId": "devbox" } }
{ "id": 8, "result": {
"shell": { "name": "zsh", "path": "/bin/zsh" },
"cwd": "file:///workspace/project"
} }cwd peut valoir null. Lorsqu’il est présent, il s’agit d’un URI file: canonique qui utilise la
syntaxe de chemin native de l’environnement. Les identifiants d’environnement inconnus et les échecs de connexion ou de
protocole renvoient des erreurs de requête.
Threads
thread/readlit un thread stocké sans s’y abonner ; définissezincludeTurnspour inclure les tours.thread/turns/listest expérimental et parcourt par pages l’historique des tours d’un thread stocké sans le reprendre. UtilisezitemsViewpour choisir si les éléments des tours sont omis, résumés ou chargés intégralement.thread/items/listest expérimental et parcourt par pages les éléments persistants d’un thread, avec la possibilité de les limiter à un seul tour.thread/listprend en charge la pagination par curseur ainsi que les filtresmodelProviders,sourceKinds,archived,isPinned,cwd,useStateDbOnly,searchTermet les filtres expérimentauxparentThreadIdouancestorThreadId.thread/loaded/listrenvoie les identifiants des threads actuellement en mémoire.thread/archivedéplace le journal JSONL persistant du thread vers le répertoire des archives et tente d’archiver les journaux des threads descendants générés qui ne le sont pas encore.thread/deletesupprime définitivement un thread persistant actif ou archivé ainsi que ses threads descendants générés.thread/metadata/updatemodifie les métadonnées stockées du thread, notamment les champs persistantsgitInfoetisPinned.thread/unsubscribedésabonne la connexion actuelle d’un thread chargé et peut déclencherthread/closedaprès un délai de grâce sans activité.thread/unarchiverestaure le rollout d’un thread archivé dans le répertoire des sessions actives.thread/compact/startdéclenche la compaction et renvoie immédiatement{}.thread/rollbackest obsolète. Il retire les N derniers tours du contexte en mémoire et enregistre un marqueur de restauration dans le journal JSONL persistant du thread.thread/inject_itemsajoute des éléments bruts de la Responses API à l’historique visible par le modèle d’un thread chargé sans démarrer de tour utilisateur.
Démarrer ou reprendre un thread
Démarrez un nouveau thread lorsque vous avez besoin d’une nouvelle conversation Codex.
{ "method": "thread/start", "id": 10, "params": {
"model": "gpt-5.6-terra",
"cwd": "/Users/me/project",
"approvalPolicy": "never",
"sandbox": "workspaceWrite",
"personality": "friendly",
"serviceName": "my_app_server_client"
} }
{ "id": 10, "result": {
"thread": {
"id": "thr_123",
"sessionId": "thr_123",
"preview": "",
"ephemeral": false,
"modelProvider": "openai",
"createdAt": 1730910000
}
} }
{ "method": "thread/started", "params": { "thread": { "id": "thr_123" } } }serviceName est facultatif. Définissez-le lorsque vous souhaitez que le serveur d’application associe aux métriques du thread le nom de service de votre intégration.
thread/start, thread/resume et thread/fork renvoient
instructionSources, un tableau de chemins de fichiers d’instructions chargés. Chaque chemin utilise
la syntaxe absolue native de son environnement source, y compris pour les environnements
distants.
Les clients expérimentaux peuvent définir historyMode sur thread/start avec la valeur "legacy"
(par défaut) ou "paginated". La création de threads paginés n’est pas encore prise en charge
et renvoie l’erreur JSON-RPC -32601. Le serveur d’application peut répertorier et lire les résumés des
enregistrements paginés existants, mais les lectures de l’historique complet, la pagination des tours et la reprise
échouent de manière sécurisée tant que l’historique paginé n’est pas pris en charge.
Les clients bêta qui activent capabilities.experimentalApi peuvent transmettre un identifiant de
profil d’autorisation nommé dans permissions au lieu de l’ancien champ sandbox.
N’envoyez pas permissions et sandbox ensemble. Utilisez
permissionProfile/list avec le cwd du projet pour découvrir les profils disponibles
et savoir si les exigences gérées autorisent chacun d’eux.
thread.sessionId identifie la racine de l’arborescence de sessions active actuelle. Les threads racines
utilisent leur propre identifiant de thread comme identifiant de session ; les threads dérivés conservent l’identifiant de session
de leur racine d’origine. Les clients doivent lire l’identifiant de session dans
thread.sessionId plutôt que de le déduire de l’identifiant de thread.
Pour poursuivre une session stockée, appelez thread/resume avec le thread.id que vous avez enregistré auparavant. La structure de la réponse correspond à thread/start. Vous pouvez également transmettre les mêmes remplacements de configuration que ceux pris en charge par thread/start, comme personality :
{ "method": "thread/resume", "id": 11, "params": {
"threadId": "thr_123",
"personality": "friendly"
} }
{ "id": 11, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false } } }La reprise d’un thread ne met pas à jour thread.updatedAt (ni l’heure de modification du fichier de rollout) à elle seule. L’horodatage est mis à jour lorsque vous démarrez un tour.
Si vous marquez un serveur MCP activé comme required dans la configuration et que l’initialisation de ce serveur échoue, thread/start et thread/resume échouent au lieu de continuer sans lui.
dynamicTools dans thread/start est un champ expérimental (nécessite capabilities.experimentalApi = true). Codex conserve ces outils dynamiques dans les métadonnées de rollout du thread et les restaure lors de thread/resume si vous ne fournissez pas de nouveaux outils dynamiques.
Si vous reprenez un thread avec un modèle différent de celui enregistré dans le rollout, Codex émet un avertissement et applique une instruction ponctuelle de changement de modèle au tour suivant.
Gérer l’objectif d’un thread
Utilisez thread/goal/set, thread/goal/get et thread/goal/clear pour gérer le
même état d’objectif persistant que celui présenté par /goal dans la TUI.
{ "method": "thread/goal/set", "id": 13, "params": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000
} }
{ "id": 13, "result": { "goal": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000,
"tokensUsed": 0,
"timeUsedSeconds": 0
} } }
{ "method": "thread/goal/updated", "params": {
"threadId": "thr_123",
"goal": {
"threadId": "thr_123",
"objective": "Finish the migration and keep tests green",
"status": "active",
"tokenBudget": 40000,
"tokensUsed": 0,
"timeUsedSeconds": 0
}
} }Les objectifs doivent être non vides et ne pas dépasser 4 000 caractères. Fournir un nouvel
objectif remplace l’objectif et réinitialise le suivi de l’utilisation. Fournir l’objectif actuel
non terminal, ou omettre objective, met à jour l’état ou le budget de jetons
tout en préservant l’historique d’utilisation.
Pour créer une branche à partir d’une session stockée, appelez thread/fork avec le thread.id. Cela crée un nouvel identifiant de thread et émet une notification thread/started correspondante. Transmettez
lastTurnId pour copier l’historique jusqu’à ce tour inclus et omettre les tours
suivants :
{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123", "lastTurnId": "turn_456" } }
{ "id": 12, "result": { "thread": { "id": "thr_456", "sessionId": "thr_123", "forkedFromId": "thr_123" } } }
{ "method": "thread/started", "params": { "thread": { "id": "thr_456" } } }Le serveur d’application rejette un lastTurnId en cours. Si vous omettez ce champ alors que le
thread source est au milieu d’un tour, la branche enregistre un marqueur d’interruption au lieu de
conserver un tour partiel non marqué.
Transmettez ephemeral: true pour créer une branche en mémoire sans l’ajouter aux listes
de threads stockés :
{
"method": "thread/fork",
"id": 13,
"params": {
"threadId": "thr_123",
"ephemeral": true
}
}
{
"id": 13,
"result": {
"thread": {
"id": "thr_789",
"sessionId": "thr_789",
"forkedFromId": "thr_123",
"ephemeral": true
}
}
}Les branches éphémères de threads paginés nécessitent également excludeTurns: true. Ce
champ est expérimental et nécessite capabilities.experimentalApi = true.
Lorsqu’un titre de thread visible par l’utilisateur a été défini, le serveur d’application renseigne thread.name dans les réponses thread/list, thread/read, thread/resume, thread/unarchive et thread/rollback. thread/start et thread/fork peuvent omettre name (ou renvoyer null) jusqu’à ce qu’un titre soit défini ultérieurement.
Lire un thread stocké (sans le reprendre)
Utilisez thread/read lorsque vous souhaitez obtenir les données d’un thread stocké sans le reprendre ni vous abonner à ses événements.
includeTurns- lorsqu’il vauttrue, la réponse inclut les tours du thread ; lorsqu’il vautfalseou est omis, vous obtenez uniquement le résumé du thread.- Les objets
threadrenvoyés incluent le champ d’exécutionstatus(notLoaded,idle,systemErrorouactiveavecactiveFlags).
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123", "includeTurns": true } }
{ "id": 19, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false, "status": { "type": "notLoaded" }, "turns": [] } } }Contrairement à thread/resume, thread/read ne charge pas le thread en mémoire et n’émet pas thread/started.
Répertorier les tours d’un thread
thread/turns/list est expérimental. Utilisez-le pour parcourir par pages l’historique des tours d’un thread stocké sans le reprendre. Par défaut, les résultats sont classés du plus récent au plus ancien afin que les clients puissent récupérer les tours plus anciens avec nextCursor. La réponse inclut également backwardsCursor ; transmettez-le comme cursor avec sortDirection: "asc" pour récupérer les tours plus récents que le premier élément de la page précédente.
itemsView contrôle la quantité de données des éléments de tour incluse dans la réponse :
notLoadedomet les éléments.summaryrenvoie des données résumées sur les éléments et constitue la valeur par défaut lorsqu’il est omis.fullrenvoie les données complètes des éléments.
{ "method": "thread/turns/list", "id": 20, "params": {
"threadId": "thr_123",
"limit": 50,
"sortDirection": "desc",
"itemsView": "summary"
} }
{ "id": 20, "result": {
"data": [],
"nextCursor": "older-turns-cursor-or-null",
"backwardsCursor": "newer-turns-cursor-or-null"
} }thread/items/list est également expérimental. Il parcourt par pages les éléments persistants sans
reprendre le thread. Transmettez turnId pour limiter les résultats à un seul tour, ou omettez-le
pour parcourir par pages les éléments de l’ensemble du thread. Le magasin de threads actif doit prendre en charge la
pagination des éléments ; sinon, le serveur renvoie une erreur indiquant que la méthode n’est pas prise en charge.
Répertorier les threads (avec pagination et filtres)
thread/list vous permet d’afficher une interface d’historique. Par défaut, les résultats sont classés du plus récent au plus ancien selon createdAt. Les filtres s’appliquent avant la pagination. Transmettez n’importe quelle combinaison des champs suivants :
cursor- chaîne opaque issue d’une réponse précédente ; omettez-la pour la première page.limit- le serveur utilise par défaut une taille de page raisonnable si ce champ n’est pas défini.sortKey-created_at(par défaut),updated_atourecency_at.sortDirection-desc(par défaut) ouasc.modelProviders- limite les résultats à des fournisseurs précis ; une valeur non définie, null ou un tableau vide inclut tous les fournisseurs.sourceKinds- limite les résultats à des sources de threads précises. Lorsqu’il est omis ou vaut[], le serveur utilise par défaut uniquement les sources interactives :clietvscode.archived- lorsqu’il vauttrue, répertorie uniquement les threads archivés. Lorsqu’il vautfalseou est omis, répertorie les threads non archivés (par défaut).isPinned- lorsqu’il est fourni, renvoie uniquement les threads dont l’état d’épinglage persistant correspond. Omettez-le pour renvoyer les threads épinglés et non épinglés.cwd- limite les résultats aux threads dont le répertoire de travail actuel de la session correspond exactement à ce chemin ou à l’un des chemins d’un tableau. Les chemins relatifs sont résolus à partir du répertoire de travail du processus du serveur d’application.useStateDbOnly- lorsqu’il vauttrue, renvoie les résultats de la base de données d’état sans analyser les journaux de threads JSONL pour réparer les métadonnées. Omettez-le ou transmettezfalsepour le comportement d’analyse et de réparation par défaut.searchTerm- limite les résultats aux threads dont le titre extrait contient ce fragment de texte sensible à la casse.parentThreadId- limite les résultats aux threads enfants directs du thread indiqué. Ce filtre est expérimental et nécessitecapabilities.experimentalApi = true.ancestorThreadId- limite les résultats aux descendants générés du thread indiqué, quelle que soit leur profondeur. Ce filtre est expérimental et nécessitecapabilities.experimentalApi = true; ne l’associez pas àparentThreadId.
sourceKinds accepte les valeurs suivantes :
clivscodeexecappServersubAgentsubAgentReviewsubAgentCompactsubAgentThreadSpawnsubAgentOtherunknown
Exemple :
{ "method": "thread/list", "id": 20, "params": {
"cursor": null,
"limit": 25,
"sortKey": "created_at"
} }
{ "id": 20, "result": {
"data": [
{ "id": "thr_a", "preview": "Create a TUI", "ephemeral": false, "isPinned": true, "modelProvider": "openai", "createdAt": 1730831111, "updatedAt": 1730831111, "name": "TUI prototype", "status": { "type": "notLoaded" } },
{ "id": "thr_b", "preview": "Fix tests", "ephemeral": false, "isPinned": false, "modelProvider": "openai", "createdAt": 1730750000, "updatedAt": 1730750000, "status": { "type": "notLoaded" } }
],
"nextCursor": "opaque-token-or-null"
} }Lorsque nextCursor vaut null, vous avez atteint la dernière page.
Mettre à jour les métadonnées stockées d’un thread
Utilisez thread/metadata/update pour modifier les métadonnées d’un thread stocké sans le reprendre.
Définissez isPinned pour épingler ou désépingler le thread, ou mettez à jour gitInfo pour modifier
les métadonnées Git persistantes. Les champs omis restent inchangés ; une valeur null explicite efface une
valeur de métadonnée Git stockée.
{ "method": "thread/metadata/update", "id": 21, "params": {
"threadId": "thr_123",
"isPinned": true,
"gitInfo": { "branch": "feature/sidebar-pr" }
} }
{ "id": 21, "result": {
"thread": {
"id": "thr_123",
"isPinned": true,
"gitInfo": { "sha": null, "branch": "feature/sidebar-pr", "originUrl": null }
}
} }Suivre les changements d’état d’un thread
thread/status/changed est émis chaque fois que l’état d’exécution d’un thread chargé change. La charge utile inclut threadId et le nouveau status.
{
"method": "thread/status/changed",
"params": {
"threadId": "thr_123",
"status": { "type": "active", "activeFlags": ["waitingOnApproval"] }
}
}Répertorier les threads chargés
thread/loaded/list renvoie les identifiants des threads actuellement chargés en mémoire.
{ "method": "thread/loaded/list", "id": 21 }
{ "id": 21, "result": { "data": ["thr_123", "thr_456"] } }Se désabonner d’un thread chargé
thread/unsubscribe supprime l’abonnement de la connexion actuelle à un thread. L’état de la réponse peut être :
unsubscribedlorsque la connexion était abonnée et ne l’est désormais plus.notSubscribedlorsque la connexion n’était pas abonnée à ce thread.notLoadedlorsque le thread n’est pas chargé.
S’il s’agissait du dernier abonné, le serveur conserve le thread chargé jusqu’à ce qu’il n’ait plus aucun abonné ni aucune activité pendant 30 minutes. À l’expiration du délai de grâce, le serveur d’application décharge le thread et émet une transition thread/status/changed vers notLoaded ainsi que thread/closed.
{ "method": "thread/unsubscribe", "id": 22, "params": { "threadId": "thr_123" } }
{ "id": 22, "result": { "status": "unsubscribed" } }Si le thread expire ensuite :
{ "method": "thread/status/changed", "params": {
"threadId": "thr_123",
"status": { "type": "notLoaded" }
} }
{ "method": "thread/closed", "params": { "threadId": "thr_123" } }Archiver un thread
Utilisez thread/archive pour déplacer le journal persistant du thread (stocké sous forme de fichier JSONL sur le disque) vers le répertoire des sessions archivées. L’archivage d’un thread tente également d’archiver les threads descendants générés qui ne le sont pas encore.
{ "method": "thread/archive", "id": 22, "params": { "threadId": "thr_b" } }
{ "id": 22, "result": {} }
{ "method": "thread/archived", "params": { "threadId": "thr_b" } }
{ "method": "thread/archived", "params": { "threadId": "thr_child" } }Les threads archivés n’apparaîtront pas dans les futurs appels à thread/list, sauf si vous transmettez archived: true. Le serveur émet une notification thread/archived pour chaque thread qu’il archive effectivement ; si un descendant généré ne peut pas être archivé, la requête peut tout de même réussir sans notification d’archivage pour ce descendant.
Supprimer un thread
Utilisez thread/delete pour supprimer définitivement un thread actif ou archivé persistant
ainsi que les threads descendants qu’il a créés. Le serveur supprime les fichiers de rollout existants et
les métadonnées associées avant de renvoyer un résultat positif ; les fichiers de rollout manquants sont considérés
comme déjà supprimés. Les threads racines éphémères ne peuvent pas être supprimés.
{ "method": "thread/delete", "id": 23, "params": { "threadId": "thr_b" } }
{ "id": 23, "result": {} }
{ "method": "thread/deleted", "params": { "threadId": "thr_b" } }
{ "method": "thread/deleted", "params": { "threadId": "thr_child" } }Désarchiver un thread
Utilisez thread/unarchive pour replacer le rollout d’un thread archivé dans le répertoire des sessions actives.
{ "method": "thread/unarchive", "id": 24, "params": { "threadId": "thr_b" } }
{ "id": 24, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes" } } }
{ "method": "thread/unarchived", "params": { "threadId": "thr_b" } }Déclencher la compaction d’un thread
Utilisez thread/compact/start pour déclencher manuellement la compaction de l’historique d’un thread. La requête renvoie immédiatement {}.
App-server émet la progression sous forme de notifications turn/* et item/* standard sur le même threadId, notamment le cycle de vie d’un élément contextCompaction (item/started puis item/completed).
{ "method": "thread/compact/start", "id": 25, "params": { "threadId": "thr_b" } }
{ "id": 25, "result": {} }Exécuter une commande shell dans un thread
Utilisez thread/shellCommand pour les commandes shell initiées par l’utilisateur qui appartiennent à un thread. La requête renvoie immédiatement {} tandis que la progression est diffusée au moyen des notifications turn/* et item/* standard.
Cette API s’exécute hors du bac à sable avec un accès complet et n’hérite pas de la politique de bac à sable du thread. Les clients ne doivent l’exposer que pour les commandes explicitement initiées par l’utilisateur.
Si le thread comporte déjà un tour actif, la commande s’exécute comme action auxiliaire de ce tour et sa sortie mise en forme est injectée dans le flux de messages du tour. Si le thread est inactif, app-server lance un tour autonome pour la commande shell.
Définissez timeoutMs pour limiter la durée d’exécution en millisecondes. Si vous l’omettez ou transmettez
null, la valeur par défaut d’une heure est utilisée. 0 demande une expiration immédiate du délai ; les valeurs
négatives sont rejetées. Le délai d’expiration ne retarde pas l’accusé de réception RPC immédiat.
{ "method": "thread/shellCommand", "id": 26, "params": { "threadId": "thr_b", "command": "git status --short", "timeoutMs": 10000 } }
{ "id": 26, "result": {} }Nettoyer les terminaux en arrière-plan
Utilisez thread/backgroundTerminals/clean pour arrêter tous les terminaux en arrière-plan en cours d’exécution associés à un thread. Cette méthode est expérimentale et nécessite capabilities.experimentalApi = true.
{ "method": "thread/backgroundTerminals/clean", "id": 27, "params": { "threadId": "thr_b" } }
{ "id": 27, "result": {} }Utilisez thread/backgroundTerminals/list pour examiner les terminaux en arrière-plan en cours d’exécution
pour un thread chargé. La requête prend en charge la pagination standard cursor et limit,
et la valeur processId renvoyée correspond à l’identifiant du processus app-server. Cette
méthode est expérimentale et nécessite capabilities.experimentalApi = true :
{ "method": "thread/backgroundTerminals/list", "id": 28, "params": { "threadId": "thr_b" } }
{ "id": 28, "result": { "data": [
{
"itemId": "item_456",
"processId": "42",
"command": "python3 -m http.server",
"cwd": "/workspace",
"osPid": null,
"cpuPercent": null,
"rssKb": null
}
], "nextCursor": null } }Utilisez thread/backgroundTerminals/terminate avec cette valeur processId pour arrêter un
terminal en arrière-plan. Cette méthode est expérimentale et nécessite
capabilities.experimentalApi = true :
{ "method": "thread/backgroundTerminals/terminate", "id": 29, "params": { "threadId": "thr_b", "processId": "42" } }
{ "id": 29, "result": { "terminated": true } }Annuler les tours récents
thread/rollback est obsolète et sera supprimé. Il retire les dernières
entrées numTurns du contexte en mémoire et conserve un marqueur d’annulation dans
le journal de rollout. La valeur thread renvoyée comprend turns renseigné après
l’annulation.
{ "method": "thread/rollback", "id": 30, "params": { "threadId": "thr_b", "numTurns": 1 } }
{ "id": 30, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes", "ephemeral": false } } }Tours
Le champ input accepte une liste d’éléments :
{ "type": "text", "text": "Explain this diff" }{ "type": "image", "url": "https://.../design.png" }{ "type": "localImage", "path": "/tmp/screenshot.png" }
Vous pouvez remplacer les paramètres de configuration pour chaque tour (modèle, effort, personnalité, cwd, politique de bac à sable, résumé). Lorsqu’ils sont spécifiés, ces paramètres deviennent les valeurs par défaut des tours suivants du même thread. outputSchema s’applique uniquement au tour actuel. Pour sandboxPolicy.type = "externalSandbox", définissez networkAccess sur restricted ou enabled ; pour workspaceWrite, networkAccess reste une valeur booléenne.
Pour turn/start.collaborationMode, settings.developer_instructions: null signifie « utiliser les instructions intégrées du mode sélectionné » et non supprimer les instructions du mode.
Accès en lecture du bac à sable (ReadOnlyAccess)
sandboxPolicy prend en charge des contrôles explicites de l’accès en lecture :
readOnly: valeuraccessfacultative ({ "type": "fullAccess" }par défaut, ou racines restreintes).workspaceWrite: valeurreadOnlyAccessfacultative ({ "type": "fullAccess" }par défaut, ou racines restreintes).
Structure de l’accès en lecture restreint :
{
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/Users/me/shared-read-only"]
}Sous macOS, includePlatformDefaults: true ajoute une politique Seatbelt prédéfinie propre à la plateforme pour les sessions à accès en lecture restreint. Cela améliore la compatibilité des outils sans autoriser largement l’intégralité de /System.
Exemples :
{ "type": "readOnly", "access": { "type": "fullAccess" } }{
"type": "workspaceWrite",
"writableRoots": ["/Users/me/project"],
"readOnlyAccess": {
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/Users/me/shared-read-only"]
},
"networkAccess": false
}Démarrer un tour
{ "method": "turn/start", "id": 30, "params": {
"threadId": "thr_123",
"input": [ { "type": "text", "text": "Run tests" } ],
"cwd": "/Users/me/project",
"approvalPolicy": "unlessTrusted",
"sandboxPolicy": {
"type": "workspaceWrite",
"writableRoots": ["/Users/me/project"],
"networkAccess": true
},
"model": "gpt-5.6-terra",
"effort": "medium",
"summary": "concise",
"personality": "friendly",
"outputSchema": {
"type": "object",
"properties": { "answer": { "type": "string" } },
"required": ["answer"],
"additionalProperties": false
}
} }
{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }Pour démarrer un tour avec la sortie d’un outil exécuté par votre client, transmettez toolOutput
avec un name non vide, un namespace facultatif et une chaîne output ou
un tableau d’éléments de contenu. Définissez input sur un tableau vide ; vous ne pouvez pas combiner
toolOutput avec une entrée utilisateur non vide.
{
"method": "turn/start",
"id": 31,
"params": {
"threadId": "thr_123",
"input": [],
"toolOutput": {
"name": "run_tests",
"namespace": null,
"output": "All 42 tests passed."
}
}
}La sortie demeure une sortie d’outil dans la conversation et apparaît comme un élément
functionCallOutput dans les notifications et l’historique persistant. Si un tour normal
est déjà actif, Codex place la sortie en file d’attente pour ce tour.
Injecter des éléments dans un thread
Utilisez thread/inject_items pour ajouter des éléments Responses API préconstruits à l’historique du prompt d’un thread chargé sans démarrer de tour utilisateur. Ces éléments sont conservés dans le rollout et inclus dans les requêtes ultérieures adressées au modèle.
{ "method": "thread/inject_items", "id": 31, "params": {
"threadId": "thr_123",
"items": [
{
"type": "message",
"role": "assistant",
"content": [{ "type": "output_text", "text": "Previously computed context." }]
}
]
} }
{ "id": 31, "result": {} }Orienter un tour actif
Utilisez turn/steer pour ajouter davantage d’entrées utilisateur au tour actif en cours.
- Incluez
expectedTurnId; sa valeur doit correspondre à l’identifiant du tour actif. - La requête échoue si le thread ne comporte aucun tour actif.
turn/steern’émet pas de nouvelle notificationturn/started.turn/steern’accepte pas les remplacements au niveau du tour (model,cwd,sandboxPolicyououtputSchema).
{ "method": "turn/steer", "id": 32, "params": {
"threadId": "thr_123",
"input": [ { "type": "text", "text": "Actually focus on failing tests first." } ],
"expectedTurnId": "turn_456"
} }
{ "id": 32, "result": { "turnId": "turn_456" } }Démarrer un tour (invoquer un skill)
Invoquez explicitement un skill en incluant $<skill-name> dans l’entrée textuelle et en ajoutant à ses côtés un élément d’entrée skill.
{ "method": "turn/start", "id": 33, "params": {
"threadId": "thr_123",
"input": [
{ "type": "text", "text": "$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage." },
{ "type": "skill", "name": "skill-creator", "path": "/Users/me/.codex/skills/skill-creator/SKILL.md" }
]
} }
{ "id": 33, "result": { "turn": { "id": "turn_457", "status": "inProgress", "items": [], "error": null } } }Interrompre un tour
{ "method": "turn/interrupt", "id": 31, "params": { "threadId": "thr_123", "turnId": "turn_456" } }
{ "id": 31, "result": {} }En cas de réussite, le tour se termine avec status: "interrupted".
Revue
review/start exécute l’outil de revue de Codex pour un thread et diffuse les éléments de la revue. Les cibles comprennent :
uncommittedChangesbaseBranch(diff par rapport à une branche)commit(revue d’un commit précis)custom(instructions libres)
Utilisez delivery: "inline" (valeur par défaut) pour exécuter la revue sur le thread existant, ou delivery: "detached" pour créer un nouveau thread de revue par dérivation.
Exemple de requête/réponse :
{ "method": "review/start", "id": 40, "params": {
"threadId": "thr_123",
"delivery": "inline",
"target": { "type": "commit", "sha": "1234567deadbeef", "title": "Polish tui colors" }
} }
{ "id": 40, "result": {
"turn": {
"id": "turn_900",
"status": "inProgress",
"items": [
{ "type": "userMessage", "id": "turn_900", "content": [ { "type": "text", "text": "Review commit 1234567: Polish tui colors" } ] }
],
"error": null
},
"reviewThreadId": "thr_123"
} }Pour une revue détachée, utilisez "delivery": "detached". La réponse possède la même structure, mais reviewThreadId correspond à l’identifiant du nouveau thread de revue (différent de la valeur threadId d’origine). Le serveur émet également une notification thread/started pour ce nouveau thread avant de diffuser le tour de revue.
Codex diffuse la notification turn/started habituelle, suivie d’un élément item/started contenant un élément enteredReviewMode :
{
"method": "item/started",
"params": {
"item": {
"type": "enteredReviewMode",
"id": "turn_900",
"review": "current changes"
}
}
}Lorsque l’outil de revue a terminé, le serveur émet item/started et item/completed contenant un élément exitedReviewMode avec le texte final de la revue :
{
"method": "item/completed",
"params": {
"item": {
"type": "exitedReviewMode",
"id": "turn_900",
"review": "Looks solid overall..."
}
}
}Utilisez cette notification pour afficher la sortie de l’outil de revue dans votre client.
Exécution de processus
process/* est une API expérimentale de contrôle explicite des processus. Elle nécessite
capabilities.experimentalApi = true et s’exécute hors du bac à sable de Codex. Utilisez-la
uniquement si votre client expose intentionnellement un contrôle local des processus sans
bac à sable.
Démarrez un processus avec process/spawn et fournissez un processHandle, puis utilisez
ce handle pour les requêtes d’entrée standard, de redimensionnement et d’arrêt. La sortie est diffusée au moyen des
notifications process/outputDelta et la fin de l’exécution au moyen de
process/exited.
{ "method": "process/spawn", "id": 48, "params": {
"command": ["python3", "-m", "pytest", "-q"],
"processHandle": "pytest-1",
"cwd": "/Users/me/project",
"tty": true
} }
{ "id": 48, "result": {} }
{ "method": "process/outputDelta", "params": {
"processHandle": "pytest-1",
"stream": "stdout",
"deltaBase64": "Li4u"
} }
{ "method": "process/exited", "params": {
"processHandle": "pytest-1",
"exitCode": 0
} }Utilisez process/writeStdin avec deltaBase64, closeStdin, ou les deux, pour envoyer
des entrées. Utilisez process/resizePty pour les événements de redimensionnement du PTY et process/kill pour
arrêter un processus en cours d’exécution.
Exécution de commandes
command/exec exécute une seule commande (tableau argv) dans le bac à sable du serveur sans créer de thread.
{ "method": "command/exec", "id": 50, "params": {
"command": ["ls", "-la"],
"cwd": "/Users/me/project",
"sandboxPolicy": { "type": "workspaceWrite" },
"timeoutMs": 10000
} }
{ "id": 50, "result": { "exitCode": 0, "stdout": "...", "stderr": "" } }Utilisez sandboxPolicy.type = "externalSandbox" si vous placez déjà le processus du serveur dans un bac à sable et souhaitez que Codex n’applique pas son propre bac à sable. Pour le mode de bac à sable externe, définissez networkAccess sur restricted (valeur par défaut) ou enabled. Pour readOnly et workspaceWrite, utilisez la même structure facultative access / readOnlyAccess que celle présentée ci-dessus.
Remarques :
- Le serveur rejette les tableaux
commandvides. sandboxPolicyaccepte la même structure que celle utilisée parturn/start(par exemple,dangerFullAccess,readOnly,workspaceWrite,externalSandbox).- Lorsqu’il est omis,
timeoutMsutilise la valeur par défaut du serveur. - Définissez
tty: truepour les sessions reposant sur un PTY, et utilisezprocessIdsi vous prévoyez d’envoyer ensuitecommand/exec/write,command/exec/resizeoucommand/exec/terminate. - Définissez
streamStdoutStderr: truepour recevoir des notificationscommand/exec/outputDeltapendant l’exécution de la commande.
Lire les exigences d’administration (configRequirements/read)
Utilisez configRequirements/read pour examiner les exigences d’administration effectives chargées depuis requirements.toml et/ou MDM.
{ "method": "configRequirements/read", "id": 52, "params": {} }
{ "id": 52, "result": {
"requirements": {
"allowedApprovalPolicies": ["onRequest", "unlessTrusted"],
"allowedSandboxModes": ["readOnly", "workspaceWrite"],
"featureRequirements": {
"personality": true,
"unified_exec": false
},
"network": {
"enabled": true,
"allowedDomains": ["api.openai.com"],
"allowUnixSockets": ["/tmp/example.sock"],
"dangerouslyAllowAllUnixSockets": false
}
}
} }result.requirements vaut null lorsqu’aucune exigence n’est configurée. Consultez la documentation sur requirements.toml pour en savoir plus sur les clés et valeurs prises en charge.
Configuration du bac à sable Windows (windowsSandbox/setupStart)
Les clients Windows personnalisés peuvent déclencher la configuration du bac à sable de manière asynchrone au lieu de bloquer lors des vérifications de démarrage.
{ "method": "windowsSandbox/setupStart", "id": 53, "params": { "mode": "elevated" } }
{ "id": 53, "result": { "started": true } }App-server lance la configuration en arrière-plan, puis émet ultérieurement une notification de fin :
{
"method": "windowsSandbox/setupCompleted",
"params": { "mode": "elevated", "success": true, "error": null }
}Modes :
elevated- exécute le processus de configuration avec élévation de privilèges du bac à sable Windows.unelevated- exécute l’ancien processus de configuration/vérification préalable.
Système de fichiers
Les API de système de fichiers v2 utilisent des chemins absolus. Utilisez fs/watch lorsqu’un client doit invalider l’état de l’interface utilisateur après la modification d’un fichier ou d’un répertoire.
{ "method": "fs/watch", "id": 54, "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
"path": "/Users/me/project/.git/HEAD"
} }
{ "id": 54, "result": { "path": "/Users/me/project/.git/HEAD" } }
{ "method": "fs/changed", "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
"changedPaths": ["/Users/me/project/.git/HEAD"]
} }
{ "method": "fs/unwatch", "id": 55, "params": {
"watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1"
} }
{ "id": 55, "result": {} }La surveillance d’un fichier émet fs/changed pour le chemin de ce fichier, y compris pour les mises à jour effectuées au moyen d’opérations de remplacement ou de renommage.
Événements
Les notifications d’événements constituent le flux initié par le serveur pour les cycles de vie des threads, des tours et de leurs éléments. Après avoir démarré ou repris un thread, continuez à lire le flux de transport actif pour recevoir les notifications thread/started, thread/archived, thread/unarchived, thread/closed, thread/status/changed, turn/*, item/* et serverRequest/resolved.
Désactivation des notifications
Les clients peuvent supprimer certaines notifications pour chaque connexion en envoyant leurs noms de méthode exacts dans initialize.params.capabilities.optOutNotificationMethods.
- Correspondance exacte uniquement :
item/agentMessage/deltane supprime que cette méthode. - Les noms de méthode inconnus sont ignorés.
- Cela s’applique aux notifications
thread/*,turn/*,item/*et aux notifications v2 associées actuelles. - Cela ne s’applique pas aux requêtes, aux réponses ni aux erreurs.
Événements de recherche approximative de fichiers (expérimental)
L’API de session de recherche approximative de fichiers émet des notifications pour chaque requête :
fuzzyFileSearch/sessionUpdated-{ sessionId, query, files }avec les correspondances actuelles de la requête active.fuzzyFileSearch/sessionCompleted-{ sessionId }une fois l’indexation et la recherche de correspondances terminées pour cette requête.
Événements d’avertissement
configWarning-{ summary, details?, path?, range? }pour les problèmes récupérables de configuration ou d’initialisation.warning-{ threadId?, message }pour les avertissements d’exécution non fatals.
Événements de configuration du bac à sable Windows
windowsSandbox/setupCompleted-{ mode, success, error }émis après la fin d’une requêtewindowsSandbox/setupStart.
Événements de tour
turn/started-{ turn }avec l’identifiant du tour, un champitemsvide etstatus: "inProgress".turn/completed-{ turn }oùturn.statusvautcompleted,interruptedoufailed; les échecs comportent{ error: { message, codexErrorInfo?, additionalDetails? } }.turn/diff/updated-{ threadId, turnId, diff }avec le dernier diff unifié agrégé de toutes les modifications de fichiers du tour.turn/plan/updated-{ turnId, explanation?, plan }chaque fois que l’agent partage ou modifie son plan ; chaque entréeplanest un élément{ step, status }dont la valeurstatusestpending,inProgressoucompleted.hook/startedethook/completed-{ threadId, turnId?, run }au démarrage d’un hook de cycle de vie synchrone et lorsque le résumé de son exécution finale est disponible. Ces notifications ne sont pas émises pour les hooks asynchrones.model/safetyBuffering/updated-{ threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel }lorsqu’une réponse entre dans une phase transitoire de mise en mémoire tampon de sécurité.model/rerouted-{ threadId, turnId, fromModel, toModel, reason }lorsque le service achemine une requête vers un autre modèle.model/verification-{ threadId, turnId, verifications }lorsque le service exige une vérification supplémentaire du compte.thread/tokenUsage/updated- mises à jour de l’utilisation pour le thread actif.
turn/diff/updated et turn/plan/updated comprennent actuellement des tableaux items vides, même lorsque des événements d’élément sont diffusés. Utilisez les notifications item/* comme source de vérité pour les éléments du tour.
Éléments
ThreadItem est l’union discriminée transmise dans les réponses des tours et les notifications item/*. Les types d’éléments courants comprennent :
userMessage-{id, content}oùcontentest une liste d’entrées utilisateur (text,imageoulocalImage).functionCallOutput-{id, name, namespace, output}pour une sortie d’outil autonome fournie viaturn/start.toolOutput.namespacepeut êtrenull.agentMessage-{id, text, phase?}contenant la réponse cumulée de l’agent. Lorsqu’il est présent,phaseutilise les valeurs de protocole de Responses API (commentary,final_answer).plan-{id, text}contenant le texte du plan proposé en mode plan. Considérez le dernier élémentplandeitem/completedcomme faisant autorité.reasoning-{id, summary, content}oùsummarycontient les résumés de raisonnement diffusés en continu etcontentles blocs de raisonnement bruts.commandExecution-{id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.fileChange-{id, changes, status}décrivant les modifications proposées ;changesrépertorie{path, kind, diff}.mcpToolCall-{id, server, tool, status, arguments, appContext?, pluginId?, result?, error?}. Pour les apps MCP approuvées,appContextpeut inclureconnectorId,linkId,resourceUri,appName,templateIdet la valeur stableactionNamedu connecteur. Les anciens éléments persistants peuvent omettre les métadonnées plus récentes. UtilisezappContext.resourceUrià la place du champ de niveau supérieurmcpAppResourceUri, désormais obsolète.dynamicToolCall-{id, tool, arguments, status, contentItems?, success?, durationMs?}pour les appels dynamiques d’outils exécutés par le client.collabToolCall-{id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.webSearch-{id, query, action?}pour les requêtes de recherche web émises par l’agent.imageView-{id, path}émis lorsque l’agent appelle l’outil de visualisation d’images.enteredReviewMode-{id, review}envoyé lorsque le réviseur démarre.exitedReviewMode-{id, review}émis lorsque le réviseur termine son travail.contextCompaction-{id}émis lorsque Codex compacte l’historique de la conversation.
Pour webSearch.action, l’action type peut être search (query?, queries?), openPage (url?) ou findInPage (url?, pattern?).
App-server rend obsolète l’ancienne notification thread/compacted ; utilisez plutôt l’élément contextCompaction.
Tous les éléments émettent deux événements de cycle de vie communs :
item/started- émet l’intégralité deitemau début d’une nouvelle unité de travail ; la valeuritem.idcorrespond à la valeuritemIdutilisée par les deltas.item/completed- envoie la valeuritemfinale une fois le travail terminé ; considérez-la comme l’état faisant autorité.
Deltas des éléments
item/agentMessage/delta- ajoute le texte diffusé au message de l’agent.item/plan/delta- diffuse le texte du plan proposé. L’élémentplanfinal peut ne pas correspondre exactement aux deltas concaténés.item/reasoning/summaryTextDelta- diffuse des résumés de raisonnement lisibles ;summaryIndexest incrémenté à l’ouverture de chaque nouvelle section du résumé.item/reasoning/summaryPartAdded- marque une limite entre les sections du résumé de raisonnement.item/reasoning/textDelta- diffuse le texte de raisonnement brut (lorsque le modèle le prend en charge).item/commandExecution/outputDelta- diffuse stdout/stderr pour une commande ; ajoutez les deltas dans l’ordre.item/fileChange/outputDelta- notification de compatibilité obsolète pour l’ancienne sortie textuelleapply_patch. Les versions actuelles d’app-server ne l’émettent plus ; utilisez les élémentsfileChangeetturn/diff/updatedà la place.
Erreurs
Si un tour échoue, le serveur émet un événement error avec { error: { message, codexErrorInfo?, additionalDetails? } }, puis termine le tour avec status: "failed". Lorsqu’un statut HTTP en amont est disponible, il apparaît dans codexErrorInfo.httpStatusCode.
Les valeurs codexErrorInfo courantes comprennent :
ContextWindowExceededUsageLimitExceededHttpConnectionFailed(erreurs 4xx/5xx en amont)ResponseStreamConnectionFailedResponseStreamDisconnectedResponseTooManyFailedAttemptsBadRequest,Unauthorized,SandboxError,InternalServerError,Other
Lorsqu’un statut HTTP en amont est disponible, le serveur le transmet dans httpStatusCode sur la variante codexErrorInfo concernée.
Approbations
Selon les paramètres Codex d’un utilisateur, l’exécution de commandes et les modifications de fichiers peuvent nécessiter une approbation. App-server envoie au client une requête JSON-RPC initiée par le serveur, et le client répond avec une charge utile de décision.
Décisions d’exécution de commandes :
accept,acceptForSession,decline,cancelou{ "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }.Décisions de modification de fichiers :
accept,acceptForSession,decline,cancel.Les requêtes comprennent
threadIdetturnId; utilisez-les pour limiter l’état de l’interface utilisateur à la conversation active.Le serveur reprend ou refuse le travail et termine l’élément avec
item/completed.
Approbations d’exécution de commandes
Ordre des messages :
item/startedaffiche l’élémentcommandExecutionen attente aveccommand,cwdet d’autres champs.item/commandExecution/requestApprovalcomprenditemId,threadId,turnId, le champ facultatifreason, le champ facultatifcommand, le champ facultatifcwd, le champ facultatifcommandActions, le champ facultatifproposedExecpolicyAmendment, le champ facultatifnetworkApprovalContextet le champ facultatifavailableDecisions. Lorsqueinitialize.params.capabilities.experimentalApi = true, la charge utile peut également inclure le champ expérimentaladditionalPermissionsdécrivant l’accès au bac à sable demandé pour chaque commande. Tous les chemins de système de fichiers dansadditionalPermissionssont absolus lors de la transmission.- Le client répond avec l’une des décisions d’approbation d’exécution de commandes ci-dessus.
serverRequest/resolvedconfirme que la requête en attente a reçu une réponse ou a été effacée.item/completedrenvoie l’élémentcommandExecutionfinal avecstatus: completed | failed | declined.
Lorsque networkApprovalContext est présent, l’invite concerne l’accès réseau géré (et non l’approbation générale d’une commande shell). Le schéma v2 actuel expose la cible host et protocol ; les clients doivent afficher une invite propre au réseau et ne pas supposer que command constitue un aperçu de commande shell compréhensible pour l’utilisateur.
Codex regroupe les invites d’approbation réseau simultanées par destination (host, protocole et port). App-server peut donc envoyer une seule invite qui débloque plusieurs requêtes en attente vers la même destination, tandis que des ports différents sur le même hôte sont traités séparément.
Approbations de modification de fichiers
Ordre des messages :
item/startedémet un élémentfileChangeavec les valeurschangesetstatus: "inProgress"proposées.item/fileChange/requestApprovalcomprenditemId,threadId,turnId, le champ facultatifreasonet le champ facultatifgrantRoot.- Le client répond avec l’une des décisions d’approbation de modification de fichiers ci-dessus.
serverRequest/resolvedconfirme que la requête en attente a reçu une réponse ou a été effacée.item/completedrenvoie l’élémentfileChangefinal avecstatus: completed | failed | declined.
tool/requestUserInput
Lorsque le client répond à item/tool/requestUserInput, app-server émet serverRequest/resolved avec { threadId, requestId }. Si la requête en attente est effacée au démarrage, à la fin ou à l’interruption du tour avant que le client ne réponde, le serveur émet la même notification pour ce nettoyage.
Les paramètres de la requête comprennent autoResolutionMs sous forme de délai d’expiration entier en millisecondes ou
null. Lorsqu’il est présent, les clients hôtes peuvent résoudre automatiquement l’invite après cet
intervalle si l’utilisateur ne répond pas.
Demandes d’autorisation
L’outil intégré request_permissions envoie
item/permissions/requestApproval avec threadId, turnId, itemId,
environmentId, cwd, la valeur facultative reason et les autorisations réseau ou de système de fichiers
demandées. Répondez avec permissions en indiquant uniquement le sous-ensemble accordé.
Définissez scope sur "session" pour conserver l’autorisation pour les tours suivants de la même
session ; omettez-le ou utilisez "turn" pour une autorisation limitée au tour. Les autorisations
qui n’ont pas été demandées sont ignorées.
Demandes de sollicitation du serveur MCP
Un serveur MCP peut interrompre un tour avec mcpServer/elicitation/request. La
requête comprend threadId, une valeur facultative turnId, serverName et l’une des
structures de requête suivantes :
mode: "form"oumode: "openai/form", avecmessageetrequestedSchema.mode: "url", avecmessage,urletelicitationId.
Répondez avec action: "accept" et la valeur content demandée, ou avec
action: "decline" ou "cancel" et content: null. App-server émet ensuite
serverRequest/resolved. Pour recevoir la variante openai/form, activez-la avec
initialize.params.capabilities.mcpServerOpenaiFormElicitation.
Appels d’outils dynamiques (expérimental)
dynamicTools sur thread/start et le flux de requête ou de réponse item/tool/call correspondant sont des API expérimentales.
Les noms d’outils dynamiques et d’espaces de noms doivent respecter les contraintes de nommage de Responses API. Évitez les noms d’espaces de noms réservés utilisés par les outils intégrés de Codex.
Lorsqu’un outil dynamique est invoqué pendant un tour, app-server émet :
item/startedavecitem.type = "dynamicToolCall",status = "inProgress", ainsi quetooletarguments.item/tool/callsous forme de requête du serveur au client.- La charge utile de réponse du client avec les éléments de contenu renvoyés.
item/completedavecitem.type = "dynamicToolCall", la valeurstatusfinale et toute valeurcontentItemsousuccessrenvoyée.
Approbations d’appels d’outils MCP (apps)
Les appels d’outils d’une app (connecteur) peuvent également nécessiter une approbation. Lorsqu’un appel d’outil d’une app produit des effets secondaires, le serveur peut solliciter une approbation avec tool/requestUserInput et des options telles que Accepter, Refuser et Annuler. Les annotations d’outils destructifs déclenchent toujours une approbation, même si l’outil annonce également des indications de privilèges moindres. Si l’utilisateur refuse ou annule, l’élément mcpToolCall associé se termine par une erreur au lieu d’exécuter l’outil.
Skills
Invoquez un skill en incluant $<skill-name> dans l’entrée textuelle de l’utilisateur. Ajoutez un élément d’entrée skill (recommandé) afin que le serveur injecte les instructions complètes du skill au lieu de laisser le modèle résoudre son nom.
{
"method": "turn/start",
"id": 101,
"params": {
"threadId": "thread-1",
"input": [
{
"type": "text",
"text": "$skill-creator Add a new skill for triaging flaky CI."
},
{
"type": "skill",
"name": "skill-creator",
"path": "/Users/me/.codex/skills/skill-creator/SKILL.md"
}
]
}
}Si vous omettez l’élément skill, le modèle analysera tout de même le marqueur $<skill-name> et tentera de localiser le skill, ce qui peut augmenter la latence.
Exemple :
$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage.Utilisez skills/list pour récupérer les skills disponibles (éventuellement limités par cwds, avec forceReload). Vous pouvez également inclure perCwdExtraUserRoots afin d’analyser des chemins absolus supplémentaires comme portée user pour certaines valeurs cwd. App-server ignore les entrées dont la valeur cwd n’est pas présente dans cwds. skills/list peut réutiliser un résultat mis en cache pour chaque cwd ; définissez forceReload: true pour actualiser les données depuis le disque. Lorsqu’ils sont présents, le serveur lit interface et dependencies depuis SKILL.json.
{ "method": "skills/list", "id": 25, "params": {
"cwds": ["/Users/me/project", "/Users/me/other-project"],
"forceReload": true,
"perCwdExtraUserRoots": [
{
"cwd": "/Users/me/project",
"extraUserRoots": ["/Users/me/shared-skills"]
}
]
} }
{ "id": 25, "result": {
"data": [{
"cwd": "/Users/me/project",
"skills": [
{
"name": "skill-creator",
"description": "Create or update a Codex skill",
"enabled": true,
"interface": {
"displayName": "Skill Creator",
"shortDescription": "Create or update a Codex skill"
},
"dependencies": {
"tools": [
{
"type": "env_var",
"value": "GITHUB_TOKEN",
"description": "GitHub API token"
},
{
"type": "mcp",
"value": "github",
"transport": "streamable_http",
"url": "https://example.com/mcp"
}
]
}
}
],
"errors": []
}]
} }Le serveur émet également des notifications skills/changed lorsque les fichiers locaux surveillés d’un skill changent. Considérez-les comme un signal d’invalidation et réexécutez skills/list avec vos paramètres actuels lorsque cela est nécessaire.
Pour activer ou désactiver un skill à partir de son chemin :
{
"method": "skills/config/write",
"id": 26,
"params": {
"path": "/Users/me/.codex/skills/skill-creator/SKILL.md",
"enabled": false
}
}Apps (connecteurs)
Utilisez app/installed pour lire le dernier instantané validé de l’environnement d’exécution des apps installées.
Chaque résultat comprend la valeur id de l’app, runtimeName (ou null), l’état
effectif enabled et l’état callable. Une app peut être appelée uniquement lorsque sa
configuration effective l’active et qu’au moins un outil visible par le modèle respecte les
politiques de l’app et des outils.
{
"method": "app/installed",
"id": 49,
"params": {
"threadId": "thread-1",
"forceRefresh": false
}
}
{
"id": 49,
"result": {
"apps": [
{
"id": "demo-app",
"runtimeName": "Demo App",
"enabled": true,
"callable": true
}
]
}
}Omettez threadId pour utiliser la configuration globale au lieu de celle d’un thread
chargé. Définissez forceRefresh: true pour actualiser l’instantané de l’environnement d’exécution du connecteur
avant de le lire. Lorsque la politique globale ou celle de l’espace de travail bloque l’accès à l’app,
une app observée peut tout de même apparaître avec enabled et callable définis sur false.
Utilisez app/list pour récupérer les apps disponibles. Dans le CLI/TUI, /apps est le sélecteur présenté à l’utilisateur ; dans les clients personnalisés, appelez directement app/list. Chaque entrée comprend à la fois isAccessible (disponible pour l’utilisateur) et isEnabled (activée dans config.toml), afin que les clients puissent distinguer l’installation/l’accès de l’état d’activation local. Les entrées d’app peuvent également inclure les champs facultatifs branding, appMetadata et labels.
{ "method": "app/list", "id": 50, "params": {
"cursor": null,
"limit": 50,
"threadId": "thread-1",
"forceRefetch": false
} }
{ "id": 50, "result": {
"data": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"logoUrl": "https://example.com/demo-app.png",
"logoUrlDark": null,
"distributionChannel": null,
"branding": null,
"appMetadata": null,
"labels": null,
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
"isAccessible": true,
"isEnabled": true
}
],
"nextCursor": null
} }Si vous fournissez threadId, le contrôle d’accès aux fonctionnalités de l’app (features.apps) utilise l’instantané de configuration de ce thread. Lorsqu’il est omis, app-server utilise la dernière configuration globale.
app/list renvoie un résultat une fois les apps accessibles et celles du répertoire chargées. Définissez forceRefetch: true pour contourner les caches d’apps et récupérer des données à jour. Les entrées du cache ne sont remplacées que lorsque les actualisations réussissent.
Le serveur émet également des notifications app/list/updated chaque fois que le chargement de l’une des sources (apps accessibles ou apps du répertoire) se termine. Chaque notification comprend la dernière liste fusionnée des apps.
{
"method": "app/list/updated",
"params": {
"data": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"logoUrl": "https://example.com/demo-app.png",
"logoUrlDark": null,
"distributionChannel": null,
"branding": null,
"appMetadata": null,
"labels": null,
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
"isAccessible": true,
"isEnabled": true
}
]
}
}Utilisez app/read lorsque vous connaissez déjà les identifiants des apps et avez besoin de leurs métadonnées plutôt
que de l’état de leur environnement d’exécution installé. Transmettez au maximum 100 valeurs appIds. Le serveur ne conserve que
la première occurrence de chaque identifiant répété et préserve cet ordre dans
apps et missingAppIds. Les apps inconnues ou inaccessibles sont renvoyées dans
missingAppIds sans faire échouer l’ensemble de la requête.
{
"method": "app/read",
"id": 52,
"params": {
"appIds": ["demo-app", "missing-app"],
"includeTools": true
}
}
{
"id": 52,
"result": {
"apps": [
{
"id": "demo-app",
"name": "Demo App",
"description": "Example connector for documentation.",
"iconUrl": null,
"iconUrlDark": null,
"distributionChannel": null,
"installUrl": null,
"pluginDisplayNames": [],
"toolSummaries": [
{
"name": "search",
"title": "Search",
"description": "Search the app.",
"isEnabled": true,
"disabledReason": null,
"isReadOnly": true
}
]
}
],
"missingAppIds": ["missing-app"]
}
}Définissez includeTools: true pour demander des résumés publics des outils destinés uniquement à l’affichage. La
réponse de métadonnées n’inclut pas l’état de l’environnement d’exécution de l’app installée et n’autorise pas
un appel d’outil ; utilisez app/installed pour vérifier les états effectifs enabled et callable.
Invoquez une app en insérant $<app-slug> dans l’entrée textuelle et en ajoutant un élément d’entrée mention avec le chemin app://<id> (recommandé).
{
"method": "turn/start",
"id": 51,
"params": {
"threadId": "thread-1",
"input": [
{
"type": "text",
"text": "$demo-app Pull the latest updates from the team."
},
{
"type": "mention",
"name": "Demo App",
"path": "app://demo-app"
}
]
}
}Exemples de RPC de configuration pour les paramètres d’apps
Utilisez config/read, config/value/write et config/batchWrite pour examiner ou mettre à jour les contrôles des apps dans config.toml.
Lisez la structure de configuration effective des apps (y compris _default et les remplacements propres à chaque outil) :
{ "method": "config/read", "id": 60, "params": { "includeLayers": false } }
{ "id": 60, "result": {
"config": {
"apps": {
"_default": {
"enabled": true,
"destructive_enabled": true,
"open_world_enabled": true,
"approvals_reviewer": "user",
"default_tools_approval_mode": "auto"
},
"google_drive": {
"enabled": true,
"destructive_enabled": false,
"approvals_reviewer": "auto_review",
"default_tools_approval_mode": "prompt",
"tools": {
"files/delete": { "enabled": false, "approval_mode": "approve" }
}
}
}
}
} }apps._default.approvals_reviewer définit l’outil de revue pour toutes les apps, sauf si une
valeur propre à une app la remplace. Lorsque les deux sont omises, l’app hérite de
la valeur de premier niveau approvals_reviewer. apps._default.default_tools_approval_mode
définit le mode d’approbation de secours pour les outils qui ne comportent aucun remplacement propre à l’app ou à l’outil.
Les exigences gérées en matière de mode d’approbation remplacent les paramètres du mode d’approbation des outils.
Mettez à jour un seul paramètre d’app :
{
"method": "config/value/write",
"id": 61,
"params": {
"keyPath": "apps.google_drive.default_tools_approval_mode",
"value": "prompt",
"mergeStrategy": "replace"
}
}Appliquez plusieurs modifications d’app de manière atomique :
{
"method": "config/batchWrite",
"id": 62,
"params": {
"edits": [
{
"keyPath": "apps._default.destructive_enabled",
"value": false,
"mergeStrategy": "upsert"
},
{
"keyPath": "apps.google_drive.tools.files/delete.approval_mode",
"value": "approve",
"mergeStrategy": "upsert"
}
]
}
}Détecter et importer la configuration d’un agent externe
Utilisez externalAgentConfig/detect pour découvrir les artefacts d’agents externes qui peuvent être migrés, puis transmettez les entrées sélectionnées à externalAgentConfig/import.
Exemple de détection :
{ "method": "externalAgentConfig/detect", "id": 63, "params": {
"includeHome": true,
"cwds": ["/Users/me/project"]
} }
{ "id": 63, "result": {
"items": [
{
"itemType": "AGENTS_MD",
"description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
"cwd": "/Users/me/project"
},
{
"itemType": "SKILLS",
"description": "Copy skill folders from /Users/me/.claude/skills to /Users/me/.agents/skills.",
"cwd": null
}
]
} }Exemple d’importation :
{ "method": "externalAgentConfig/import", "id": 64, "params": {
"migrationItems": [
{
"itemType": "AGENTS_MD",
"description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
"cwd": "/Users/me/project"
}
],
"source": "claude-code"
} }
{ "id": 64, "result": { "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868" } }Le paramètre d’importation facultatif de premier niveau source indique le produit qui
a généré les éléments de migration sélectionnés.
Le serveur émet externalAgentConfig/import/progress à mesure que les types d’éléments sont traités,
et externalAgentConfig/import/completed une fois toutes les importations synchrones et en arrière-plan
terminées. Ces notifications comprennent la même valeur importId que la
réponse ainsi que itemTypeResults avec les valeurs successes et failures propres à chaque type.
La notification de fin peut arriver immédiatement après la réponse ou une fois les importations distantes
en arrière-plan terminées.
{ "method": "externalAgentConfig/import/progress", "params": {
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"itemTypeResults": [
{
"itemType": "AGENTS_MD",
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
]
} }
{ "method": "externalAgentConfig/import/completed", "params": {
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"itemTypeResults": [
{
"itemType": "AGENTS_MD",
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
]
} }Lire les importations déjà terminées :
{ "method": "externalAgentConfig/import/readHistories", "id": 65 }
{ "id": 65, "result": { "data": [
{
"importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
"completedAtMs": 1781784000000,
"successes": [
{ "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
],
"failures": []
}
] } }Les valeurs itemType prises en charge sont AGENTS_MD, CONFIG, SKILLS, PLUGINS,
MCP_SERVER_CONFIG, SUBAGENTS, HOOKS, COMMANDS et SESSIONS. Pour les
éléments PLUGINS, details.plugins répertorie chaque marketplaceName et la valeur
pluginNames que Codex peut tenter de migrer. La détection ne renvoie que les éléments qui
nécessitent encore une intervention. Par exemple, Codex ignore la migration AGENTS lorsque AGENTS.md
existe déjà et n’est pas vide, et les importations de skills ne remplacent pas les
répertoires de skills existants.
Lors de la détection de plugins depuis .claude/settings.json, Codex lit les sources
de marketplaces configurées dans extraKnownMarketplaces. Si enabledPlugins contient
des plugins provenant de claude-plugins-official mais que la source de la marketplace est absente,
Codex déduit que anthropics/claude-plugins-official est la source.
Points de terminaison d’authentification
La surface JSON-RPC d’authentification et de compte expose des méthodes de requête/réponse ainsi que des notifications initiées par le serveur (sans id). Utilisez-les pour déterminer l’état d’authentification, démarrer ou annuler des connexions, se déconnecter, examiner les limites de débit de ChatGPT et informer les propriétaires d’un espace de travail lorsque les crédits ou les limites d’utilisation sont épuisés.
Modes d’authentification
Codex prend en charge les modes d’authentification suivants. account/updated.authMode indique le mode actif et comprend la valeur ChatGPT planType actuelle lorsqu’elle est disponible. account/read fournit également des informations sur le compte et l’abonnement.
- API key (
apikey) - l’appelant fournit une API key OpenAI avectype: "apiKey", et Codex la stocke pour les requêtes API. - Géré par ChatGPT (
chatgpt) - Codex gère le flux OAuth de ChatGPT, conserve les jetons et les actualise automatiquement. Commencez avectype: "chatgpt"pour le flux par navigateur outype: "chatgptDeviceCode"pour le flux par code d’appareil. - Jetons ChatGPT externes (
chatgptAuthTokens) - mode expérimental destiné aux applications hôtes qui gèrent déjà le cycle de vie de l’authentification ChatGPT de l’utilisateur. L’application hôte fournit directement unaccessToken, unchatgptAccountIdet, facultativement, unchatgptPlanType, puis doit actualiser le jeton sur demande. - Amazon Bedrock -
account/readsignale les comptes Bedrock sous la formetype: "amazonBedrock"et indique si les identifiants proviennent d’une API key Bedrock gérée par Codex (credentialSource: "codexManaged") ou de la chaîne externe d’identifiants AWS (credentialSource: "awsManaged").account/updated.authModeutilisebedrockApiKeypour les API keys Bedrock gérées par Codex.
Vue d’ensemble de l’API
account/read- récupère les informations actuelles du compte ; peut éventuellement actualiser les jetons.account/login/start- démarre la connexion (apiKey,chatgpt,chatgptDeviceCodeou le mode expérimentalchatgptAuthTokens).account/login/completed(notification) - émise lorsqu’une tentative de connexion se termine (réussite ou erreur).account/login/cancel- annule une connexion ChatGPT gérée en attente à l’aide deloginId.account/logout- déconnecte l’utilisateur ; déclencheaccount/updated.account/updated(notification) - émise chaque fois que le mode d’authentification change (authMode:apikey,chatgpt,chatgptAuthTokens,agentIdentity,personalAccessToken,bedrockApiKeyounull) et comprendplanTypelorsqu’il est disponible.account/chatgptAuthTokens/refresh(requête du serveur) - demande de nouveaux jetons ChatGPT gérés en externe après une erreur d’autorisation.account/rateLimits/read- récupère les limites de débit de ChatGPT.account/rateLimits/updated(notification) - émise chaque fois que les limites de débit ChatGPT d’un utilisateur changent.account/sendAddCreditsNudgeEmail- demande à ChatGPT d’envoyer un e-mail au propriétaire d’un espace de travail lorsque les crédits sont épuisés ou qu’une limite d’utilisation est atteinte.account/rateLimitResetCredit/consume- utilise une réinitialisation de limite de débit acquise avec une valeuridempotencyKeyfournie par l’appelant.account/usage/read- récupère les résumés de l’activité des jetons du compte ChatGPT et les compartiments quotidiens.account/workspaceMessages/read- récupère les messages actifs de l’espace de travail, y compris les titres de notification lorsqu’ils sont disponibles.mcpServer/oauthLogin/completed(notification) - émise à la fin d’un fluxmcpServer/oauth/login; la charge utile comprend{ name, threadId, success, error? }.threadIdpeut valoirnullpour les flux OAuth limités à une app ou à un plugin.mcpServer/startupStatus/updated(notification) - émise lorsque l’état de démarrage d’un serveur MCP configuré change ; la charge utile comprend{ threadId, name, status, error, failureReason }.threadIdvautnullpour un démarrage limité à une app. En cas d’échec du démarrage,failureReason: "reauthenticationRequired"signifie que les identifiants OAuth stockés ont expiré et n’ont pas pu être actualisés ; le client doit alors proposer de reconnecter le serveur.
1) Vérifier l’état d’authentification
Requête :
{ "method": "account/read", "id": 1, "params": { "refreshToken": false } }Exemples de réponses :
{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": false } }{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": true } }{
"id": 1,
"result": { "account": { "type": "apiKey" }, "requiresOpenaiAuth": true }
}{
"id": 1,
"result": {
"account": {
"type": "amazonBedrock",
"credentialSource": "codexManaged"
},
"requiresOpenaiAuth": false
}
}{
"id": 1,
"result": {
"account": {
"type": "amazonBedrock",
"credentialSource": "awsManaged"
},
"requiresOpenaiAuth": false
}
}{
"id": 1,
"result": {
"account": {
"type": "chatgpt",
"email": "user@example.com",
"planType": "pro"
},
"requiresOpenaiAuth": true
}
}Remarques sur les champs :
refreshToken(valeur booléenne) : définisseztruepour forcer l’actualisation d’un jeton en mode ChatGPT géré. En mode de jetons externes (chatgptAuthTokens), app-server ignore cet indicateur.emailvautnulllorsque le compte ChatGPT ne possède pas d’adresse e-mail.requiresOpenaiAuthindique le fournisseur actif ; lorsque sa valeur estfalse, Codex peut s’exécuter sans identifiants OpenAI.- Amazon Bedrock renvoie
credentialSource: "codexManaged"lorsqu’il utilise une API key Bedrock gérée par Codex. Il renvoiecredentialSource: "awsManaged"pour le chemin externe des identifiants AWS. Cela indique la source d’identifiants sélectionnée, mais ne vérifie pas si la chaîne d’identifiants AWS peut résoudre des identifiants.
2) Se connecter avec une API key
- Envoyez :
{
"method": "account/login/start",
"id": 2,
"params": { "type": "apiKey", "apiKey": "sk-..." }
}- Résultat attendu :
{ "id": 2, "result": { "type": "apiKey" } }- Notifications :
{
"method": "account/login/completed",
"params": { "loginId": null, "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "apikey", "planType": null }
}3) Se connecter avec ChatGPT (flux par navigateur)
- Démarrez :
{
"method": "account/login/start",
"id": 3,
"params": {
"type": "chatgpt",
"useHostedLoginSuccessPage": true,
"appBrand": "chatgpt"
}
} Par défaut, un rappel de navigateur réussi redirige vers une page locale confirmant la réussite.
Définissez useHostedLoginSuccessPage: true pour utiliser la page de réussite hébergée lorsque
la configuration de l’organisation n’est pas requise. Lorsque la page de réussite hébergée est activée, appBrand
peut valoir "codex" ou "chatgpt" ; les valeurs omises ou null utilisent par défaut
"codex".
{
"id": 3,
"result": {
"type": "chatgpt",
"loginId": "<uuid>",
"authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback"
}
}- Ouvrez
authUrldans un navigateur ; app-server héberge le rappel local. - Attendez les notifications :
{
"method": "account/login/completed",
"params": { "loginId": "<uuid>", "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgpt", "planType": "plus" }
}3b) Se connecter avec ChatGPT (flux par code d’appareil)
Utilisez ce flux lorsque votre client gère la procédure de connexion ou lorsqu’un rappel de navigateur manque de fiabilité.
- Démarrez :
{
"method": "account/login/start",
"id": 4,
"params": { "type": "chatgptDeviceCode" }
} {
"id": 4,
"result": {
"type": "chatgptDeviceCode",
"loginId": "<uuid>",
"verificationUrl": "https://auth.openai.com/codex/device",
"userCode": "ABCD-1234"
}
}- Présentez
verificationUrletuserCodeà l’utilisateur ; l’interface gère l’expérience utilisateur. - Attendez les notifications :
{
"method": "account/login/completed",
"params": { "loginId": "<uuid>", "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgpt", "planType": "plus" }
}3c) Se connecter avec des jetons ChatGPT gérés en externe (chatgptAuthTokens)
Utilisez ce mode expérimental uniquement lorsqu’une application hôte gère le cycle de vie de l’authentification ChatGPT de l’utilisateur et fournit directement les jetons. Les clients doivent définir capabilities.experimentalApi = true pendant initialize avant d’utiliser ce type de connexion.
- Envoyez :
{
"method": "account/login/start",
"id": 7,
"params": {
"type": "chatgptAuthTokens",
"accessToken": "<jwt>",
"chatgptAccountId": "org-123",
"chatgptPlanType": "business"
}
}- Résultat attendu :
{ "id": 7, "result": { "type": "chatgptAuthTokens" } }- Notifications :
{
"method": "account/login/completed",
"params": { "loginId": null, "success": true, "error": null }
} {
"method": "account/updated",
"params": { "authMode": "chatgptAuthTokens", "planType": "business" }
}Lorsque le serveur reçoit un 401 Unauthorized, il peut demander des jetons actualisés à l’application hôte :
{
"method": "account/chatgptAuthTokens/refresh",
"id": 8,
"params": { "reason": "unauthorized", "previousAccountId": "org-123" }
}
{ "id": 8, "result": { "accessToken": "<jwt>", "chatgptAccountId": "org-123", "chatgptPlanType": "business" } }Le serveur réessaie la requête d’origine après une réponse d’actualisation réussie. Les requêtes expirent après environ 10 secondes.
4) Annuler une connexion ChatGPT
{ "method": "account/login/cancel", "id": 4, "params": { "loginId": "<uuid>" } }
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": false, "error": "..." } }5) Se déconnecter
{ "method": "account/logout", "id": 5 }
{ "id": 5, "result": {} }
{ "method": "account/updated", "params": { "authMode": null, "planType": null } }6) Limites de débit (ChatGPT)
{ "method": "account/rateLimits/read", "id": 6 }
{ "id": 6, "result": {
"rateLimits": {
"limitId": "codex",
"limitName": null,
"primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
"secondary": null,
"rateLimitReachedType": null
},
"rateLimitsByLimitId": {
"codex": {
"limitId": "codex",
"limitName": null,
"primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
"secondary": null,
"rateLimitReachedType": null
},
"codex_other": {
"limitId": "codex_other",
"limitName": "codex_other",
"primary": { "usedPercent": 42, "windowDurationMins": 60, "resetsAt": 1730950800 },
"secondary": null,
"rateLimitReachedType": null
}
},
"rateLimitResetCredits": {
"availableCount": 2,
"credits": [{
"id": "RateLimitResetCredit_1",
"resetType": "codexRateLimits",
"status": "available",
"grantedAt": 1781654400,
"expiresAt": 1784246400,
"title": "Rate-limit reset",
"description": "Reset an eligible Codex rate-limit window."
}]
}
} }
{ "method": "account/rateLimits/updated", "params": {
"rateLimits": {
"limitId": "codex",
"primary": { "usedPercent": 31, "windowDurationMins": 15, "resetsAt": 1730948100 }
}
} }Remarques sur les champs :
rateLimitsest la vue à compartiment unique assurant la rétrocompatibilité.rateLimitsByLimitId(lorsqu’il est présent) est la vue multicompartiment indexée par la valeur mesuréelimit_id(par exemplecodex).limitIdest l’identifiant du compartiment mesuré.limitNameest un libellé facultatif destiné à l’utilisateur pour ce compartiment.usedPercentcorrespond à l’utilisation actuelle dans la fenêtre de quota.windowDurationMinscorrespond à la durée de la fenêtre de quota.resetsAtest un horodatage Unix (en secondes) de la prochaine réinitialisation.planTypeest inclus lorsque le serveur renvoie l’abonnement ChatGPT associé à un compartiment.creditsest inclus lorsque le serveur renvoie le détail des crédits restants de l’espace de travail.rateLimitReachedTypeindique l’état de limite classifié par le serveur lorsqu’une limite a été atteinte.rateLimitResetCreditscontient le nombre de réinitialisations acquises disponibles lorsque le service le fournit ; sinon, sa valeur estnull.rateLimitResetCredits.creditsvautnulllorsque seul le nombre est connu. Un tableau vide signifie que le service a récupéré les détails et n’a renvoyé aucun crédit disponible. Le service peut limiter le nombre de lignes de détail ;availableCountfait donc autorité.- Chaque ligne de détail comprend une valeur opaque
id,resetType,status,grantedAt,expiresAt(qui peut valoirnull),title(qui peut valoirnull) etdescription(qui peut valoirnull). - Récupérez
account/rateLimits/readaprès avoir utilisé une réinitialisation.
7) Utilisation des jetons (ChatGPT)
Utilisez account/usage/read pour récupérer les champs récapitulatifs de l’activité des jetons ChatGPT et
des compartiments quotidiens facultatifs.
{ "method": "account/usage/read", "id": 7 }
{ "id": 7, "result": {
"summary": {
"lifetimeTokens": 1234567,
"peakDailyTokens": 45678,
"longestRunningTurnSec": 540,
"currentStreakDays": 8,
"longestStreakDays": 14
},
"dailyUsageBuckets": [
{ "startDate": "2026-06-18", "tokens": 12345 }
]
} }Remarques sur les champs :
- Les valeurs
summarypeuvent valoirnulllorsque le service n’a pas renvoyé cette métrique. dailyUsageBucketspeut valoirnull; lorsqu’il est présent, chaque compartiment comprendstartDateettokens.- Le point de terminaison nécessite une authentification reposant sur les services Codex. ChatGPT, les jetons ChatGPT externes, l’identité de l’agent et l’authentification par jeton d’accès personnel fonctionnent ; l’authentification uniquement par API key et l’authentification Bedrock ne fonctionnent pas.
8) Réinitialisations acquises des limites de débit (ChatGPT)
Utilisez account/rateLimitResetCredit/consume pour utiliser une réinitialisation acquise.
{ "method": "account/rateLimitResetCredit/consume", "id": 8, "params": { "idempotencyKey": "8ae96ff3-3425-4f4c-8772-b6fd61502868", "creditId": "RateLimitResetCredit_1" } }
{ "id": 8, "result": { "outcome": "reset" } }Remarques sur les champs :
idempotencyKeyne doit pas être vide. Utilisez un UUID pour chaque tentative logique d’utilisation et réutilisez la même valeur lorsque vous réessayez cette tentative.creditIdest facultatif. Lorsqu’il est fourni, il doit s’agir d’un identifiant opaque non vide provenant deaccount/rateLimits/read. Lorsqu’il est omis, le service sélectionne le prochain crédit disponible.resetsignifie qu’un crédit a été utilisé.alreadyRedeemedsignifie que la même utilisation a déjà été effectuée. Considérez cela comme une réussite idempotente et actualisez les limites du compte.nothingToResetsignifie qu’aucune fenêtre de limite de débit éligible ne peut être réinitialisée.noCreditsignifie que le compte ne dispose d’aucun crédit de réinitialisation acquis.- Récupérez
account/rateLimits/readaprès avoir utilisé une réinitialisation au lieu de déduire les fenêtres mises à jour à partir de cette réponse.
9) Informer le propriétaire d’un espace de travail d’une limite
Utilisez account/sendAddCreditsNudgeEmail pour demander à ChatGPT d’envoyer un e-mail au propriétaire d’un espace de travail lorsque les crédits sont épuisés ou qu’une limite d’utilisation a été atteinte.
{ "method": "account/sendAddCreditsNudgeEmail", "id": 9, "params": { "creditType": "credits" } }
{ "id": 9, "result": { "status": "sent" } }Utilisez creditType: "credits" lorsque les crédits de l’espace de travail sont épuisés, ou creditType: "usage_limit" lorsque la limite d’utilisation de l’espace de travail a été atteinte. Si le propriétaire a déjà été informé récemment, l’état de la réponse est cooldown_active.
10) Messages de l’espace de travail (ChatGPT)
Utilisez account/workspaceMessages/read pour récupérer les messages actifs de l’espace de travail
actuel, y compris les titres de notification lorsqu’ils sont disponibles.
{ "method": "account/workspaceMessages/read", "id": 10 }
{ "id": 10, "result": { "featureEnabled": true, "messages": [
{ "messageId": "msg_123", "messageType": "headline", "messageBody": "Workspace maintenance starts at 5pm.", "createdAt": 1781395200, "archivedAt": null }
] } }