---
name: ohmygpt
description: Integrate the OhMyGPT API (one key for 250+ models over OpenAI, Anthropic and Gemini compatible endpoints) into code, or point a coding tool such as Claude Code, Codex, opencode or Cursor at it. Use when the user mentions OhMyGPT, api.ohmygpt.com or OHMYGPT_API_KEY.
---

# OhMyGPT API

Base URL `https://api.ohmygpt.com`. Read the key from the `OHMYGPT_API_KEY` environment variable; never hard-code it, commit it, or ship it to a browser or mobile client. Users create keys at https://www.ohmygpt.com/keys.

## Look model IDs up, never guess them

Model IDs change every week and your training data is out of date. Fetch the live list (no key needed):

```bash
curl -s https://api.ohmygpt.com/v1/models | jq -r '.data[] | select(.id | test("claude")) | [.id, ([.protocols[].path] | join(" ")), (.lifecycle.sunset_at // "")] | @tsv'
```

Each entry's `protocols[].path` lists the endpoints that model accepts; `lifecycle.sunset_at`, when set, is the day it stops working. Prices, providers and an example request for one model are at `https://www.ohmygpt.com/models/<model id>.md`, and every model with its prices is at https://www.ohmygpt.com/models.md. Use the ID exactly as listed. A `provider:` prefix naming one of the entry's `providers[].provider` pins that provider; models with `managed_routing: true` choose their provider themselves.

## Endpoints

Keep the project's existing SDK; change only the base URL and the key.

| Protocol | Endpoint | SDK base URL | Auth header |
|---|---|---|---|
| OpenAI Chat Completions | `POST /v1/chat/completions` | `https://api.ohmygpt.com/v1` | `Authorization: Bearer` |
| OpenAI Responses | `POST /v1/responses` | `https://api.ohmygpt.com/v1` | `Authorization: Bearer` |
| Anthropic Messages | `POST /v1/messages` | `https://api.ohmygpt.com` (no `/v1`) | `x-api-key` |
| Gemini | `POST /v1/models/{model}:generateContent` | `https://api.ohmygpt.com`, `api_version="v1"` | `x-goog-api-key` |

The Anthropic SDK and Claude Code append `/v1/messages` themselves, so a base URL ending in `/v1` produces `/v1/v1/messages` and a 404.

## Coding tools

Claude Code:
```bash
export ANTHROPIC_BASE_URL="https://api.ohmygpt.com"
export ANTHROPIC_AUTH_TOKEN="$OHMYGPT_API_KEY"
export ANTHROPIC_MODEL="<model id>"
```

Codex (`~/.codex/config.toml`; Codex only speaks Responses):
```toml
model = "<model id>"
model_provider = "ohmygpt"

[model_providers.ohmygpt]
name = "OhMyGPT"
base_url = "https://api.ohmygpt.com/v1"
env_key = "OHMYGPT_API_KEY"
wire_api = "responses"
```

opencode (`opencode.json`):
```json
{
  "provider": {
    "ohmygpt": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "OhMyGPT",
      "options": { "baseURL": "https://api.ohmygpt.com/v1", "apiKey": "{env:OHMYGPT_API_KEY}" },
      "models": { "<model id>": {} }
    }
  }
}
```

Cursor: Settings → Models → OpenAI API Key = the key, Override OpenAI Base URL = `https://api.ohmygpt.com/v1`.

## Test for free

`ohmygpt/mock` costs nothing and answers deterministically on every endpoint above, streaming or not. If the request declares tools it calls the first one (or the one `tool_choice` names), with every required argument set to its zero value; after a tool result it replies with text. Run the integration against it first, then switch to the real model. It needs an account that has topped up at least once.

```bash
curl https://api.ohmygpt.com/v1/chat/completions \
  -H "Authorization: Bearer $OHMYGPT_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "ohmygpt/mock", "messages": [{"role": "user", "content": "ping"}]}'
```

## Routing

On Chat Completions and Responses a top-level `provider` object steers which provider serves the model: `only`, `ignore`, `order` (lists of provider slugs) and `sort` (`price`, `latency`, `throughput`). OpenAI SDKs need it in `extra_body` (Python) or as an extra property (TypeScript). OpenRouter model suffixes such as `:floor` or `:nitro` and `models[]` fallback lists are not supported.

## Cost

Every response carries `X-Request-ID`. Non-streaming responses also carry `X-Cost-Credits`, the charge in Credits (1 USD = 250,000 Credits); streams send it as an SSE comment line `: x-cost-credits: N` just before the final frame. Usage history is at https://www.ohmygpt.com/usage. Optional request headers name your app: `HTTP-Referer` (its URL), `X-OhMyGPT-Title` and `X-OhMyGPT-Categories`. Apps already sending OpenRouter's `X-OpenRouter-Title` / `X-Title` and `X-OpenRouter-Categories` need no change.

## Errors

Branch on the HTTP status and show the message; it says what to do next.

| Status | Meaning | What to do |
|---|---|---|
| 400 | Bad request or a parameter this model does not accept | Fix or remove the parameter the message names; do not retry unchanged |
| 401 | Missing or invalid key | Ask the user for a valid key |
| 402 | Out of balance, or the key's spending cap is reached | Ask the user to top up at https://www.ohmygpt.com/billing |
| 403 | The key may not use this model | Ask the user to allow the model on the key |
| 404 | Unknown or retired model ID | Look the ID up again; do not retry |
| 429 | Rate limited | Wait for the `Retry-After` header, then retry |
| 502, 503, 504 | The model is temporarily unavailable | Retry with backoff, or switch model |

## Done means

The key comes from `OHMYGPT_API_KEY`, the model ID was taken from `/v1/models` and is listed for the endpoint used, and the integration ran once against `ohmygpt/mock` and once against the real model, printing the output both times.
