codex-image — gpt-image-2 via Codex OAuth subscription
Overview
Images are generated by gpt-image-2 through the Codex/ChatGPT OAuth subscription (token from ~/.codex/auth.json, created by codex login). No API key, no per-image cost — quota is shared with the Codex subscription.
Common misconception (documented agent failure): "Codex is text-only, image generation needs OPENAI_API_KEY / DALL-E." Wrong. The Codex backend (chatgpt.com/backend-api/codex) serves the image_generation tool over the Responses API; host model gpt-5.5 invokes it, gpt-image-2 renders.
Note: the Codex Claude Code plugin (openai/codex-plugin-cc) does NOT generate images — its role is review/architecture. This skill's script bypasses the plugin and talks to the Codex backend directly.
Setup (once)
Prerequisite — connect Codex first (this is how you get the token). The skill generates using the subscription OAuth token stored in ~/.codex/auth.json. To obtain that token you authenticate Codex once: install the Codex plugin and connect it to Claude Code (or use the Codex CLI directly), then log in — the login writes your subscription token to ~/.codex/auth.json. Only after Codex is connected and the token exists does generation work: scripts/run.sh reads that token and calls the Codex backend. Note: the Codex plugin's role is to connect Codex and produce the token — it does not itself render images; the rendering is done by this skill's own script over the Responses API.
- Install the Codex CLI:
npm install -g @openai/codex - Log in with your ChatGPT Plus/Pro (or Codex) subscription, not an API key:
codex login— on a headless server usecodex login --device-auth(gives a link + code you confirm from your phone). This writes the OAuth token to~/.codex/auth.json. - The Python
openaiSDK is bootstrapped automatically byscripts/run.shinto the skill's own venv — nothing to install by hand.
Quick reference
# self-contained launcher — uses the skill's own venv, bootstraps it if missing
scripts/run.sh "prompt in English" [quality] [aspect] [ref1.png ... ref5.png]
| Param | Values | Notes |
|---|---|---|
| quality | low (medium (default, ~1-2min) / high ( |
|
| aspect | landscape 1536x1024 / square 1024x1024 / portrait 1024x1536 |
|
| refN | up to 5 local image paths (png/jpg/webp) | passed as input_image data-URL content blocks; style/character/logo transfer. To use refs you MUST also pass quality and aspect (positional args) |
| output | prints path to PNG | saved in ~/.codex/cache/images/img_<ts>.png |
Reference E2E verified: avatar character correctly transferred into a new scene (technique from ningzimu/codex-gpt-image, audited — talks only to chatgpt.com/auth.openai.com).
Prompt in English works best. Generation is slow — for high use a background call.
Hard constraints (violating any → HTTP 400 or wrong path)
- References: max 5 images, as content blocks.
{"type":"input_image","image_url":"data:<mime>;base64,...","detail":"auto"}placed NEXT TOinput_textin the same user message. There is no seed parameter — for strict reproducibility a paid API (fal.ai FLUX) is still the better tool; for character/style/logo transfer this works. - Never
client.images.generate()/ Images API — that is the API-key path, the OAuth subscription rejects it. Only Responses API + toolimage_generation(+tool_choice={"type":"image_generation"}so the host model draws immediately). stream=Trueandstore=Falseare mandatory — otherwise HTTP 400 from the Codex backend.inputmust be a LIST of message objects, not a bare string.- Auth:
tokens.access_token(+tokens.account_id→chatgpt-account-idheader) from~/.codex/auth.json. Required headers:OpenAI-Beta: responses=experimental,originator: codex_cli_rs.
Troubleshooting
| Symptom | Fix |
|---|---|
ModuleNotFoundError: openai |
run via scripts/run.sh (skill's own venv), NOT system python3 — it lacks the SDK |
Codex auth не найден |
codex login (headless server: codex login --device-auth) |
| HTTP 400 | check stream=True, store=False, input as message list |
| 401/403 | token expired — re-run codex login; check account_id header |
| No image in stream | model refused (policy) — rephrase prompt |
When NOT to use
- Deterministic graphics (avatars, banners, diagrams with exact typography/brand colors): hand-author SVG → render PNG via
@resvg/resvg-js. A model will not hit exact brand colors or spell long headlines reliably. - Reference-image / character-consistent pipelines: needs a paid image API (e.g. fal.ai FLUX), not this skill.
The skill is fully self-contained (script + own .venv, auto-bootstrapped by run.sh). E2E verified: low/square PNG generated via run.sh.