---
title: "OpenAI Codex"
description: "Web search through your existing Pi, OMP, Codex or OpenCode login."
canonical_url: "https://web.agntn.dev/providers/openai-codex"
---
# OpenAI Codex

> Web search through your existing Pi, OMP, Codex or OpenCode login.

<provider-facts provider="openai-codex">



</provider-facts>

This is the search available through a Codex login, not the separately billed OpenAI API. The adapter calls the ChatGPT backend with the hosted `web_search` tool. A model answer without a completed search is an error, not a search result.

## Credentials

Log in with Pi, OMP, Codex or OpenCode, then search. No manual token export:

```bash
web search "Node.js release notes" --provider openai-codex --json
```

Pi tools resolve credentials through the host's model registry. Pi owns expiry-based refresh, but its extension API can't force renewal of a revoked token. OMP's auth broker supports forced refresh and keeps the calling session's account affinity. Listing providers doesn't resolve a token, and concurrent calls don't share accounts.

Outside a host, automatic discovery reads saved logins in this order:

<table>
<thead>
  <tr>
    <th>
      Client
    </th>
    
    <th>
      Default store
    </th>
    
    <th>
      Overrides
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Codex
    </td>
    
    <td>
      <code>
        ~/.codex/auth.json
      </code>
    </td>
    
    <td>
      <code>
        CODEX_HOME
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Pi
    </td>
    
    <td>
      <code>
        ~/.pi/agent/auth.json
      </code>
    </td>
    
    <td>
      <code>
        PI_CODING_AGENT_DIR
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      OMP
    </td>
    
    <td>
      <code>
        ~/.omp/agent/agent.db
      </code>
      
      , then legacy <code>
        auth.json
      </code>
    </td>
    
    <td>
      <code>
        PI_CODING_AGENT_DIR
      </code>
      
      , <code>
        OMP_PROFILE
      </code>
      
       or legacy <code>
        PI_PROFILE
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      OpenCode
    </td>
    
    <td>
      <code>
        ~/.local/share/opencode/auth.json
      </code>
    </td>
    
    <td>
      <code>
        XDG_DATA_HOME
      </code>
    </td>
  </tr>
</tbody>
</table>

Only OAuth access tokens are used. API keys, disabled OMP accounts and expired tokens are skipped. Discovery never writes login files, creates a database or rotates saved refresh tokens. Standalone callers need a usable saved access token; if it expired, open the owning client and let it refresh. Codex logins held only in an OS keyring are not read. OMP SQLite requires Node's optional `node:sqlite` builtin; the native OMP host resolver does not.

Choose a store with `codex.authSource` or `OPENAI_CODEX_AUTH_SOURCE`: `auto` (default), `codex`, `pi`, `omp`, `opencode`, or `none` to disable local and host discovery. A named source bypasses other stores and the invoking host.

Explicit `codex.credentials` wins over environment overrides, which win over automatic discovery. `OPENAI_CODEX_ACCESS_TOKEN` can still supply a bearer; `OPENAI_CODEX_ACCOUNT_ID` is optional when its JWT contains `chatgpt_account_id`. A partial environment override does not silently switch to a different account. `OPENAI_API_KEY` does not configure this provider.

In application code, explicit credentials remain an optional override:

```ts
import { createSearchProvider } from "@agntn/web";

const search = createSearchProvider("openai-codex", {
  codex: {
    credentials: {
      accessToken: "your-oauth-access-token",
      accountId: "your-chatgpt-account-id",
    },
    model: "gpt-5.5",
  },
});
const results = await search.search("Node.js release notes", { maxResults: 5 });
```

For refresh, pass a callback instead of the fixed pair. Your login service owns token storage and concurrent refresh coordination:

```ts
import { createSearchProvider, type CodexCredentialProvider } from "@agntn/web";

export function createCodexSearch(credentials: CodexCredentialProvider) {
  return createSearchProvider("openai-codex", { codex: { credentials } });
}
```

The callback receives `{ refresh, signal }` and returns `{ accessToken, accountId? }`, directly or through a promise. The account ID is derived from the access token when omitted. It runs before each search with `refresh: false`. After an authentication rejection it runs once more with `refresh: true`. The adapter retries once only if the bearer or account changed. If the host returns the rejected pair unchanged, search stops and asks for a fresh login. Check expiry even on the first call. The library never handles a refresh token itself.

Explicit credentials and model take precedence over the environment. Instance configuration is local to that instance, it does not enroll a callback in the global `auto` or `all` flows.

## Endpoint and results

`POST https://chatgpt.com/backend-api/codex/responses`, with Bearer auth, `chatgpt-account-id`, `store: false`, streaming enabled and `tool_choice: { type: "web_search" }`.

Results come only from structured search sources and `url_citation` annotations. They have `url`, `title` and an empty `snippet`. Generated prose is not a page excerpt. URLs that appear only in prose never become results.

```ts
import { searchProviderDetailed } from "@agntn/web";

const response = await searchProviderDetailed("openai-codex", "Node.js release notes", {
  maxResults: 5,
  summary: true,
});
console.log(response.results);
console.log(response.metadata?.answer);
```

The detailed helper uses the same automatic login discovery and explicit environment overrides. `summary: true` includes the generated answer in `metadata.answer`; it stays absent otherwise. Metadata also carries the returned model, request ID and token usage when available.

## Limits and traps

- This is an experimental adapter for the Codex backend, not a stable public search API. Model access and subscription limits still apply.
- The default model is `gpt-5.5`. Override it with `codex.model` or `OPENAI_CODEX_MODEL` if your account needs another model that supports hosted web search. There is no hidden model fallback.
- `maxResults` caps collected sources locally, not upstream search work. Default 10, maximum 100. It does not promise that many sources.
- No paging, domain/date/category filters, highlights, full page text, reverse image search or URL reading. Detailed helpers report ignored filters.
- `auto` tries Codex after the existing API providers, before custom providers and SearXNG. `all` includes it when a usable saved login, a native host resolver or explicit environment credentials are available. Discovery does not check subscription status or refresh tokens.
- A search has a 90-second ceiling, including credential resolution and its one possible refresh. Caller cancellation and earlier deadlines still win. The transport rejects streams above 8 MiB and events above 1 MiB.
- The adapter does not retry metered requests after HTTP 429 or server errors. Automatic search may move to another configured provider under the library's normal fallback rules.
- OAuth credentials can only go to the fixed ChatGPT endpoint. Custom `baseURL` values and HTTP redirects are refused. Error messages omit upstream bodies and credential callback diagnostics.
- Do not put personal subscription credentials on a public explorer worker. Local configuration is enough to use the library and its tools.

Implementation: `src/providers/openai-codex.ts`. Protocol reference: the Codex search adapter in [oh-my-pi](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/web/search/providers/codex.ts).


## Sitemap

See the full [sitemap](https://web.agntn.dev/sitemap.md) for all pages.
