Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,15 @@
# OPENAI_SESSION_STICKY_KEYS=false
# OPENAI_BASE_URL=https://api.openai.com/v1

# ChatGPT subscription (Codex backend, /v1/responses only)
# Billed against your ChatGPT plan instead of OpenAI Platform credit. The key is
# the access token from `codex login`; it expires roughly every 10 days.
# CHATGPT_API_KEY=$(jq -r .tokens.access_token ~/.codex/auth.json)
# CHATGPT_API_KEY=
# CHATGPT_BASE_URL=https://chatgpt.com/backend-api/codex
# Optional model override; defaults to the models a ChatGPT plan can call.
# CHATGPT_MODELS=gpt-5.6-sol,gpt-5.6-terra,gpt-5.6-luna,gpt-5.5

# Anthropic
# Accepts a Console API key (sk-ant-api...) or a Claude subscription OAuth
# token from `claude setup-token` (sk-ant-oat...; Claude Code traffic only).
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,9 @@ GoModel supports OpenAI, Anthropic, Cohere, Google Gemini, Vertex AI, DeepSeek,
Groq, Fireworks AI, Meta (Muse Spark), OpenRouter, Z.ai, xAI (Grok), Alibaba
Cloud Model Studio (Bailian), Kilo AI, MiniMax, Xiaomi MiMo, OpenCode Go, Azure
OpenAI, Oracle, Ollama, SGLang, vLLM, llm-d, Amazon Bedrock Runtime, Amazon
Bedrock Mantle, and all OpenAI-compatible providers. Voice: ElevenLabs
(text-to-speech and speech-to-text).
Bedrock Mantle, and all OpenAI-compatible providers. Subscription-billed:
ChatGPT (the Codex backend) and Claude. Voice: ElevenLabs (text-to-speech and
speech-to-text).

