All articles

Codex exec: run Codex non-interactively in scripts and CI

Codex exec title card with a terminal running codex exec --json and printing a turn.completed event

How codex exec works: read-only by default, sandbox flags, stdin, -o, --json and --output-schema output, codex exec resume and running Codex in CI.

Most people meet Codex in its interactive terminal UI. The same agent also runs without that UI: codex exec takes a prompt, works through the task, prints the final answer and exits. That makes it the piece you use in shell scripts, git hooks, cron jobs and CI pipelines, anywhere nobody is sitting at the keyboard.

This guide covers what codex exec does by default, how to give it more or less permission, how to get output a script can parse, how to continue a run with codex exec resume, and how to run it safely in CI. Commands and flags follow the official non-interactive mode documentation and the Codex source code as of October 2026. If Codex is not installed yet, start with our guide to installing the Codex CLI.

What codex exec does

codex exec (alias codex e) runs one task non-interactively. You pass the instructions as an argument, Codex reads the repository, runs commands inside its sandbox and stops when the task is done.

codex exec "summarize the repository structure and list the top 5 risky areas"

Two details make it script friendly:

  • Progress goes to stderr, the answer goes to stdout. While Codex works, its steps stream to stderr. Only the final agent message is printed to stdout, so you can pipe or redirect it without filtering anything out.
  • It expects a Git repository. Codex refuses to run outside one, as a guard against destructive changes in folders you cannot roll back. Add --skip-git-repo-check when you deliberately run it elsewhere, such as a scratch directory.

Because stdout carries only the answer, saving a result is a plain redirect:

codex exec "generate release notes for the last 10 commits" | tee release-notes.md

Feed it input from stdin

codex exec reads standard input in two ways. If you pass a prompt and pipe data in, the piped text becomes context for that prompt:

git diff main...HEAD | codex exec "explain what this diff changes, file by file" > diff-notes.md

If you pass - as the prompt, or no prompt at all, stdin becomes the whole prompt. That is useful when a script builds the instructions from a template:

cat prompts/triage.md | codex exec -

The resume and review subcommands described below accept - the same way.

Permissions: read-only unless you say otherwise

The most important default to know: codex exec runs in a read-only sandbox. Codex can read files and run commands that only look around, but it cannot change your working tree. That is safe for summaries, reviews and questions, and it is why a first attempt at "fix the failing test" often reports a fix without applying it.

Three stacked codex exec sandbox levels: read-only is the default with no flag, workspace-write needs --sandbox workspace-write, danger-full-access removes the sandbox; a marker steps up through them
codex exec starts read-only. Raise the sandbox per run only as far as the task needs: workspace-write for edits, danger-full-access only in disposable containers.

Raise the level per run with --sandbox:

SandboxWhat Codex may doTypical use
read-only (default)Read files, no writesSummaries, reviews, questions
workspace-writeEdit files inside the projectFixes, refactors, generated code
danger-full-accessNo sandbox at allDisposable containers only
codex exec --sandbox workspace-write "fix the failing test in tests/api.test.ts"

Older scripts often use --full-auto. The documentation calls it a deprecated compatibility flag that prints a warning, so write --sandbox workspace-write in new scripts. The flag --dangerously-bypass-approvals-and-sandbox (alias --yolo) removes every protection; keep it for throwaway environments that you would happily delete. Our guide to the Codex sandbox explains the modes, network access, extra writable folders and approval policies in more detail.

Two more flags help when you want a predictable run regardless of whose machine it is: --ignore-user-config skips your personal config.toml (authentication still works), and --ignore-rules skips user and project execpolicy rule files.

Get output a script can use

Plain text on stdout is enough for notes and summaries. When another program has to act on the result, codex exec has three better options.

codex exec sends a stream of progress dots to stderr and a single final message to stdout; below, the -o, --json and --output-schema options are listed as ways to capture output
Progress streams to stderr and only the final message reaches stdout. Use -o for an answer file, --json for JSONL events, or --output-schema for a fixed JSON shape.

Write the final message to a file with -o (long form --output-last-message). The terminal still shows progress, and the file gets only the answer:

codex exec -o summary.md "summarize the changes on this branch for a pull request description"

Stream events as JSON Lines with --json. Every step becomes one JSON object on stdout: thread.started, turn.started, item.started and item.completed for commands, file changes and messages, and finally turn.completed (with token usage) or turn.failed. A short jq filter pulls out the agent's messages:

codex exec --json "summarize the repo structure" \
  | jq -r 'select(.type == "item.completed" and .item.type == "agent_message") | .item.text'

The thread.started event carries a thread_id, which is the ID you need to resume that run later.

Force a shape with a JSON Schema. --output-schema takes a schema file and makes the final response match it, so a script gets predictable fields instead of prose:

