VOOZH about

URL: https://developers.openai.com/codex/noninteractive

⇱ Non-interactive mode – Codex | OpenAI Developers


Search the Codex docs

Primary navigation

Non-interactive mode lets you run Codex from scripts (for example, continuous integration (CI) jobs) without opening the interactive TUI. You invoke it with codex exec.

For flag-level details, see codex exec.

When to use codex exec

Use codex exec when you want Codex to:

  • Run as part of a pipeline (CI, pre-merge checks, scheduled jobs).
  • Produce output you can pipe into other tools (for example, to generate release notes or summaries).
  • Fit naturally into CLI workflows that chain command output into Codex and pass Codex output to other tools.
  • Run with explicit, pre-set sandbox and approval settings.

Basic usage

Pass a task prompt as a single argument:

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

While codex exec runs, Codex streams progress to stderr and prints only the final agent message to stdout. This makes it straightforward to redirect or pipe the final result:

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

Use --ephemeral when you don’t want to persist session rollout files to disk:

codex exec --ephemeral "triage this repository and suggest next steps"

If stdin is piped and you also provide a prompt argument, Codex treats the prompt as the instruction and the piped content as additional context.

This makes it easy to generate input with one command and hand it directly to Codex:

curl -s https://jsonplaceholder.typicode.com/comments \
 | codex exec "format the top 20 items into a markdown table" \
 > table.md

For more advanced stdin piping patterns, see Advanced stdin piping.

Permissions and safety

By default, codex exec runs in a read-only sandbox. In automation, set the least permissions needed for the workflow:

  • Allow edits: codex exec --sandbox workspace-write "<task>"
  • Allow broader access: codex exec --sandbox danger-full-access "<task>"

Use danger-full-access only in a controlled environment (for example, an isolated CI runner or container).

Codex keeps codex exec --full-auto as a deprecated compatibility flag and prints a warning. Prefer the explicit --sandbox workspace-write flag in new scripts.

Use --ignore-user-config when you need a run that doesn’t load $CODEX_HOME/config.toml, and --ignore-rules when you need to skip user and project execpolicy .rules files for a controlled automation environment.

If you configure an enabled MCP server with required = true and it fails to initialize, codex exec exits with an error instead of continuing without that server.

Make output machine-readable

To consume Codex output in scripts, use JSON Lines output:

codex exec --json "summarize the repo structure" | jq

When you enable --json, stdout becomes a JSON Lines (JSONL) stream so you can capture every event Codex emits while it’s running. Event types include thread.started, turn.started, turn.completed, turn.failed, item.*, and error.

Item types include agent messages, reasoning, command executions, file changes, MCP tool calls, web searches, and plan updates.

Sample JSON stream (each line is a JSON object):