See the [Providers Overview](https://gomodel.enterpilot.io/docs/providers/overview?utm_source=readme) for the full
per-provider feature matrix (chat, `/responses`, embeddings, files, batches,
Expand Down
8 changes: 8 additions & 0 deletions config/config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ providers:
type: anthropic
api_key: "sk-ant-..."

# ChatGPT subscription (Codex backend). Serves /v1/responses only and is
# billed against your ChatGPT plan. The key is the access token from
# `codex login`: jq -r .tokens.access_token ~/.codex/auth.json
chatgpt:
type: chatgpt
api_key: "${CHATGPT_API_KEY}"
# models: [gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gpt-5.5]

cohere:
type: cohere
api_key: "${COHERE_API_KEY}"
Expand Down
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
"providers/overview",
"providers/key-rotation",
"providers/anthropic",
"providers/chatgpt",
"providers/cohere",
"providers/gemini",
"providers/deepseek",
Expand Down
228 changes: 95 additions & 133 deletions docs/guides/codex.mdx
Original file line number Diff line number Diff line change
@@ -1,130 +1,116 @@
---
title: "GoModel & Codex"
description: "Route OpenAI Codex through GoModel's Responses API: run the gateway with Docker, point Codex at it with a master key, and verify the setup."
description: "Put GoModel between Codex and your models: keep billing on your ChatGPT subscription, or route Codex to any other provider."
icon: "code-xml"
keywords: ["Codex", "OpenAI Codex", "coding agent", "setup guide"]
keywords: ["Codex", "OpenAI Codex", "ChatGPT subscription", "coding agent", "setup guide"]
---

GoModel is a good fit for Codex because Codex already targets the OpenAI
Responses API.

Flow:
`Codex -> GoModel -> upstream`

`Codex -> GoModel -> upstream model provider`
Codex talks to GoModel with a GoModel master key, so every request shows up in
the dashboard. The one choice to make is which provider serves the model,
because that decides what pays for it:

| Provider | Upstream | Billing |
| -------- | -------- | ------- |
| [`chatgpt`](/providers/chatgpt) | The Codex backend behind your ChatGPT plan | ChatGPT subscription quota |
| `openai`, [`deepseek`](/providers/deepseek), [`anthropic`](/providers/anthropic), [any other](/providers/overview) | That provider's API | That provider's API credit |

Everything after this point is the same either way.

## Before you start

- Install Codex on your machine.
- Choose a GoModel master key, for example `change-me`.
- Make sure GoModel has the upstream provider key for the models you want to use.

<Note>
You can keep using Codex with a ChatGPT subscription sign-in, but GoModel
still needs a gateway credential from Codex and an upstream provider key of
its own. In this guide, `OPENAI_API_KEY=change-me` is the GoModel master key
that Codex sends to GoModel, not your OpenAI Platform key.
</Note>

## 1. Run GoModel
To bill Codex to your ChatGPT plan, sign in once so Codex writes its token
file, then hand that token to GoModel:

Start GoModel with a master key and an OpenAI provider key:
```bash
codex login
export CHATGPT_API_KEY=$(jq -r .tokens.access_token ~/.codex/auth.json)
```

```bash
docker run --rm -p 8080:8080 \
-e GOMODEL_MASTER_KEY="change-me" \
-e OPENAI_API_KEY="sk-..." \
-e CHATGPT_API_KEY="$CHATGPT_API_KEY" \
enterpilot/gomodel
```

## 2. Confirm the Responses API
See the [ChatGPT provider page](/providers/chatgpt) for the model list, the
token's ~10-day lifetime, and which Responses parameters that backend accepts.

Before testing Codex itself, you can optionally verify that GoModel answers a
normal Responses API request:
To bill it to API credit instead, configure any other provider as usual — for
example `-e OPENAI_API_KEY="sk-..."` — and use one of its models in step 2.

This step is optional. If you are sure you have configured a valid
`OPENAI_API_KEY` in GoModel, you can skip it and go straight to
[step 3](#3-configure-codex-to-use-gomodel).
## 1. Confirm the Responses API

<CodeGroup>
Optional: check that GoModel answers a plain Responses request before involving
Codex. Use a model your configured provider actually serves.

```bash curl
```bash
curl -s http://localhost:8080/v1/responses \
-H "Authorization: Bearer change-me" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4.1-mini",
"input": "Reply with exactly ok",
"max_output_tokens": 16
}'
-d '{"model": "gpt-5.6-sol", "input": "Reply with exactly ok"}'
```

```python Python
from openai import OpenAI
The response contains `ok`. For the Python and JavaScript equivalents, see the
[Responses API reference](/advanced/responses-api).

client = OpenAI(base_url="http://localhost:8080/v1", api_key="change-me")

response = client.responses.create(
model="gpt-4.1-mini",
input="Reply with exactly ok",
max_output_tokens=16,
)

print(response.output_text)
```

```javascript JavaScript
import OpenAI from "openai";

const client = new OpenAI({
baseURL: "http://localhost:8080/v1",
apiKey: "change-me",
});

const response = await client.responses.create({
model: "gpt-4.1-mini",
input: "Reply with exactly ok",
max_output_tokens: 16,
});

console.log(response.output_text);
```
## 2. Configure Codex to use GoModel

</CodeGroup>

If the gateway is wired correctly, the response will contain `ok`.

## 3. Configure Codex to use GoModel

Use a Responses-based provider in your Codex config file:
Add a Responses-based provider to `~/.codex/config.toml`:

```toml
model_provider = "gomodel"
model = "gpt-4.1-mini"
model = "gpt-5.6-sol" # or any model your GoModel serves

[model_providers.gomodel]
name = "GoModel"
base_url = "http://localhost:8080/v1"
env_key = "OPENAI_API_KEY"
env_key = "GOMODEL_API_KEY"
wire_api = "responses"
```

Then export the GoModel master key for that provider:

```bash
export OPENAI_API_KEY=change-me
export GOMODEL_API_KEY=change-me
```

<Note>
Codex `0.122.0` did not use the `OPENAI_BASE_URL` environment variable in
local validation. Use the provider config above, or set `openai_base_url` in
Codex config if you intentionally want to override the built-in OpenAI
provider.
Codex requires this variable even when you are signed in with ChatGPT, and it
carries the GoModel master key — not an OpenAI key. Without it the provider
fails to start.
</Note>

## 4. Run a Codex test prompt
To try it without editing your config, pass the same settings inline:

```bash
codex exec -m gpt-4.1-mini 'Reply with exactly ok and no punctuation.'
GOMODEL_API_KEY=change-me codex exec \
-c model_provider=gomodel \
-c 'model_providers.gomodel.name="GoModel"' \
-c 'model_providers.gomodel.base_url="http://localhost:8080/v1"' \
-c 'model_providers.gomodel.env_key="GOMODEL_API_KEY"' \
-c 'model_providers.gomodel.wire_api="responses"' \
-m gpt-5.6-sol 'Reply with exactly ok and no punctuation.'
```

<Note>
Codex ignores `OPENAI_BASE_URL`. Use the provider config above, or set
`openai_base_url` in Codex config if you intentionally want to override the
built-in OpenAI provider.
</Note>

## 3. Run a Codex test prompt

```bash
codex exec -m gpt-5.6-sol 'Reply with exactly ok and no punctuation.'
```

The validated result was:
Expand All @@ -133,87 +119,63 @@ The validated result was:
ok
```

<Note>
Codex 0.147.0 logs `failed to refresh available models: missing field
"models"` at startup. It calls its own catalogue endpoint, which GoModel
answers with the standard OpenAI `/v1/models` shape. The message is cosmetic
— Codex falls back and the session works.
</Note>

## 4. Check the traffic in GoModel

Open the GoModel dashboard audit logs:

[http://localhost:8080/admin/dashboard/audit](http://localhost:8080/admin/dashboard/audit)

This lets you confirm that Codex is reaching GoModel and inspect the full
request and response trail. From the same dashboard, you can keep following
your GoModel traffic and usage.

## DeepSeek V4

Codex sends `POST /v1/responses`. DeepSeek exposes chat completions instead of
a native Responses API, so configure the first-class DeepSeek provider and let
GoModel translate the request.
Codex sends `POST /v1/responses`, which DeepSeek does not serve natively. Use
`type: deepseek` rather than `type: openai`: the DeepSeek provider translates
`/responses` to `/chat/completions`, while the generic OpenAI provider forwards
it upstream unchanged.

```yaml
providers:
deepseek:
type: deepseek
base_url: "https://api.deepseek.com"
api_key: "${DEEPSEEK_API_KEY}"
```

If you previously configured DeepSeek as `type: openai`, change it to
`type: deepseek` for Codex. The generic OpenAI provider forwards `/responses`
upstream, while the DeepSeek provider translates `/responses` to
`/chat/completions`.

See the [DeepSeek guide](/providers/deepseek) for the full reasoning effort
mapping table (DeepSeek V4 only accepts `high` and `max`, so GoModel maps
`low` and `medium` up to `high`).

Codex attaches `include: ["reasoning.encrypted_content"]` to every Responses
request. GoModel ignores it on chat-translated providers, so the response
carries no encrypted reasoning items. See
[Responses compatibility](/advanced/responses-compatibility) for the full
feature matrix.

Then use the DeepSeek model name in Codex:

```toml
model_provider = "gomodel"
model = "deepseek-v4-pro"

[model_providers.gomodel]
name = "GoModel"
base_url = "http://localhost:8080/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"
```

## 5. Check the traffic in GoModel

Open the GoModel dashboard audit logs:

[http://localhost:8080/admin/dashboard/audit](http://localhost:8080/admin/dashboard/audit)

This lets you confirm that Codex is reaching GoModel and inspect the full
request and response trail. From the same dashboard, you can keep following
your GoModel traffic and usage.
Then set `model = "deepseek-v4-pro"` in the Codex config from step 2. See the
[DeepSeek page](/providers/deepseek) for the reasoning-effort mapping, and
[Responses compatibility](/advanced/responses-compatibility) for what
chat-translated providers drop — including the `reasoning.encrypted_content`
Codex asks for on every request.

## Current status

- the recommended integration path is Codex custom provider -> standard
`http://localhost:8080/v1`
- Codex custom provider mode sends `POST /v1/responses`
- Codex `0.122.0` sends an uncompressed JSON request body in this path, so the
- Codex custom provider mode sends `POST /v1/responses` as plain JSON, so the
old `--disable enable_request_compression` workaround is no longer required
- ChatGPT subscription sign-in can coexist with the custom provider, but the
custom provider still requires the configured `env_key`

## References

- OpenAI Codex discussion: [Deprecating `chat/completions` support in Codex](https://github.com/openai/codex/discussions/7782)
- OpenAI Codex repository: [openai/codex](https://github.com/openai/codex)

## Validated on April 21, 2026

This guide was validated against:

- a local GoModel instance on `http://localhost:8080`
- Codex CLI `0.122.0`
## Validated on August 20, 2026

Local validation confirmed:
This guide was validated against a local GoModel instance and Codex CLI
`0.147.0`. Local validation confirmed:

- `POST /v1/responses` returned `200 OK` with `curl`
- `codex exec` returned `ok` through `Codex -> GoModel -> OpenAI-compatible upstream`
- Codex sent plain JSON to `POST /v1/responses`; no `Content-Encoding: zstd`
header was present
- a ChatGPT-signed-in Codex session worked with the custom `gomodel` provider
when `OPENAI_API_KEY` was set to the GoModel master key
- the same custom provider failed without `OPENAI_API_KEY`, because the provider
`env_key` is still required
- `codex exec` returned `ok` through `Codex -> GoModel -> ChatGPT subscription`
- `POST /v1/responses` returned `200 OK` for both streaming and non-streaming
callers
- Codex sent plain JSON; no `Content-Encoding: zstd` header was present
- the custom `gomodel` provider failed without its `env_key`, because Codex
still requires that variable when signed in with ChatGPT
Loading