---
title: "OpenAI"
description: "Route mapped models to the OpenAI Responses API with an OPENAI_API_KEY — translation, effort, token counting, and tool search."
image: "https://shunt-docs.pages.dev/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://shunt-docs.pages.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI

The built-in **`openai`** provider routes a mapped model's inference to the **OpenAI platform
API** (`api.openai.com`), billed per token against an `OPENAI_API_KEY`. It is a
**`kind = "responses"`** provider: shunt translates Claude Code's Anthropic Messages request into
the OpenAI **Responses API**, streams the reply back, and translates it again — tools, images,
and streaming included.

> **API key vs. ChatGPT subscription**
>
> `openai` spends metered **API credits**. To spend a **ChatGPT/Codex subscription** instead
> (reusing `codex login`, no per-token billing), use the [`codex` provider](/guides/codex/) — same
> translation path, different backend and auth.

## Quick start

Let a coding agent wire it up for you — `shunt add` prints an embedded setup blueprint
(offline and read-only; the agent edits the config, the command never does):

```bash
shunt add upstream openai --print | claude
```

Or follow the manual steps below.

## Configure the upstream

The `openai` preset supplies `kind = "responses"`, `base_url = "https://api.openai.com/v1"`
(shunt appends `/responses`), and API-key auth from `OPENAI_API_KEY`:

```toml
[[upstreams]]
name = "anthropic"
provider = "anthropic"   # keep Anthropic as the default for unrouted models (e.g. claude-*)

[[upstreams]]
name = "openai"
provider = "openai"
# effort = "high"          # optional default reasoning effort
# count_tokens = "tiktoken" # default; "estimate" opts out of local counting
```

Ordered `[[upstreams]]` replace shunt's built-in providers, so the config must declare the
`anthropic` default it still falls back to (`server.default_provider` defaults to `anthropic`).

Explicit fields override preset defaults. The legacy `[providers.openai]` table form remains
supported — but do not mix `[[upstreams]]` and `[providers.*]` in one file.

## Credentials

Export the key in the environment that launches shunt — never write it into the config:

```bash
export OPENAI_API_KEY='...'
```

`shunt check` validates the config's structure but does not read the key's value — if
`OPENAI_API_KEY` is unset, the first request routed to `openai` returns an authentication error.

## Models & routing

Route ids exactly, by prefix, or advertise a Claude-named alias to
[model discovery](/guides/model-discovery/):

```toml
# Recommended: advertise + route + translate in one declaration
[[models]]
id = "claude-gpt-5-4-via-openai"
display_name = "GPT-5.4 (via OpenAI)"

[models.upstream_model]
openai = "gpt-5.4"

# Or catch every gpt-* id a client sends
[[route_prefixes]]
prefix = "gpt-"
provider = "openai"
```

Verify current model availability on your OpenAI account before selecting a slug. Unlike the
ChatGPT-account Codex backend, the platform API accepts its regular public slugs.

## Reasoning effort, context, and token counting

The Responses translation supports a per-provider or per-route reasoning-effort dial
(`low` … `max`) and local tiktoken-based `count_tokens` so Claude Code's context accounting keeps
working. Both are shared with the other Responses providers and documented in
[Effort & Context](/guides/effort-and-context/).

**Tool search.** With Claude Code's `ENABLE_TOOL_SEARCH=true`, shunt emulates deferred tool
discovery on the Responses path via a text shim; setting `tool_search = true` on the provider
upgrades it to the Responses API's native client-executed `tool_search` protocol on GPT-5.4+
models. See [Tool search](/guides/codex/#tool-search).

## Verify

```bash
shunt check    # -> config ok
shunt run
curl -sS http://127.0.0.1:3001/v1/models
curl -sS http://127.0.0.1:3001/v1/messages \
  -H 'anthropic-version: 2023-06-01' \
  -H 'content-type: application/json' \
  -d '{"model":"claude-gpt-5-4-via-openai","max_tokens":16,"messages":[{"role":"user","content":"Reply with OK."}]}'
```

Confirm the response's `x-gateway-upstream` header names `openai`, then
[point Claude Code at shunt](/guides/connect-claude-code/).

Source: https://shunt-docs.pages.dev/providers/openai/index.mdx
