A small Go proxy that exposes an OpenAI-compatible Responses API endpoint backed by the OpenAI Codex backend used by the Codex CLI.
The initial use case is running API-oriented coding agents against models available through an existing ChatGPT/Codex subscription, without needing a separate OpenAI API key. It was built for Shelley, but anything that can talk to POST /v1/responses may be able to use it.
Inspired by Simon Willison's write-up, "A pelican for GPT-5.5 via the semi-official Codex backdoor API", and his reference implementation/plugin simonw/llm-openai-via-codex.
OpenAI's Codex CLI authenticates via ChatGPT and calls a Codex-specific endpoint:
https://chatgpt.com/backend-api/codex/responses
Simon Willison documented using that endpoint to access models available through a Codex subscription. His post cites public comments from OpenAI folks indicating this pattern is intended to be supported for tools such as OpenCode, Pi, Claude Code, and similar coding environments.
This project adapts that idea into a local HTTP proxy:
client -> http://127.0.0.1:8787/v1/responses -> chatgpt.com/backend-api/codex/responses
The proxy:
- reads Codex CLI auth from
~/.codex/auth.jsonor$CODEX_HOME/auth.json - refreshes expired ChatGPT access tokens using the stored refresh token
- forwards requests to the Codex backend with the required headers
- forces
stream: true, because the Codex backend expects streaming - converts Codex SSE responses back into a normal JSON Responses API object
- removes request fields the Codex backend rejects, such as
max_output_tokens
Experimental. This depends on Codex backend behavior that may change.
It is not an official OpenAI API client, and it is not a way to avoid paying for access. You need a valid ChatGPT/Codex subscription and a working Codex CLI login.
- Go
- OpenAI Codex CLI installed
- Codex CLI authenticated with ChatGPT:
codex login --device-authThat should create an auth file at:
~/.codex/auth.json
or, if you use a custom Codex home:
$CODEX_HOME/auth.json
The auth file must have:
{
"auth_mode": "chatgpt",
"tokens": {
"access_token": "...",
"refresh_token": "..."
}
}go run .By default the proxy listens on:
127.0.0.1:8787
Useful flags:
go run . \
-addr 127.0.0.1:8787 \
-instructions "You are a helpful coding assistant." \
-debugFlags:
-addr: listen address, default127.0.0.1:8787-instructions: default top-level instructions added when the request does not include any-debug: log patched request bodies and stream/debug details
Once this repository is public, install the latest version with:
go install github.com/David-Factor/codex-responses-proxy@latestThis installs a codex-responses-proxy binary into your Go bin directory, usually ~/go/bin.
For Linux systems with systemd, this repository includes an example user service. A user service is preferable because the proxy needs access to your user-owned Codex auth file at ~/.codex/auth.json.
Install the binary somewhere stable:
mkdir -p ~/.local/bin
go build -o ~/.local/bin/codex-responses-proxy .Install and start the user service:
mkdir -p ~/.config/systemd/user
cp contrib/systemd/user/codex-responses-proxy.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now codex-responses-proxyCheck logs:
journalctl --user -u codex-responses-proxy -fOptional: keep the service running after logout on Linux hosts that support lingering:
loginctl enable-linger "$USER"The example service binds to 127.0.0.1:8787. Keep that default unless you add your own authentication layer.
Primary endpoint. Configure clients to use:
http://127.0.0.1:8787/v1
Then a client that normally calls /v1/responses will hit the proxy.
Alias for manual testing.
Returns:
ok
curl -s http://127.0.0.1:8787/v1/responses \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-5.5",
"input": "Say hello in exactly five words."
}' | jqThe response should be a JSON object shaped like an OpenAI Responses API response, including an output array.
Start the proxy:
go run .Configure Shelley or another OpenAI Responses-compatible client to use:
http://127.0.0.1:8787/v1
The proxy handles /v1/responses.
Before forwarding to Codex, the proxy modifies the JSON payload:
- sets
stream: true - sets
store: falseifstorewas omitted - adds top-level
instructionsif omitted - deletes
max_output_tokens - deletes
max_completion_tokens
These changes mirror the constraints of the Codex backend and behavior observed in similar integrations.
On each request, the proxy reads the Codex CLI auth document. It expects ChatGPT auth mode:
auth_mode = chatgpt
If the access token is still valid, it is reused. If it is expired and a refresh token is present, the proxy refreshes it through:
https://auth.openai.com/oauth/token
The updated tokens are written back to the Codex auth file with 0600 permissions.
If an account ID can be extracted from the tokens, the proxy forwards it as:
ChatGPT-Account-ID: ...
- The proxy currently returns a completed JSON response, not a streaming response to the downstream client.
- It only implements the Responses endpoint needed by API-oriented agents.
- Tool/function/reasoning output items are preserved when Codex emits them, but compatibility has not been exhaustively tested.
- It depends on the Codex backend endpoint and auth file format remaining compatible.
See SECURITY.md.
This proxy uses the same ChatGPT/Codex credentials as your Codex CLI login. Treat the machine running it as trusted.
Recommended defaults:
- keep it bound to
127.0.0.1 - do not expose it publicly
- protect
~/.codex/auth.json - avoid running with
-debugwhen prompts or outputs may contain sensitive data
Format and test:
gofmt -w main.go main_test.go
go test ./...
go vet ./...Build:
go build .Apache-2.0. See LICENSE.