Codex
Use the OpenAI Codex CLI and Codex app against LuluTokens with a custom model provider.
Codex talks the Responses API, which the gateway relays at
POST /v1/responses. You wire it up by declaring a custom model provider in
~/.codex/config.toml.
Configure
Add the provider
model_provider = "lulutokens"
model = "gpt-5.4"
[model_providers.lulutokens]
name = "LuluTokens"
base_url = "https://api.lulutokens.ai/v1"
wire_api = "responses"
http_headers = { Authorization = "Bearer sk-..." }{
"auth_mode": "apikey",
"OPENAI_API_KEY": "sk-..."
}Replace sk-... with your real key in both files. http_headers sends a
literal value — it does not expand $VARIABLES — so the key has to be
written out. Both files therefore hold a secret: keep them out of any dotfiles
repo.
To keep the key out of the config file, use env_http_headers instead — it reads
the header value from an environment variable at request time:
env_http_headers = { Authorization = "LULUTOKENS_AUTH" }export LULUTOKENS_AUTH="Bearer sk-..."Note that the variable holds the whole header value, Bearer prefix
included.
Run it
codexAsk it something small first — what files are in this directory? — to confirm
the round trip works before starting real work.
Keeping your OpenAI login too
If you also use Codex against OpenAI directly, put LuluTokens in a profile instead of making it the global default:
[model_providers.lulutokens]
name = "LuluTokens"
base_url = "https://api.lulutokens.ai/v1"
wire_api = "responses"
http_headers = { Authorization = "Bearer sk-..." }
[profiles.lulu]
model_provider = "lulutokens"
model = "gpt-5.4"codex --profile luluModels that only speak Chat Completions
Not every model is exposed through the Responses API. For those, set the
provider's wire format to chat — Codex will then call
POST /v1/chat/completions instead:
[model_providers.lulutokens-chat]
name = "LuluTokens (chat)"
base_url = "https://api.lulutokens.ai/v1"
http_headers = { Authorization = "Bearer sk-..." }
wire_api = "chat"Some agentic features degrade on the chat wire format, so prefer responses
where the model supports it.
Tool support
Codex works, with one limitation worth knowing up front: only function-calling tools are supported. Tools that exist only in the Responses API are not available through the gateway.
| Codex feature | Status |
|---|---|
| Running commands, reading and writing files | Works |
| Function calling | Works |
apply_patch (structured diffs) | Not available — Codex edits files through shell commands instead |
| Built-in web search | Not available |
In practice you will not notice much beyond slightly more verbose edits on large files: instead of emitting a patch, Codex rewrites through the shell.
This is an upstream constraint, not a setting on your account — the provider behind these models terminates on a Chat Completions endpoint, which accepts only function tools. Nothing to configure on your side.
Troubleshooting
| Symptom | Cause |
|---|---|
401 | The key in http_headers / auth.json is wrong, or the Bearer prefix is missing. A literal $VARIABLE left in http_headers also lands here — it is not expanded |
404 | base_url is missing the /v1 suffix |
400 model_not_found | The model value is not enabled on your account |
| Hangs, then fails | The model does not support wire_api = "responses" — try chat |
422 … Invalid value: 'tool_search' | An unsupported tool type reached the provider. This should not happen on api.lulutokens.ai — please report it if it does |
422 … Missing required parameter: 'tools[N].custom' | Same cause as above |
Codex config keys have changed across releases. If codex rejects the file,
check the key names against your installed version with codex --help and the
Codex documentation.