Who this is for and what you will get
If you want Codex to run inside CI, a scheduled job or a shell pipeline instead of an interactive session, this guide is for you. You will learn to run codex exec, capture its output, choose a sandbox, produce machine-readable JSON and handle API keys safely.[1]
What codex exec is
Non-interactive mode runs Codex from scripts without opening the interactive interface. You start it with codex exec.[1] It fits pipelines such as CI, pre-merge checks and scheduled jobs. It also suits feeding output to other tools, chaining command output into Codex, and running with sandbox and approval settings fixed in advance.[1] Every flag is described under the codex exec entry in the developer command reference.[1]
Your first run
Pass the task as the only argument. The following command asks for a short risk assessment of the repository:[1]
codex exec "summarize the repository structure and list the top 5 risky areas"While it works, progress goes to stderr, and stdout carries only the final message. That makes the result easy to redirect or pipe into the next command.[1]
codex exec "generate release notes for the last 10 commits" | tee release-notes.mdTo avoid saving session files to disk, add --ephemeral:[1]
codex exec --ephemeral "triage this repository and suggest next steps"Feeding data through a pipe
When you give both stdin and a prompt argument, Codex treats the prompt as the instruction and the piped text as extra context. This example fetches some comments and asks Codex to turn them into a table:[1]
curl -s https://jsonplaceholder.typicode.com/comments \
| codex exec "format the top 20 items into a markdown table" \
> table.mdThere are two more stdin patterns. In prompt-plus-stdin, you write the instruction and the command output serves as context. Here, failing tests are summarized after a test run:[1]
npm test 2>&1 \
| codex exec "summarize the failing tests and propose the smallest likely fix" \
| tee test-summary.mdIn the second pattern, stdin becomes the entire prompt. This suits prompts that a script assembles:[1]
cat prompt.txt | codex exec -If you omit the prompt argument, Codex reads the prompt from stdin anyway. The - makes that behavior explicit.[1]
Choosing permissions
codex exec starts in a read-only sandbox. Add --sandbox workspace-write to allow edits. --sandbox danger-full-access grants broader access and belongs only on an isolated CI runner or inside a container.[1]
--full-auto is no longer supported. Replace it with --sandbox workspace-write, or use --approve-for-me to send approval requests through automatic review while staying in the workspace-write sandbox.[1]
Use --ignore-user-config to skip $CODEX_HOME/config.toml, and --ignore-rules to skip user and project execpolicy .rules files in a controlled environment.[1]
If an enabled MCP server marked required = true fails to initialize, codex exec exits with an error rather than carrying on without it.[1]
Machine-readable output
Add --json and stdout becomes a JSON Lines stream that logs each event as it happens:[1]
codex exec --json "summarize the repo structure" | jqEvent types include thread.started, turn.started, turn.completed, turn.failed, item.* and error. Items cover agent messages, reasoning, command runs, file edits, MCP tool calls, web searches and plan updates.[1] A short sample stream looks like this:[1]
{"type":"thread.started","thread_id":"0199a213-81c0-7800-8aa1-bbab2a035a53"}
{"type":"turn.started"}
{"type":"item.started","item":{"id":"item_1","type":"command_execution","command":"bash -lc ls","status":"in_progress"}}
{"type":"item.completed","item":{"id":"item_3","type":"agent_message","text":"Repo contains docs, sdk, and examples directories."}}
{"type":"turn.completed","usage":{"input_tokens":24763,"cached_input_tokens":24448,"output_tokens":122,"reasoning_output_tokens":0}}If you only need the last message, pass -o <path> or --output-last-message <path>. The message is written to that file and still printed to stdout.[1]
Structured results with a schema
--output-schema makes the final response match a JSON Schema. This helps when later steps depend on fixed field names, such as job summaries, risk reports or release metadata.[1] A schema file looks like this:[1]
{
"type": "object",
"properties": {
"project_name": { "type": "string" },
"programming_languages": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["project_name", "programming_languages"],
"additionalProperties": false
}Then run Codex with the schema and write the result to a file:[1]
codex exec "Extract project metadata" \
--output-schema ./schema.json \
-o ./project-metadata.jsonAuthentication in CI
By default codex exec reuses the CLI login saved on the machine. Automation usually supplies credentials explicitly.[1] To use a different API key for one run, set CODEX_API_KEY inline:[1]
CODEX_API_KEY=<api-key> codex exec --json "triage open bug reports"CODEX_API_KEY works with codex exec, codex review, the TypeScript SDK and codex exec-server --remote.[1]
Keep keys out of job-wide variables. In workflows that check out or run repository code, do not set OPENAI_API_KEY or CODEX_API_KEY at job level. Build scripts, tests, dependency lifecycle hooks or a compromised action in the same job can read them.[1]
For GitHub Actions, the documentation recommends the official Codex GitHub Action over installing and logging in to the CLI yourself. The action installs Codex, starts a Responses API proxy and runs Codex under a configurable safety strategy.[1]
Using ChatGPT-managed auth in CI is an advanced option for running jobs under a Codex user account. The ~/.codex/auth.json file holds access tokens, so guard it like a password and never commit it, paste it into a ticket or share it in chat. Do not use this approach for public or open-source repositories.[1]
Resuming a session
In a two-stage pipeline, pick up the earlier session with resume:[1]
codex exec "review the change for race conditions"
codex exec resume --last "fix the race conditions you found"You can also name a specific session with codex exec resume <SESSION_ID>.[1]
The Git requirement
Codex expects commands to run inside a Git repository, which guards against destructive edits. Only pass --skip-git-repo-check if you are sure the environment is safe.[1]
An auto-fix pattern for failing CI
The documentation outlines one pattern. When the main CI workflow fails, a follow-up workflow starts. It checks out the failing commit with read-only permissions, runs setup steps before Codex without giving those steps the OpenAI API key, runs the Codex GitHub Action, saves Codex's local changes as a patch artifact, and lets a separate job apply the patch and open a pull request.[1]
The Codex job has only contents: read. The job that opens the pull request gets write permissions but never receives OPENAI_API_KEY.[1]
Next steps
The full list of flags is in the official developer command reference.[1]
Sources
- 1Non-interactive modeOpenAI Codex docs
Cite this page: Codex Non-Interactive Mode: Scripting with codex exec. TellWorld, https://www.tellworld.net/practice/practice-codex-non-interactive. Updated 2026-11-14