{
  "type": "object",
  "properties": {
    "project_name": { "type": "string" },
    "programming_languages": { "type": "array", "items": { "type": "string" } }
  },
  "required": ["project_name", "programming_languages"],
  "additionalProperties": false
}
codex exec "Extract project metadata" --output-schema ./schema.json -o ./project-metadata.json

Combining --output-schema with -o gives you a JSON file you can load directly in the next step of a pipeline.

Continue a run with codex exec resume

Each codex exec run is saved as a session, just like an interactive one. codex exec resume sends a follow-up prompt into that session, so Codex keeps everything it already read and decided:

codex exec "review the change for race conditions"
codex exec resume --last "fix the race conditions you found"
A first codex exec run saves a thread_id; a link draws to codex exec resume --last, then to codex exec resume with an ID, each continuing the same saved context
Every saved codex exec run can be continued with codex exec resume --last or by its thread_id. Runs started with --ephemeral are not saved and cannot be resumed.

--last picks the most recent session. Pass a session ID (or a thread name) to target a specific one, and add --all if the session was started in another directory, since the lookup filters by the current directory by default. In scripts, read the ID from the thread.started event of the first run instead of relying on --last, because a second job on the same machine could create a newer session in between.

If you do not want a run saved at all, add --ephemeral. Nothing is written to disk, which suits one-off CI jobs, but it also means that run cannot be resumed. Our guide to codex resume covers the interactive picker, forks and naming sessions.

Review code with codex exec review

codex exec review runs a code review without the UI. It can review your uncommitted changes, a branch against its base, or a single commit:

codex exec review --uncommitted
codex exec review --base main
codex exec review --commit 1a2b3c4

You can add custom review instructions as a prompt, for example asking it to focus on error handling. Because a review reads code rather than changing it, this is a low-risk first step if you are trying codex exec in a pre-push hook.

Run codex exec in CI

The same commands work in CI with a few adjustments:

  1. Authenticate with an API key. Set CODEX_API_KEY for the job, for example CODEX_API_KEY=<api-key> codex exec --json "triage open bug reports". The documentation supports this variable for codex exec, so you do not need an interactive login on the runner.
  2. Choose the sandbox deliberately. Leave the default read-only sandbox for review and summary jobs. Use --sandbox workspace-write only for jobs that must edit files, and let the pipeline open a pull request so a person reviews the change.
  3. Make runs reproducible. --ignore-user-config and --ephemeral keep a runner's leftovers from changing behavior or piling up session files.
  4. On GitHub, use the action. The docs recommend the Codex GitHub Action (openai/codex-action@v1) instead of installing Codex and passing API keys to shell steps yourself.

Keep project instructions in AGENTS.md so CI runs follow the same build and test commands as your local sessions. Our guide to AGENTS.md for Codex explains how Codex finds those files.

Common problems

SymptomLikely causeFix
Codex describes a fix but no file changedDefault read-only sandboxAdd --sandbox workspace-write
Refuses to start in a folderNot a Git repositoryRun inside a repo or add --skip-git-repo-check
Script captures progress noiseReading stderr as wellRead stdout only, or use -o
Warning about --full-autoDeprecated flagReplace with --sandbox workspace-write
resume --last picks the wrong runAnother run is newerResume by the thread_id from --json
Different results on CI and laptopPersonal config loadedAdd --ignore-user-config

When a flag behaves differently from this guide, run codex exec --help: the installed version is the source of truth for its own options.

Where VibeiDE fits

codex exec is ideal for unattended jobs. For the interactive side of the same work, VibeiDE is a desktop app that coordinates the Codex, Claude Code and OpenCode CLIs you already installed, signed in with your own accounts. Codex runs in an embedded terminal that shows the original CLI interface, each project has its own task queue, each task keeps its saved provider conversation so a follow-up continues it instead of re-explaining the context, and finished tasks wait in Ready for review. See the Codex page or how the task queue works.

Takeaways

  • codex exec runs one task without the UI: progress on stderr, the final message on stdout.
  • It is read-only by default; add --sandbox workspace-write when the task must edit files, and drop the deprecated --full-auto.
  • Use -o for a clean answer file, --json for events a script can parse, and --output-schema for a fixed JSON shape.
  • Continue a run with codex exec resume --last, or by thread_id in scripts; --ephemeral skips saving.
  • In CI, authenticate with CODEX_API_KEY, keep the sandbox tight, and prefer openai/codex-action@v1 on GitHub.

Share this article

Post on XShare on LinkedIn

Related articles

Necessary cookies support sign-in, security, your language and this choice. Optional categories stay off until accepted.

First-party page views and acquisition measurement, plus Google Analytics 4 (Google Ireland, data may reach the US). Advertising features stay off.

Remember referral credit for later. Links still work on the current page without this cookie.

Privacy · Cookie inventory