Non-interactive mode allows you to run Codex without the terminal UI, making it ideal for automation, scripts, and CI/CD pipelines. Use the exec and review commands for headless execution.
The exec command
Run a one-off task without the interactive TUI:
Basic usage
From stdin
With dash
codex exec "run the test suite and fix any failures"
By default, exec provides human-readable output with progress indicators. For programmatic use, enable JSON output:
codex exec --json "run tests" > events.jsonl
This streams JSONL (JSON Lines) events that you can parse:
{ "method" : "turn/started" , "params" :{ "turn" :{ "id" : "turn_123" , "status" : "inProgress" }}}
{ "method" : "item/started" , "params" :{ "item" :{ "type" : "agentMessage" , "id" : "msg_1" }}}
{ "method" : "item/agentMessage/delta" , "params" :{ "itemId" : "msg_1" , "delta" : "Running" }}
{ "method" : "item/agentMessage/delta" , "params" :{ "itemId" : "msg_1" , "delta" : " tests..." }}
{ "method" : "item/completed" , "params" :{ "item" :{ "type" : "agentMessage" , "id" : "msg_1" , "text" : "Running tests..." }}}
{ "method" : "turn/completed" , "params" :{ "turn" :{ "id" : "turn_123" , "status" : "completed" }}}
Exit codes
codex exec returns meaningful exit codes for automation:
Exit Code Meaning 0Success - task completed 1General error 2Authentication failed 3Configuration error 4Model/API error 130Interrupted by user (Ctrl+C)
Command options
codex exec [OPTIONS] [PROMPT]
Options:
-m, --model < MODE L > Model to use (e.g., gpt-5.2-codex )
-s, --sandbox < MOD E > Sandbox mode: read-only, workspace-write, danger-full-access
-C, --cd < DI R > Working directory
-i, --image < FIL E > Attach images (comma-separated)
--json Output JSONL events
--ephemeral Don't persist session to disk
--output-schema <FILE> JSON Schema for structured output
-o, --output-last-message <FILE> Write final agent message to file
--color <WHEN> Color output: auto, always, never
--full-auto Auto-approve with workspace-write sandbox
--yolo Bypass all approvals (DANGEROUS)
The review command
Request an automated code review from Codex:
Review uncommitted changes
Review specific commit
Review against base branch
Custom review instructions
Review targets
The review command supports multiple targets:
Uncommitted
Commit
Base branch
Custom
Review staged, unstaged, and untracked files: Review a specific commit by SHA: Review changes since branching from main: Provide free-form instructions: codex review --instructions "Check for SQL injection vulnerabilities"
Review output
Reviews produce structured feedback:
╭─ Code Review ──────────────────────────────────────────╮
│ Overall: The changes look solid with minor suggestions │
│ │
│ Findings: │
│ │
│ • Consider adding error handling — auth.ts:42-55 │
│ The login function doesn't handle network failures │
│ │
│ • Extract magic number — config.ts:18 │
│ Use a named constant for the timeout value │
│ │
│ • Add input validation — api.ts:91 │
│ Validate user input before database queries │
╰─────────────────────────────────────────────────────────╯
Resume and continue
Non-interactive mode supports resuming previous sessions:
Resume last session
Resume by ID
Resume with JSON output
codex exec resume --last "add more test cases"
CI/CD integration
Codex is designed to integrate seamlessly into automated workflows.
GitHub Actions
Automated testing
Code review
name : Codex Auto-fix
on : [ push ]
jobs :
auto-fix :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v4
- name : Install Codex
run : |
curl -fsSL https://codex.openai.com/install.sh | sh
echo "$HOME/.codex/bin" >> $GITHUB_PATH
- name : Run tests and auto-fix
env :
OPENAI_API_KEY : ${{ secrets.OPENAI_API_KEY }}
run : |
codex exec --full-auto --json "run tests and fix any failures" | tee results.jsonl
- name : Check success
run : |
if [ $? -ne 0 ]; then
echo "Codex failed to fix tests"
exit 1
fi
GitLab CI
codex-review :
stage : test
image : ubuntu:latest
before_script :
- curl -fsSL https://codex.openai.com/install.sh | sh
- export PATH="$HOME/.codex/bin:$PATH"
script :
- codex review --base origin/main --json > review.jsonl
artifacts :
paths :
- review.jsonl
expire_in : 1 week
only :
- merge_requests
Jenkins
pipeline {
agent any
environment {
OPENAI_API_KEY = credentials( 'openai-api-key' )
}
stages {
stage( 'Install Codex' ) {
steps {
sh 'curl -fsSL https://codex.openai.com/install.sh | sh'
}
}
stage( 'Run Tests' ) {
steps {
sh '''
export PATH="$HOME/.codex/bin:$PATH"
codex exec --full-auto --json "run the test suite" > results.jsonl
'''
}
}
stage( 'Analyze Results' ) {
steps {
script {
def results = readJSON file : 'results.jsonl'
// Process JSONL events
}
}
}
}
}
Structured output
Constrain the agent’s response to a specific JSON schema:
codex exec \
--output-schema schema.json \
--json \
"analyze test coverage"
schema.json:
{
"type" : "object" ,
"properties" : {
"coverage_percentage" : { "type" : "number" },
"uncovered_files" : {
"type" : "array" ,
"items" : { "type" : "string" }
},
"recommendations" : {
"type" : "array" ,
"items" : { "type" : "string" }
}
},
"required" : [ "coverage_percentage" , "uncovered_files" , "recommendations" ],
"additionalProperties" : false
}
The final agent message will conform to this schema.
Ephemeral sessions
Run without persisting to disk:
codex exec --ephemeral "quick calculation: 2^16"
Useful for:
One-off queries
Sensitive data that shouldn’t be logged
Reducing disk I/O in high-volume scenarios
Automation best practices
Use --full-auto for trusted environments
In sandboxed CI runners, use --full-auto to auto-approve operations: codex exec --full-auto "install deps and run tests"
Enable JSON output for parsing
Always use --json in automation to get structured events: codex exec --json "task" | jq -r 'select(.method=="turn/completed")'
Check exit codes
Handle failures gracefully in scripts: if ! codex exec "run tests" ; then
echo "Tests failed"
exit 1
fi
Capture final output
Use --output-last-message for the agent’s final response: codex exec -o result.txt "summarize changes"
cat result.txt
Never use --yolo (dangerously bypass approvals) in production or on untrusted inputs. This disables all safety checks.
Parsing JSONL output
Using jq
# Extract all agent messages
codex exec --json "task" | jq -r 'select(.method=="item/agentMessage/delta") | .params.delta'
# Get final turn status
codex exec --json "task" | jq -r 'select(.method=="turn/completed") | .params.turn.status'
# Count commands executed
codex exec --json "task" | jq -r 'select(.method=="item/started" and .params.item.type=="commandExecution")' | wc -l
Using Python
import json
import subprocess
proc = subprocess.Popen(
[ "codex" , "exec" , "--json" , "run tests" ],
stdout = subprocess. PIPE ,
stderr = subprocess. PIPE ,
text = True
)
for line in proc.stdout:
event = json.loads(line)
if event[ "method" ] == "item/commandExecution/outputDelta" :
print (event[ "params" ][ "delta" ], end = "" )
elif event[ "method" ] == "turn/completed" :
print ( f " \n Status: { event[ 'params' ][ 'turn' ][ 'status' ] } " )
Next steps
Interactive mode Learn about the TUI for development
Sandboxing Understand security in automation