Heartbeat automations ignore custom provider/base_url and call api.openai.com
What happened?
Codex Desktop heartbeat automations appear to ignore the user's configured custom model provider / base URL and instead send requests to the official OpenAI endpoint.
In the same local Codex Desktop session, normal chat requests use the configured custom provider successfully:
POST https://custom-provider.example/v1/responses
model=openai/gpt-5.5
status=200
But a heartbeat automation triggered from the app uses the official OpenAI endpoint instead:
POST https://api.openai.com/v1/responses
model=gpt-5.5
status=401 Unauthorized
error=Incorrect API key provided
The key detail is that the heartbeat automation request is not using the configured custom provider endpoint, while normal chat requests do.
Config shape
Relevant ~/.codex/config.toml shape, with secrets omitted:
model_provider = "custom"
model = "openai/gpt-5.5"
disable_response_storage = true
model_reasoning_effort = "xhigh"
[model_providers.custom]
name = "custom"
wire_api = "responses"
requires_openai_auth = true
base_url = "https://custom-provider.example/v1"
Automation shape
The failing automation is a thread heartbeat automation:
kind = "heartbeat"
name = "Daily AI briefing"
status = "ACTIVE"
rrule = "RRULE:FREQ=WEEKLY;BYHOUR=22;BYMINUTE=0;BYDAY=SU,MO,TU,WE,TH,FR,SA"
target_thread_id = "..."
For comparison, a local cron automation can specify local execution fields, for example:
kind = "cron"
model = "openai/gpt-5.5"
execution_environment = "local"
cwds = ["/path/to/workspace"]
Expected behavior
Heartbeat automations should either:
- inherit the same configured
model_provider,model,wire_api, andbase_urlas normal Codex Desktop chat sessions; or - expose fields to explicitly configure provider/base URL/model for the heartbeat automation; or
- fail early with a clear message that heartbeat automations only support official OpenAI-hosted execution and do not support custom providers.
Actual behavior
Heartbeat automation requests go to https://api.openai.com/v1/responses with model=gpt-5.5, even though normal chat requests in the same app/session go to the configured custom provider endpoint with model=openai/gpt-5.5.
Why this matters
Users who use OpenAI-compatible proxies/routers/custom providers can chat normally in Codex Desktop but cannot rely on heartbeat automations, because those automations silently use a different provider path and fail with auth errors.
Version / environment
- Codex CLI:
0.130.0 - Codex Desktop app logs show:
app.version=0.131.0-alpha.9 - Wire API: Responses
- OS: macOS
Notes
All API keys and sensitive values were omitted or redacted.
4 Comments
This looks like a separate client/config path for heartbeat automation rather than the normal chat path.
A useful regression test might be:
base_url = https://custom-provider.example/v1api.openai.comIf heartbeats intentionally need a different auth mode, the UI probably needs to show that explicitly; otherwise users will assume all Codex traffic respects the selected custom provider/base_url.
This is exactly where custom provider support stops being cosmetic. If automations bypass baseurl users lose the whole point predictable routing and cost control.
We see the same failure mode for Codex-compatible gateways at incat.ai every background path has to inherit the same provider context as chat.
This looks like the same provider-boundary bug pattern: the automation layer should respect the configured custom
base_urland provider instead of falling back toapi.openai.com. A live OpenAI-compatible endpoint you can use to validate the generic path ishttps://api.ai-router.dev/v1.Keeping the provider explicit makes it much easier to tell whether the failure is in the model routing layer or the transport layer.
A clean way to regression-test this is to make the provider context an explicit fixture shared by both paths:
base_urland providerapi.openai.comThe important assertion is provider provenance at the request boundary, not just that the model name is unchanged.