{"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 final message, write it to a file with -o <path>/--output-last-message <path>. This writes the final message to the file and still prints it to stdout (see codex exec for details).

Create structured outputs with a schema

If you need structured data for downstream steps, use --output-schema to request a final response that conforms to a JSON Schema. This is useful for automated workflows that need stable fields (for example, job summaries, risk reports, or release metadata).

schema.json

{
 "type": "object",
 "properties": {
 "project_name": { "type": "string" },
 "programming_languages": {
 "type": "array",
 "items": { "type": "string" }
 }
 },
 "required": ["project_name", "programming_languages"],
 "additionalProperties": false
}

Run Codex with the schema and write the final JSON response to disk:

codex exec "Extract project metadata" \
 --output-schema ./schema.json \
 -o ./project-metadata.json

Example final output (stdout):

{
 "project_name": "Codex CLI",
 "programming_languages": ["Rust", "TypeScript", "Shell"]
}

Authenticate in automation

codex exec reuses saved CLI authentication by default. In CI, it’s common to provide credentials explicitly:

Use API key auth

For GitHub Actions, use the Codex GitHub Action instead of installing and authenticating the CLI yourself. The action is designed to reduce API key exposure by installing Codex, starting a Responses API proxy, and running Codex with a configurable safety strategy.

Do not set OPENAI_API_KEY or CODEX_API_KEY as a job-level environment variable in workflows that check out or run repository-controlled code. Build scripts, tests, dependency lifecycle hooks, or a compromised action in the same job can read those environment variables.

For other automation environments, set CODEX_API_KEY only for the single codex exec invocation and make sure no untrusted code runs in the same process environment.

To use a different API key for a single run, set CODEX_API_KEY inline:

CODEX_API_KEY=<api-key> codex exec --json "triage open bug reports"

CODEX_API_KEY is only supported in codex exec.

Resume a non-interactive session

If you need to continue a previous run (for example, a two-stage pipeline), use the resume subcommand:

codex exec "review the change for race conditions"
codex exec resume --last "fix the race conditions you found"

You can also target a specific session ID with codex exec resume <SESSION_ID>.

Git repository required

Codex requires commands to run inside a Git repository to prevent destructive changes. Override this check with codex exec --skip-git-repo-check if you’re sure the environment is safe.

Common automation patterns

Example: Autofix CI failures in GitHub Actions

For GitHub Actions workflows, use openai/codex-action instead of installing Codex and passing the API key to a shell step. The action starts a secure proxy for the OpenAI API key.

You can use Codex to automatically propose fixes when a CI workflow fails. The pattern is:

  1. Trigger a follow-up workflow when your main CI workflow completes with an error.
  2. Check out the failing commit with repository read permissions only.
  3. Run setup commands before Codex, without exposing your OpenAI API key to those steps.
  4. Run the Codex GitHub Action.
  5. Save Codex’s local changes as a patch artifact.
  6. In a separate job, apply the patch and open a pull request.

The Codex job below has only contents: read. After Codex runs, it only serializes the diff as an artifact. The open_pr job receives repository write permissions, but it does not receive OPENAI_API_KEY.

The example assumes a Node.js project. Adjust the setup and test commands to match your stack.

For a deeper security checklist, see the Codex GitHub Action security guidance.

name: Codex auto-fix on CI failure

on:
 workflow_run:
 workflows: ["CI"]
 types: [completed]

jobs:
 generate_fix:
 if: ${{ github.event.workflow_run.conclusion == 'failure' }}
 runs-on: ubuntu-latest
 permissions:
 contents: read
 outputs:
 has_patch: ${{ steps.diff.outputs.has_patch }}
 steps:
 - uses: actions/checkout@v5
 with:
 ref: ${{ github.event.workflow_run.head_sha }}
 fetch-depth: 0
 persist-credentials: false

 - uses: actions/setup-node@v4
 with:
 node-version: "20"

 - name: Install dependencies
 run: |
 if [ -f package-lock.json ]; then npm ci; fi

 - name: Run Codex
 uses: openai/codex-action@v1
 with:
 openai-api-key: ${{ secrets.OPENAI_API_KEY }}
 prompt: |
 The CI workflow "${{ github.event.workflow_run.name }}" failed for commit
 ${{ github.event.workflow_run.head_sha }}.

 Run `npm test --silent` to reproduce the failure. Identify the minimal
 change needed to make the tests pass, implement only that change, and
 run `npm test --silent` again.

 Do not refactor unrelated files.

 - name: Create patch artifact
 id: diff
 run: |
 git add -N .
 git diff --binary HEAD > codex.patch
 if [ -s codex.patch ]; then
 echo "has_patch=true" >> "$GITHUB_OUTPUT"
 else
 echo "has_patch=false" >> "$GITHUB_OUTPUT"
 fi

 - name: Upload patch artifact
 if: steps.diff.outputs.has_patch == 'true'
 uses: actions/upload-artifact@v4
 with:
 name: codex-fix-patch
 path: codex.patch
 if-no-files-found: error

 open_pr:
 runs-on: ubuntu-latest
 needs: generate_fix
 if: needs.generate_fix.outputs.has_patch == 'true'
 permissions:
 contents: write
 pull-requests: write
 steps:
 - uses: actions/checkout@v5
 with:
 ref: ${{ github.event.workflow_run.head_sha }}
 fetch-depth: 0

 - uses: actions/download-artifact@v4
 with:
 name: codex-fix-patch

 - name: Apply Codex patch
 run: git apply --index codex.patch

 - name: Open pull request
 env:
 GH_TOKEN: ${{ github.token }}
 FAILED_HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
 FAILED_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
 RUN_ID: ${{ github.event.workflow_run.run_id }}
 run: |
 branch="codex/auto-fix-$RUN_ID"

 git config user.name "github-actions[bot]"
 git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
 git switch -c "$branch"
 git commit -m "Auto-fix failing CI via Codex"
 git push origin "$branch"

 {
 echo "Codex generated this patch after CI failed for \`$FAILED_HEAD_SHA\`."
 echo
 echo "Review the changes before merging."
 } > pr-body.md

 gh pr create \
 --base "$FAILED_HEAD_BRANCH" \
 --head "$branch" \
 --title "Auto-fix failing CI via Codex" \
 --body-file pr-body.md

Advanced stdin piping

When another command produces input for Codex, choose the stdin pattern based on where the instruction should come from. Use prompt-plus-stdin when you already know the instruction and want to pass piped output as context. Use codex exec - when stdin should become the full prompt.

Use prompt-plus-stdin

Prompt-plus-stdin is useful when another command already produces the data you want Codex to inspect. In this mode, you write the instruction yourself and pipe in the output as context, which makes it a natural fit for CLI workflows built around command output, logs, and generated data.

npm test 2>&1 \
 | codex exec "summarize the failing tests and propose the smallest likely fix" \
 | tee test-summary.md

Use codex exec - when stdin is the prompt

If you omit the prompt argument, Codex reads the prompt from stdin. Use codex exec - when you want to force that behavior explicitly.

The - sentinel is useful when another command or script is generating the entire prompt dynamically. This is a good fit when you store prompts in files, assemble prompts with shell scripts, or combine live command output with instructions before handing the whole prompt to Codex.

cat prompt.txt | codex exec -
printf "Summarize this error log in 3 bullets:\n\n%s\n" "$(tail -n 200 app.log)" \
 | codex exec -
generate_prompt.sh | codex exec - --json > result.jsonl

Loading docs agent...