Serveur d’application Codex
Pour consulter l’index complet de la documentation, reportez-vous à llms.txt. Les versions Markdown des pages de documentation sont disponibles en ajoutant .md à l’URL de la page.
Codex app-server est l’interface utilisée par Codex pour alimenter des clients riches (par exemple, l’extension Codex pour VS Code). Utilisez-la lorsque vous souhaitez intégrer Codex en profondeur dans votre propre produit : authentification, historique des conversations, approbations et événements diffusés en continu par l’agent. L’implémentation d’app-server 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 Codex open source.
Connecter l’interface de terminal du CLI
Le mode d’interface de terminal à distance vous permet d’exécuter app-server sur une machine et de connecter l’interface de terminal du 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 le nom de celle-ci au lieu d’inscrire 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. Utilisez des WebSockets non sécurisés uniquement pour localhost ou une connexion
transférée par port SSH.
Connecter un hôte Code Mode distant
Par défaut, app-server 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 d’app-server vers son hôte Code
Mode. Cette option ne modifie pas --listen, qui contrôle la manière dont les clients se connectent à
app-server. Tous les threads d’un même processus app-server 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 app-server et le transport WebSocket sont
expérimentaux et ne sont pas pris en charge pour les charges de travail de production.
Protocole
À l’instar de MCP, codex app-server prend en charge la communication bidirectionnelle au moyen de messages JSON-RPC 2.0 (l’en-tête "jsonrpc":"2.0" étant omis lors de la transmission).
Transports pris en charge :
stdio(--listen stdio://, par défaut) : JSON délimité par des sauts de 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 app-server par défaut de Codex ou un chemin de socket Unix personnalisé, à l’aide de la négociation HTTP Upgrade standard. off(--listen off) : n’expose aucun transport local.
Lorsque vous utilisez --listen ws://IP:PORT, le même écouteur fournit également des
sondes d’intégrité HTTP de base :
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 progressif, les écouteurs WebSocket qui ne sont pas limités à l’interface de bouclage 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 sous la forme
Authorization: Bearer <token> pendant la négociation WebSocket, et app-server
impose l’authentification avant le trafic JSON-RPC initialize.
Préférez --ws-token-file à la transmission de jetons bearer bruts sur la ligne de commande. N’utilisez
--ws-token-sha256 que lorsque le client conserve le jeton brut à entropie élevée dans un
magasin de secrets local distinct ; le hachage n’est qu’un vérificateur et les clients ont toujours besoin
du jeton d’origine.
En mode WebSocket, app-server 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
exponentiellement croissant 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 même 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 JSON Schema depuis le CLI. Chaque sortie est propre à la version de Codex que vous avez exécutée, de sorte que les artefacts générés correspondent exactement à cette version :
codex app-server generate-ts --out ./schemas
codex app-server generate-json-schema --out ./schemasBien démarrer
- 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 de 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 threads pour créer, répertorier ou archiver des conversations. Pilotez une conversation avec les API de tours et diffusez sa progression au moyen des notifications de tours.
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 envoyée 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 bac à sable, 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, progression des outils et autres mises à jour. - Terminer le tour : le serveur émet
turn/completedavec le statut 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 fonctionnalité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- activez 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 de l’ajouter à la liste des clients connus. Pour plus de contexte, consultez la référence des 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 d’app-server sont volontairement protégés par la fonctionnalité 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é, app-server 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 tours et d’éléments de ce thread.thread/resume- rouvre un thread existant à partir de son identifiant afin que les appelsturn/startultérieurs y ajoutent du contenu.thread/fork- crée une branche d’un thread avec un nouvel identifiant en copiant l’historique stocké. TransmettezlastTurnIdpour copier l’historique jusqu’à ce tour et omettre les tours suivants, ouephemeral: truepour créer une branche 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 identifiant sans le reprendre ; définissezincludeTurnspour renvoyer l’historique complet des tours. Les objetsthreadrenvoyés incluent lestatusd’exécution.thread/list- parcourt les journaux de threads stockés par pages ; 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, éventuellement limités à unturnId. 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- modifie les métadonnées d’un thread stocké basé sur SQLite, notamment les valeurs persistantesgitInfoetisPinned.thread/archive- déplace le fichier journal d’un thread vers le répertoire d’archives et tente d’archiver les journaux des threads descendants générés qui ne le sont pas déjà ; 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 ses 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 tours et d’éléments du thread. S’il s’agissait du dernier abonné, le serveur décharge le thread après un délai d’inactivité sans abonné et émetthread/closed.thread/unarchive- restaure un rollout de 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 des conversations d’un thread ; renvoie immédiatement{}tandis que la progression est diffusée au moyen des notificationsturn/*etitem/*.thread/shellCommand- exécute une commande shell lancée par l’utilisateur sur un thread. Cette commande s’exécute en dehors 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 en arrière-plan en cours d’exécution pour un thread (expérimental ; nécessitecapabilities.experimentalApi).thread/backgroundTerminals/list- répertorie les terminaux en arrière-plan en cours d’exécution pour un thread chargé (expérimental ; nécessitecapabilities.experimentalApi).thread/backgroundTerminals/terminate- arrête un terminal en arrière-plan en cours d’exécution à partir de sonprocessIdapp-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 l’entrée utilisateur à un thread et démarre la génération 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 Responses API bruts à 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 est indiquée par{}et le tour se termine avecstatus: "interrupted".review/start- lance l’outil de révision Codex pour un thread ; émet des élémentsenteredReviewModeetexitedReviewMode.command/exec- exécute une commande unique 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 utilisant 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 en dehors 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 utilisant un PTY (expérimental).process/kill- arrête 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 fin 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, unupgradefacultatif etinputModalities.modelProvider/capabilities/read- lit les limites des fonctionnalités du fournisseur pour les combinaisons modèle/fournisseur.experimentalFeature/list- répertorie les indicateurs de fonctionnalité avec les métadonnées de leur étape du 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é 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 en vigueur les autorisent, 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 paramètre facultatifperCwdExtraUserRoots).skills/extraRoots/set- remplace les racines supplémentaires au niveau du processus utilisées pour découvrir les skills autonomes, sans les conserver.skills/changed(notification) - émise lorsque les fichiers de skills 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 ainsi que la racine de marketplace installée lorsqu’elle existe.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 de politique 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 unversiondistant, unlocalVersionlocal, des icônes structurées pour les thèmes clair et sombre ainsi queinstallPolicySource, qui peut êtrenull,WORKSPACE_SETTINGouIMPLICIT_CANONICAL_APPpour les lignes distantes actuelles. N’appelez pas encore cette méthode depuis des clients de production.plugin/read- en cours de développement ; lit un plugin à partir du chemin de sa marketplace ou du nom de sa marketplace distante et de son nom de plugin, y compris les skills inclus, les apps, les noms de serveurs MCP et leshareUrld’un plugin distant lorsque le catalogue distant en fournit un. N’appelez pas encore cette méthode depuis des clients de production.plugin/install- en cours de développement ; installe un plugin depuis le chemin d’une marketplace ou le nom d’une marketplace distante. N’appelez pas encore cette méthode depuis des clients de production.plugin/uninstall- en cours de développement ; désinstalle un plugin installé. N’appelez pas encore cette méthode depuis des clients de production.plugin/skill/read- lit à la demande le Markdown du skill d’un 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 selon leur chemin.mcpServer/oauth/login- démarre une connexion OAuth pour un serveur MCP configuré ; renvoie une URL d’autorisation et émetmcpServer/oauthLogin/completedune fois l’opération terminée.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 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 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 la configuration des serveurs MCP depuis le disque et met en file d’attente une actualisation pour les threads chargés.mcpServerStatus/list- répertorie les serveurs MCP, outils, ressources et états d’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 ressource MCP unique par l’intermédiaire 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 le paramètre facultatifcwds; chaque élément détecté comprendcwd(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 incluent 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 paire clé/valeur de configuration dans le fichierconfig.tomlde l’utilisateur sur le disque.config/batchWrite- applique de manière atomique les modifications de configuration au fichierconfig.tomlde l’utilisateur sur le disque.configRequirements/read- récupère les exigences provenant derequirements.tomlet/ou de MDM, y compris la configuration gérée exacte, les listes d’autorisation, les élémentsfeatureRequirementsépinglés et les exigences de résidence ou de 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) - opèrent sur des chemins de système de fichiers absolus 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 basées 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 disponibles uniquement dans le catalogue
distant, PluginMarketplaceEntry.path peut être null ; transmettez
remoteMarketplaceName au lieu de marketplacePath lorsque vous lisez ou installez
ces plugins.
Modèles
Répertorier les modèles (model/list)
Appelez model/list pour découvrir les modèles disponibles et leurs fonctionnalité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 facultatives de mise à niveau pour les invites de migration dans les clients.hidden- indique si le modèle est masqué dans la liste de sélection 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 des instructions propres à une personnalité, telles que/personality.isDefault- indique si le modèle est le choix par défaut recommandé.
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 à l’aide de hidden.
Lorsque inputModalities est absent (anciens catalogues de modèles), traitez-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é accompagnés de leurs métadonnées et de l’étape de leur 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 être beta, underDevelopment, stable, deprecated ou removed. Pour les indicateurs non bêta, displayName, description et announcement peuvent être null.
Inspecter un environnement d’exécution (expérimental)
Utilisez environment/info pour inspecter un environnement distant configuré avant
d’y commencer le travail. Cette 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 être 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 ainsi que 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, éventuellement limités à 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 dans le répertoire d’archives et tente d’archiver les journaux des threads descendants générés qui ne le sont pas déjà.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 du thread stocké, notamment les valeurs persistantesgitInfoetisPinned.thread/unsubscribedésabonne la connexion actuelle d’un thread chargé et peut déclencherthread/closedaprès un délai d’inactivité.thread/unarchiverestaure un rollout de 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 Responses API bruts à 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 qu’app-server 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 paginée de threads n’est pas encore prise en charge
et renvoie l’erreur JSON-RPC -32601. App-server peut répertorier et lire les résumés des
enregistrements paginés existants, mais la lecture 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 l’identifiant nommé d’un
profil d’autorisation dans permissions au lieu du champ historique sandbox.
N’envoyez pas permissions et sandbox ensemble. Utilisez
permissionProfile/list avec le cwd du projet pour découvrir les profils disponibles
et vérifier si les exigences gérées autorisent chacun d’eux.
thread.sessionId identifie la racine actuelle de l’arborescence des sessions actives. Les threads racines
utilisent leur propre identifiant de thread comme identifiant de session ; les threads issus d’une branche conservent l’identifiant de session
de la racine dont ils proviennent. Les clients doivent lire l’identifiant de session dans
thread.sessionId au lieu de le déduire de l’identifiant du thread.
Pour poursuivre une session stockée, appelez thread/resume avec le thread.id que vous avez enregistré précédemment. 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, tels que 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 poursuivre sans lui.
dynamicTools sur 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 lorsque 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 affiché 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 contenir entre 1 et 4 000 caractères. La fourniture d’un nouvel
objectif remplace l’objectif existant et réinitialise le suivi de l’utilisation. La fourniture de l’objectif
non terminal actuel, ou l’omission de objective, met à jour le statut ou le budget de jetons
tout en conservant 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" } } }App-server rejette un lastTurnId en cours. Si vous omettez ce champ alors que le
thread source se trouve au milieu d’un tour, la branche enregistre un marqueur d’interruption au lieu
de conserver un tour partiel sans marqueur.
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, app-server 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 accéder aux données d’un thread stocké sans le reprendre ni vous abonner à ses événements.
includeTurns- lorsque la valeur esttrue, la réponse inclut les tours du thread ; lorsque la valeur estfalseou qu’elle est omise, vous obtenez uniquement le résumé du thread.- Les objets
threadrenvoyés incluent lestatusd’exécution (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 en tant que 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 détermine la quantité de données d’éléments de tours incluse dans la réponse :
notLoadedomet les éléments.summaryrenvoie des données d’éléments résumées et constitue la valeur par défaut en cas d’omission.fullrenvoie les données d’éléments complètes.
{ "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 les éléments de l’ensemble du thread. Le stockage de threads actif doit prendre en charge la
pagination des éléments ; dans le cas contraire, 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 paramètres suivants :
cursor- chaîne opaque provenant 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 paramètre 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 spécifiques ; une valeur non définie, null ou un tableau vide inclut tous les fournisseurs.sourceKinds- limite les résultats à des sources de threads spécifiques. Si ce paramètre est omis ou vaut[], le serveur utilise par défaut uniquement les sources interactives :clietvscode.archived- lorsque la valeur esttrue, répertorie uniquement les threads archivés. Lorsque la valeur estfalseou qu’elle est omise, 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 app-server.useStateDbOnly- lorsque la valeur esttrue, 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 ce paramètre ou transmettezfalsepour conserver le comportement par défaut d’analyse et de réparation.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 d’un thread stocké
Utilisez thread/metadata/update pour modifier les métadonnées d’un thread stocké sans reprendre le
thread. 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ées 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 comprend 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 est l’un des suivants :
unsubscribedlorsque la connexion était abonnée et que l’abonnement est désormais supprimé.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, app-server 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 ultérieurement :
{ "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 déjà.
{ "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 fils 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 fil qu’il archive effectivement ; si un descendant créé ne peut pas être archivé, la requête peut tout de même aboutir sans notification d’archivage pour ce descendant.
Supprimer un fil
Utilisez thread/delete pour supprimer définitivement un fil actif ou archivé persistant
ainsi que les fils descendants qu’il a créés. Le serveur supprime les fichiers de rollout existants et
les métadonnées associées avant de renvoyer une réponse indiquant la réussite ; les fichiers de rollout manquants sont considérés
comme déjà supprimés. Les fils 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 fil
Utilisez thread/unarchive pour replacer le rollout d’un fil 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 fil
Utilisez thread/compact/start pour déclencher manuellement la compaction de l’historique d’un fil. La requête renvoie immédiatement {}.
App-server communique la progression au moyen des notifications standard turn/* et item/* 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 fil
Utilisez thread/shellCommand pour les commandes shell lancées par l’utilisateur et rattachées à un fil. La requête renvoie immédiatement {}, tandis que la progression est diffusée par les notifications standard turn/* et item/*.
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 fil. Les clients ne doivent l’exposer que pour des commandes explicitement lancées par l’utilisateur.
Si le fil 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 fil est inactif, app-server lance un tour autonome pour la commande shell.
{ "method": "thread/shellCommand", "id": 26, "params": { "threadId": "thr_b", "command": "git status --short" } }
{ "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 fil. 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 inspecter les terminaux en arrière-plan en cours d’exécution
pour un fil chargé. La requête prend en charge la pagination standard cursor et limit,
et le processId renvoyé 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 ce 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. Le thread renvoyé 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 fil. outputSchema ne s’applique qu’au tour en cours. 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 effacer 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:accessfacultatif ({ "type": "fullAccess" }par défaut, ou racines restreintes).workspaceWrite:readOnlyAccessfacultatif ({ "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 pour la plateforme aux sessions dont l’accès en lecture est restreint. Cela améliore la compatibilité des outils sans autoriser largement l’ensemble 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 } } }Injecter des éléments dans un fil
Utilisez thread/inject_items pour ajouter des éléments Responses API préconstruits à l’historique des prompts d’un fil chargé sans démarrer de tour utilisateur. Ces éléments sont conservés dans le rollout et inclus dans les requêtes ultérieures 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 une nouvelle saisie utilisateur au tour actif en cours d’exécution.
- Incluez
expectedTurnId; il doit correspondre à l’identifiant du tour actif. - La requête échoue si le fil 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 (appeler une compétence)
Appelez explicitement une compétence en incluant $<skill-name> dans la saisie textuelle et en ajoutant un élément d’entrée skill à ses côtés.
{ "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 le réviseur Codex pour un fil et diffuse les éléments de 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 fil existant, ou delivery: "detached" pour créer un nouveau fil de revue par bifurcation.
Exemple de requête et de 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 présente la même structure, mais reviewThreadId correspond à l’identifiant du nouveau fil de revue (différent du threadId d’origine). Le serveur émet également une notification thread/started pour ce nouveau fil avant de diffuser le tour de revue.
Codex diffuse la notification turn/started habituelle, suivie d’un item/started contenant un élément enteredReviewMode :
{
"method": "item/started",
"params": {
"item": {
"type": "enteredReviewMode",
"id": "turn_900",
"review": "current changes"
}
}
}Lorsque le réviseur termine, 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 du réviseur dans votre client.
Exécution de processus
process/* est une API expérimentale et explicite de contrôle des processus. Elle nécessite
capabilities.experimentalApi = true et s’exécute hors du bac à sable de Codex. Utilisez-la
uniquement lorsque votre client expose délibérément le contrôle des processus locaux 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 du processus 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 données d’entrée. Utilisez process/resizePty pour les événements de redimensionnement du PTY et process/kill pour
mettre fin à 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 fil.
{ "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 serveur dans un bac à sable et souhaitez que Codex ignore son propre mécanisme de 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 queturn/start(par exemple,dangerFullAccess,readOnly,workspaceWrite,externalSandbox).- Lorsqu’il est omis,
timeoutMsreprend la valeur par défaut du serveur. - Définissez
tty: truepour les sessions reposant sur un PTY et utilisezprocessIdlorsque vous prévoyez d’effectuer ensuite un appel àcommand/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 inspecter 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 pendant les 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 d’achèvement :
{
"method": "windowsSandbox/setupCompleted",
"params": { "mode": "elevated", "success": true, "error": null }
}Modes :
elevated- exécute le processus de configuration avec élévation 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 par des opérations de remplacement ou de renommage.
Événements
Les notifications d’événements constituent le flux émis par le serveur pour les cycles de vie des fils, des tours et des éléments qu’ils contiennent. Après avoir démarré ou repris un fil, 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.
- S’applique aux notifications v2
thread/*,turn/*,item/*et associées de la connexion actuelle. - Ne s’applique pas aux requêtes, réponses ni 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 des 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 à l’issue d’une requêtewindowsSandbox/setupStart.
Événements de tour
turn/started-{ turn }avec l’identifiant du tour, unitemsvide etstatus: "inProgress".turn/completed-{ turn }oùturn.statusvautcompleted,interruptedoufailed; les échecs incluent{ 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{ step, status }dontstatusvautpending,inProgressoucompleted.hook/startedethook/completed-{ threadId, turnId?, run }lorsqu’un hook de cycle de vie démarre et lorsque le résumé final de son exécution est disponible.model/safetyBuffering/updated-{ threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel }lorsqu’une réponse entre dans une mémoire tampon de sécurité transitoire.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 fil 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 référence 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).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 l’élémentplanfinal deitem/completedcomme faisant autorité.reasoning-{id, summary, content}oùsummarycontient les résumés de raisonnement diffusés etcontentles blocs de raisonnement bruts.commandExecution-{id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.fileChange-{id, changes, status}décrivant les modifications proposées ; la listechangescontient des{path, kind, diff}.mcpToolCall-{id, server, tool, status, arguments, appContext?, pluginId?, result?, error?}. Pour les apps MCP de confiance,appContextpeut inclureconnectorId,linkId,resourceUri,appName,templateIdet le connecteur stableactionName. Les anciens éléments conservés peuvent omettre les métadonnées plus récentes. UtilisezappContext.resourceUriau lieu du champ de premier niveau obsolètemcpAppResourceUri.dynamicToolCall-{id, tool, arguments, status, contentItems?, success?, durationMs?}pour les appels d’outils dynamiques 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 sur le Web lancées par l’agent.imageView-{id, path}émis lorsque l’agent appelle l’outil de visualisation d’images.enteredReviewMode-{id, review}envoyé au démarrage du réviseur.exitedReviewMode-{id, review}émis lorsque le réviseur termine.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 leitemcomplet lorsqu’une nouvelle unité de travail commence ; leitem.idcorrespond auitemIdutilisé par les deltas.item/completed- envoie leitemfinal lorsque le travail se termine ; considérez-le comme l’état faisant autorité.
Deltas d’élément
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 lisibles du raisonnement ;summaryIndexs’incrémente lorsqu’une nouvelle section du résumé s’ouvre.item/reasoning/summaryPartAdded- marque une limite entre les sections du résumé du raisonnement.item/reasoning/textDelta- diffuse le texte brut du raisonnement (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 de l’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 relatives à l’exécution de commandes :
accept,acceptForSession,decline,cancelou{ "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }.Décisions relatives aux modifications 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, puis termine l’élément avec
item/completed.
Approbations de l’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 comprendre 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 dans le protocole.- Le client répond avec l’une des décisions d’approbation de l’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 un 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 pertinent 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 différents ports d’un même hôte sont traités séparément.
Approbations des modifications de fichiers
Ordre des messages :
item/startedémet un élémentfileChangeavec les champs proposéschangesetstatus: "inProgress".item/fileChange/requestApprovalcomprenditemId,threadId,turnId, le champ facultatifreasonet le champ facultatifgrantRoot.- Le client répond avec l’une des décisions d’approbation des modifications 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 lors de l’interruption du tour avant la réponse du client, le serveur émet la même notification pour ce nettoyage.
Les paramètres de la requête comprennent autoResolutionMs sous la forme d’un 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, le champ facultatif reason et les autorisations réseau ou de système de fichiers
demandées. Répondez avec permissions contenant uniquement le sous-ensemble accordé.
Définissez scope sur "session" pour conserver l’autorisation pour les tours ultérieurs de la même
session ; omettez-le ou utilisez "turn" pour limiter l’autorisation 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, le champ facultatif 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 le content demandé, 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 Codex intégrés.
Lorsqu’un outil dynamique est appelé pendant un tour, app-server émet :
item/startedavecitem.type = "dynamicToolCall",status = "inProgress", ainsi quetooletarguments.item/tool/callen tant que 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", lestatusfinal et toute valeurcontentItemsousuccessrenvoyée.
Approbations des appels d’outils MCP (apps)
Les appels d’outils d’apps (connecteurs) peuvent également nécessiter une approbation. Lorsqu’un appel d’outil d’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 indique également des caractéristiques moins privilégiées. Si l’utilisateur refuse ou annule, l’élément mcpToolCall associé se termine avec une erreur au lieu d’exécuter l’outil.
Compétences
Appelez une compétence en incluant $<skill-name> dans la saisie textuelle. Ajoutez un élément d’entrée skill (recommandé) afin que le serveur injecte l’intégralité des instructions de la compétence 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 la compétence, 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 compétences disponibles (éventuellement limitées par cwds, avec forceReload). Vous pouvez également inclure perCwdExtraUserRoots pour analyser des chemins absolus supplémentaires en tant que portée user pour des valeurs cwd précises. App-server ignore les entrées dont cwd n’est pas présent 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 de compétences locaux surveillés changent. Considérez-les comme un signal d’invalidation et réexécutez skills/list avec vos paramètres actuels si nécessaire.
Pour activer ou désactiver une compétence par 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é d’exécution validé des apps installées.
Chaque résultat comprend le id de l’app, runtimeName (ou null), l’état effectif
enabled et l’état callable. Une app ne peut être appelée que lorsque la 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 fil chargé.
Définissez forceRefresh: true pour actualiser l’instantané d’exécution du connecteur
avant de le lire. Lorsque la politique globale ou celle de l’espace de travail bloque l’accès aux apps,
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 la CLI/TUI, /apps est le sélecteur affiché à 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é dans config.toml), afin que les clients puissent distinguer l’installation ou l’accès de l’état d’activation local. Les entrées d’app peuvent également comprendre 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 des fonctionnalités de l’app (features.apps) utilise l’instantané de configuration de ce fil. Lorsqu’il est omis, app-server utilise la dernière configuration globale.
app/list renvoie une réponse 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 actualisées. Les entrées du cache ne sont remplacées que si l’actualisation réussit.
Le serveur émet également des notifications app/list/updated chaque fois que le chargement de l’une des deux 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 leur état d’exécution installé. Transmettez au maximum 100 appIds. Le serveur ne conserve que
la première occurrence de chaque identifiant répété et maintient cet ordre dans
apps comme dans 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 ne comprend pas l’état d’exécution des apps installées et n’autorise pas
un appel d’outil ; utilisez app/installed pour vérifier les états effectifs enabled et callable.
Appelez une app en insérant $<app-slug> dans la saisie 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 inspecter ou mettre à jour les contrôles des apps dans config.toml.
Lisez la structure effective de la configuration des apps (notamment _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 le réviseur 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 approvals_reviewer de premier niveau. apps._default.default_tools_approval_mode
définit le mode d’approbation de secours pour les outils sans remplacement propre à l’app ou à l’outil.
Les exigences de mode d’approbation gérées prévalent sur les paramètres de 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 pouvant ê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 ayant
généré les éléments de migration sélectionnés.
Le serveur émet externalAgentConfig/import/progress à mesure que les types d’éléments se terminent,
et externalAgentConfig/import/completed une fois toutes les importations synchrones et en arrière-plan
terminées. Ces notifications comprennent le même importId que la
réponse et itemTypeResults avec les champs successes et failures pour chaque type.
La notification d’achèvement 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 précédemment 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 le
pluginNames que Codex peut tenter de migrer. La détection ne renvoie que les éléments pour lesquels
il reste du travail. Par exemple, Codex ignore la migration d’AGENTS lorsque AGENTS.md
existe déjà et n’est pas vide, et les importations de compétences n’écrasent pas les répertoires de
compétences existants.
Lors de la détection de plugins depuis .claude/settings.json, Codex lit les sources de
marketplace configurées dans extraKnownMarketplaces. Si enabledPlugins contient des
plugins provenant de claude-plugins-official mais que la source du 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, inspecter les limites d’utilisation de ChatGPT et avertir les propriétaires de l’espace de travail lorsque les crédits sont épuisés ou les limites d’utilisation atteintes.
Modes d’authentification
Codex prend en charge les modes d’authentification suivants. account/updated.authMode indique le mode actif et comprend le planType ChatGPT actuel lorsqu’il est disponible. account/read fournit également des informations sur le compte et l’abonnement.
- API key (
apikey) - l’appelant fournit une OpenAI API key avectype: "apiKey", et Codex la conserve pour les requêtes API. - Géré par ChatGPT (
chatgpt) - Codex prend en charge le flux OAuth de ChatGPT, conserve les jetons et les actualise automatiquement. Commencez partype: "chatgpt"pour le flux dans le navigateur ou partype: "chatgptDeviceCode"pour le flux par code d’appareil. - Jetons ChatGPT externes (
chatgptAuthTokens) - fonctionnalité expérimentale destinée aux apps hôtes qui gèrent déjà le cycle de vie de l’authentification ChatGPT de l’utilisateur. L’app hôte fournit directement unaccessToken, unchatgptAccountIdet, facultativement, unchatgptPlanType, et doit actualiser le jeton à la demande. - Amazon Bedrock -
account/readsignale les comptes Bedrock commetype: "amazonBedrock"et indique si les identifiants proviennent d’une Bedrock API key gérée par Codex (credentialSource: "codexManaged") ou de la chaîne d’identifiants AWS externe (credentialSource: "awsManaged").account/updated.authModeutilisebedrockApiKeypour les Bedrock API keys 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- commence 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 d’utilisation de ChatGPT.account/rateLimits/updated(notification) - émise chaque fois que les limites d’utilisation de 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 d’utilisation acquise à l’aide d’une valeuridempotencyKeyfournie par l’appelant.account/usage/read- récupère les résumés d’activité des jetons du compte ChatGPT et les compartiments quotidiens.account/workspaceMessages/read- récupère les messages actifs de l’espace de travail, notamment les titres des notifications 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 conservés ont expiré et n’ont pas pu être actualisés ; le client doit donc 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(booléen) : définisseztruepour forcer l’actualisation du 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.requiresOpenaiAuthreflète le fournisseur actif ; lorsquefalse, Codex peut fonctionner sans identifiants OpenAI.- Amazon Bedrock indique
credentialSource: "codexManaged"lorsqu’il utilise une Bedrock API key gérée par Codex. Il indiquecredentialSource: "awsManaged"pour le chemin d’identifiants AWS externe. Cela identifie la source d’identifiants sélectionnée, sans valider que la chaîne d’identifiants AWS peut résoudre les identifiants.
2) Se connecter avec une API key
- Envoyez :
{
"method": "account/login/start",
"id": 2,
"params": { "type": "apiKey", "apiKey": "sk-..." }
}- Attendez-vous à recevoir :
{ "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 dans le 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 l’expérience de connexion ou lorsqu’un rappel de navigateur est peu fiable.
- 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 ; le frontend 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"
}
}- Attendez-vous à recevoir :
{ "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’app 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 d’utilisation (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 à plusieurs compartiments indexée parlimit_idmesuré (par exemplecodex).limitIdest l’identifiant du compartiment mesuré.limitNameest un libellé facultatif du compartiment destiné à l’utilisateur.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 les détails des crédits restants de l’espace de travail.rateLimitReachedTypeidentifie l’état de limite classé par le serveur lorsqu’une limite a été atteinte.rateLimitResetCreditscontient le nombre de réinitialisations acquises disponibles lorsque le service le fournit ; sinon, il vautnull.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 détaillées ;availableCountfait donc autorité.- Chaque ligne détaillée comprend un
idopaque,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 du résumé d’activité des jetons ChatGPT et
les 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 êtrenulllorsque le service n’a pas renvoyé cette métrique. dailyUsageBucketspeut valoirnull; lorsqu’il est présent, chaque compartiment comprendstartDateettokens.- Le point de terminaison exige une authentification reposant sur les services Codex. ChatGPT, les jetons ChatGPT externes, l’identité d’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 d’utilisation (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à abouti. Considérez-la comme une réussite idempotente et actualisez les limites du compte.nothingToResetsignifie qu’aucune fenêtre de limite d’utilisation admissible 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 de cette réponse les fenêtres mises à jour.
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é averti 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, notamment les titres des notifications 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 }
] } }