Generate and edit images with gpt-image-2 by reusing the OAuth token the Codex CLI already
stored at ~/.codex/auth.json. The gpt-image CLI talks directly to ChatGPT's Codex
backend — no API key, no proxy, no server. It saves each image with a 6-char id and returns the
absolute path in a JSON envelope, then tells you (via next_action) to Read the image and
revise. This closes a tight generate → inspect → revise loop you can run unattended.
Prerequisites
- The user is logged into the Codex CLI so
~/.codex/auth.jsonexists. If missing, the CLI returnserror.class:"auth"with the suggestioncodex login. python3(>= 3.7). No pip packages — the CLI is stdlib-only.- Install the command once:
scripts/install.sh(putsgpt-imageon~/.local/bin). If it's not on PATH, call the script directly:scripts/gpt-image ....
The loop — GENERATE → READ → CRITIQUE → REVISE
- Generate:
gpt-image "<prompt>" -r <ratio>(write the prompt with the structure inreferences/prompting.md— don't free-style it). - Read: take
result.pathfrom the JSON and use your Read tool on it. Looking is mandatory — never assume the output from the prompt. - Critique (rethink): score what you actually see against the brief — intended use, text verbatim/legible, invariants preserved (edits), on-brand, no artifacts.
- Revise (modify): ~80% there →
gpt-image edit -i <result.path> "<one change>"and restate the invariants; wrong concept → rewrite the base prompt and regenerate. Read again.
Repeat until the critique passes. Each call prints next_action.command with the next step.
Writing the prompt — read the guide first
First-pass quality is decided by the prompt, not the flags. Before your FIRST
gpt-image gen/edit in a task, read references/prompting.md (the meta-guidance hub),
then load the ONE spoke that matches your case. This is a hard precondition — skipping it is
how you get rerolls and slop.
references/prompting.md— fundamentals, the 11-part prompt-body order, the GENERATE→READ→CRITIQUE→REVISE loop, parameter quick-rules, and routing.references/prompting/generate.md— text→image recipes (infographic, photoreal, logo, ad, comic, UI mock, science, slide, greeting card, merch).references/prompting/edit.md— text+image→image recipes (translation, style transfer, try-on, sketch→render, product mockup, in-image text, relight, removal, composite, interior swap, character consistency).references/prompting/variants.md— generating distinct alternatives: one invariant spine, vary ONE axis (composition/lighting/medium/focal/density/palette), spread wide, converge.references/prompting/parameters.md— size constraints, quality/ratio, and the API params that are not CLI flags (n→ loop;background/input_fidelity→ prompt language).
Commands
gpt-image "<prompt>" # generate (default subcommand)
gpt-image gen "<prompt>" [opts] # explicit generate
gpt-image edit -i <img> [-i <img2>] "<prompt>" [--mask <m>] # edit existing image(s)
gpt-image doctor # check the local login + token (spends nothing)
Options: -r/--ratio (1:1/square, 3:2/landscape, 2:3/portrait, auto), --size WxH
(overrides ratio), -q/--quality, -o/--outdir (default: cwd), -m/--model, --auth <path>,
--max-wait <s> (rate-limit auto-wait budget; default 60, max 300, 0 off).
Env defaults: GPT_IMAGE_RATIO, GPT_IMAGE_QUALITY, GPT_IMAGE_OUTDIR, GPT_IMAGE_MODEL,
GPT_IMAGE_MAX_WAIT.
| ratio | size |
|---|---|
1:1 / square |
1024x1024 |
3:2 / landscape |
1536x1024 |
2:3 / portrait |
1024x1536 |
auto |
model picks |
Output envelope
Stdout is pure JSON (stderr carries human hints):
{ "ok": true,
"result": { "path": "/abs/cwd/6d2bd1.png", "paths": ["..."], "id": "6d2bd1",
"model": "gpt-image-2", "ratio": "3:2", "size": "1536x1024",
"revised_prompt": "...", "bytes": 3325293 },
"error": null,
"next_action": { "command": "Read /abs/cwd/6d2bd1.png",
"hint": "View it, then: gpt-image edit -i /abs/cwd/6d2bd1.png \"<changes>\"" },
"schema_version": "v1" }
Exit codes
0 ok · 2 usage · 3 auth (no/expired login → codex login) · 4 not_found (account lacks
image entitlement) · 6 validation (empty prompt, bad ratio, missing image) · 7 transient
(rate limit / network / upstream — retry) · 1 other.
Rate limits & plan usage
Codex has two caps and the CLI handles both:
- Short per-minute image bucket: the error says
try again in <N>ms/s. The CLI parses that and auto-waits + retries up to--max-waitseconds (default 60, max 300,0disables; envGPT_IMAGE_MAX_WAIT). Short throttles clear themselves — no agent action needed. - Account plan windows: a 5h
primaryand weeklysecondarywindow. The CLI reports them asresult.usage_limitson every success (used %, window minutes,reset_after_seconds,reset_at), andgpt-image doctorechoes the last-seen values.
If you still get 7 RATE_LIMITED, the reset was beyond --max-wait. The error envelope carries
retry_after_seconds, plan_reset_at, and usage_limits — read those to know exactly when to
retry instead of guessing. Don't hammer it; wait for the stated window.
Notes for agents
- Always Read the returned
result.pathbefore deciding the next edit — don't assume the output; look at it. - The CLI never modifies
~/.codex/auth.json; refreshed tokens are cached separately in~/.config/gpt-image/token.json. - Prompt craft is mandatory reading:
references/prompting.mdis the hub; its four spokes (prompting/generate.md,prompting/edit.md,prompting/variants.md,prompting/parameters.md) hold the per-case recipes, the variant system, and the size rules. Read the hub before your first generate/edit, then the one matching spoke. - Internals (OAuth refresh, the Codex responses wire format, troubleshooting) live in
references/(codex-auth.md,wire-format.md,troubleshooting.md). Read them only if something breaks or you're extending the CLI.