Skip to content

Documentation

How to use it

ClaudeOpus speaks the Anthropic Messages API, byte for byte. Change one base URL and your SDK, your CLI and your editor carry on as if nothing happened.

The whole change
export ANTHROPIC_BASE_URL=https://api.claudeopus.pro
export ANTHROPIC_AUTH_TOKEN=sk-ant-co-YOUR_KEY

What this is

An Anthropic-compatible proxy. Same /v1/messages protocol, same headers, same SSE event stream. Point any Anthropic client at it and pass a ClaudeOpus key where you'd pass an Anthropic one.

One detail worth reading twice: routes are mounted at the root. Messages go to /v1/messages right on the base URL — there is no /api in front of it.

Base URL
https://api.claudeopus.pro
Max context
1Mtokens
Max output
128Ktokens
Models
15served
Usage window
5 hrolling

Keys start with sk-ant-co- and are issued by an administrator or a reseller. You can check any key's status, how much of its 5-hour window is used, and its recent requests on the key status page.

Quick start

The setup script asks for your key, writes it and the base URL into Claude Code's settings, and verifies the connection before it exits. Run it again to change the key. Older versions also registered a ClaudeOpus MCP server; tools now run on our side, so a re-run removes that entry.

macOS / Linux
curl -fsSL https://claudeopus.pro/setup.sh | bash
Windows (PowerShell)
irm https://claudeopus.pro/setup.ps1 | iex

An interactive wizard on npm asks for your key and which editors to set up — Claude Code, the VS Code Claude extension, Cursor, Windsurf, Cline or Roo Code — rather than assuming Claude Code. Run it again and pick its Remove option to take the config back out.

Any platform
npx claudeopus

Prefer to do it yourself? The settings it writes are in Editors & CLIs, and the rest of this page covers the shape of every request and response.

Authentication

Send the key as x-api-key, the way the Anthropic SDK does. Authorization: Bearer works identically — whichever your client already sends.

Request
curl https://api.claudeopus.pro/v1/messages \
  -H "x-api-key: sk-ant-co-YOUR_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-5",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello, world."}]
  }'

Both SDKs also read ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY (or ANTHROPIC_AUTH_TOKEN) from the environment, so the two export lines at the top of this page are all they need.

A missing or bad key doesn't throw a 401 here — see Limits & errors for why.

Models

The four current models, one per family:

Fable

Claude Fable 5.1

Flagship
claude-fable-5-1

The most capable model here — demanding reasoning and long-horizon agentic work. Knowledge to June 2026, the freshest here.

Context
1,000,000
Max output
128,000

Opus

Claude Opus 5

Deep reasoning
claude-opus-5

Deep reasoning across the same million-token window, a step behind Fable.

Context
1,000,000
Max output
128,000

Sonnet

Claude Sonnet 5

Balanced
claude-sonnet-5

Balanced — the same million-token window, lighter on the clock.

Context
1,000,000
Max output
128,000

Haiku

Claude Haiku 4.5

Fast
claude-haiku-4-5-20251001

Low latency, high throughput.

Context
200,000
Max output
64,000

Aliases

Four aliases resolve to the newest model in each family, so you never have to chase a date-stamped ID:

Model aliases and the model each one resolves to
AliasResolves to
fableclaude-fable-5-1
opusclaude-opus-5
sonnetclaude-sonnet-5
haikuclaude-haiku-4-5-20251001

Display names work too — Opus 4.8 or Claude Opus 4.8 reaches claude-opus-4-8. Claude Code's [1m] suffix is accepted as-is: send claude-opus-5[1m] and the proxy strips it before routing.

Every model served

Earlier releases stay routable for pinned clients. All 15, as GET /v1/models describes them:

  • Claude Fable 5.1claude-fable-5-1
    Family
    Fable
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Fable 5claude-fable-5
    Family
    Fable
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Opus 5.5claude-opus-5-5
    Family
    Opus
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Opus 5claude-opus-5
    Family
    Opus
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Sonnet 5claude-sonnet-5
    Family
    Sonnet
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Opus 4.8claude-opus-4-8
    Family
    Opus
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Opus 4.7claude-opus-4-7
    Family
    Opus
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Opus 4.6claude-opus-4-6
    Family
    Opus
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Sonnet 4.6claude-sonnet-4-6
    Family
    Sonnet
    Context
    1,000,000
    Max output
    128,000
    [1m] twin
    Yes
    Released
  • Claude Opus 4.5claude-opus-4-5
    Family
    Opus
    Context
    200,000
    Max output
    16,000
    [1m] twin
    No
    Released
  • Claude Sonnet 4.5claude-sonnet-4-5-20250929
    Family
    Sonnet
    Context
    200,000
    Max output
    16,000
    [1m] twin
    No
    Released
  • Claude Haiku 4.5claude-haiku-4-5-20251001
    Family
    Haiku
    Context
    200,000
    Max output
    64,000
    [1m] twin
    No
    Released
  • Claude Opus 4.1claude-opus-4-1-20250805
    Family
    Opus
    Context
    200,000
    Max output
    16,000
    [1m] twin
    No
    Released
  • Claude Opus 4claude-opus-4-20250514
    Family
    Opus
    Context
    200,000
    Max output
    16,000
    [1m] twin
    No
    Released
  • Claude Sonnet 4claude-sonnet-4-20250514
    Family
    Sonnet
    Context
    200,000
    Max output
    16,000
    [1m] twin
    No
    Released

Context and max output are in tokens. — means /v1/models declares no max_output_tokens for that model.

Listing them

GET /v1/models returns 24 entries: the 15 models, each with id, display_name, created_at, context_window and, where declared, max_output_tokens — plus a [1m] twin of each of the 9 1M-context models. The twin is there for Claude Code, which sizes its own context budget from a built-in table rather than from context_window; the proxy strips the suffix, so both forms reach the same model with the same window.

GET /v1/models/{id} returns one, or a 404. Neither needs a key.

List the models
curl https://api.claudeopus.pro/v1/models

Messages API

The same shape as Anthropic's /v1/messages. If it works against the Anthropic SDK, it works here unchanged — tools, system prompts, multi-turn, and all.

Response
{
  "id": "msg_abc123",
  "type": "message",
  "role": "assistant",
  "content": [{"type": "text", "text": "Hello, world."}],
  "model": "claude-opus-5",
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 12,
    "output_tokens": 6,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 0
  }
}

Omit max_tokens and it defaults to 4096. Omit model and you get claude-sonnet-4-6. The usage block is the real token count, and it's what your 5-hour window is charged from — see Limits & errors.

Very long conversations are compacted automatically rather than rejected: the proxy trims oldest-first until the request fits, and only gives up once there's nothing left to cut.

Streaming

Set "stream": true and read the response as SSE. Events are passed straight through as they're generated — no buffering, no aggregation, no added latency.

Event stream
data: {"type":"message_start","message":{...}}
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}}
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":", world."}}
data: {"type":"content_block_stop","index":0}
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"}}
data: {"type":"message_stop"}

Streams are held open for as long as the model keeps talking, and usage is metered from the final message_delta. Disconnect early and generation is cancelled with you.

Prompt caching

Mark any large, stable prefix — a system prompt, a tool schema, a document — with cache_control and it's cached.

A cached system prompt
{
  "model": "claude-opus-5",
  "max_tokens": 1024,
  "system": [
    {
      "type": "text",
      "text": "<your long, stable instructions>",
      "cache_control": {"type": "ephemeral"}
    }
  ],
  "messages": [{"role": "user", "content": "Hello, world."}]
}

Cached tokens are free against your 5-hour window. Only non-cached input plus output counts toward it — cache reads and cache writes are both left out. A long cached system prompt effectively costs you nothing to keep sending.

Editors & CLIs

Every client needs the same two facts: a base URL and a key. For Claude Code, the setup script merges the env block below into ~/.claude/settings.json, marks first-run onboarding as done ("hasCompletedOnboarding": true) and leaves your other settings alone. It installs nothing. If you would rather not edit these files by hand, npx claudeopus writes them for Claude Code, Cline and Roo Code; for Cursor and Windsurf it prints the base URL to paste into their own settings.

Claude Code

In ~/.claude/settings.json:

~/.claude/settings.json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.claudeopus.pro",
    "ANTHROPIC_AUTH_TOKEN": "sk-ant-co-YOUR_KEY",
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
    "CLAUDE_CODE_AUTO_MODE_SERVER": "0"
  }
}

Restart Claude Code afterwards. Add ANTHROPIC_MODEL if you want to pin a model; leave it out and Claude Code picks per task.

Cursor

Settings → Models → Add custom OpenAI-compatible model. Cursor speaks OpenAI, so point it at the compatibility layer:

Base URL
https://api.claudeopus.pro/v1
API key
Your ClaudeOpus key
Model
claude-opus-5

Windsurf, Cline, Roo Code

All three accept an Anthropic-compatible base URL in their provider settings. Use https://api.claudeopus.pro and your key — no other changes.

OpenAI-compatible

For clients that only speak OpenAI, there's /v1/chat/completions. Requests are translated into Anthropic format on the way in and back again on the way out — streaming included, tool calls and all.

Chat completions
curl https://api.claudeopus.pro/v1/chat/completions \
  -H "Authorization: Bearer sk-ant-co-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": true
  }'

This route returns real OpenAI-shaped errors with real status codes, not the 200-with-a-message behaviour described in Limits & errors.

Server-side tools

Web search and image analysis run on our side — nothing to install, no MCP server, no client plugin. Images you put in a message are handled server-side before the model answers.

Both are also callable directly, with the same key:

Web search
curl https://api.claudeopus.pro/tools/web_search \
  -H "x-api-key: sk-ant-co-YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{"query": "anthropic messages api changelog"}'
Image analysis
curl https://api.claudeopus.pro/tools/understand_image \
  -H "x-api-key: sk-ant-co-YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{
    "prompt": "What does this diagram show?",
    "image_url": "https://example.com/diagram.png"
  }'

image_url takes a URL or a base64 data URI. Payloads over 18 MB are refused with a 413.

Limits & errors

Each key carries two limits: a per-minute request ceiling and a rolling 5-hour usage window. The window opens with your first charged request — not at a fixed hour — and resets five hours later.

The 5-hour window

Usage is always shown as a percentage of the window, never as a token count. It reads 0% while the window is idle and climbs as you use it; from 90% the readout flags it Near limit. It only reaches 100% once the window is actually spent — from then until the reset, requests get the Usage limit reached reply below.

Non-cached input and output count toward the window; cache reads and cache writes don't (see Prompt caching). Some keys are unlimited: they have no 5-hour cap and read “Unlimited” instead of a percentage.

Usage per model family

The window is one budget shared by every model on the key. The key status page and your dashboard split the percentage used by model family — Fable, Opus, Sonnet and Haiku, always in that order — so you can see what is drawing it down. The four shares add up to the total.

5-hour window · example

72.4%used

  • Fable18.6%
  • Opus31.2%
  • Sonnet19.1%
  • Haiku3.5%
Illustrative numbers. The key status page and your dashboard show your key's own window, the same way.

A request counts toward the family of the model you asked for: claude-fable-5-1 and claude-fable-5 under Fable, every Opus model under Opus, and so on. A model name outside the four families counts under Opus. Families can be weighted differently, so the same request doesn't always take the same share of the window on every model.

Failures you can read

Anything wrong with your key comes back as a normal 200 with an assistant message explaining it — in the model you asked for, and charged nothing. It looks like a reply, so clients that handle error codes badly (most editors) show you the reason instead of a red box or a crash. The checks run in this order:

  • Unknown key

    “Invalid API key. Please check that your API key is correct and try again.”
  • Disabled key

    “Your API key has been disabled. Please contact your administrator to re-enable it.”

    An admin switched it off.

  • Expired key

    “Your API key expired on 9/30/2026. Please contact your administrator to renew it.”

    Past its expiry date. The message names the date.

  • Rate limited

    “Rate limit exceeded — You've exceeded 60 requests per minute. Please wait 42 seconds and try again.”

    Over the key’s per-minute ceiling. Also sets retry-after, x-ratelimit-limit and x-ratelimit-remaining.

  • Window used up

    “Usage limit reached — you've used 100% of your 5-hour window. It resets in 2h 14m.”

    The message says when the window resets.

Numbers, dates and times in the replies above are examples.

Failures you can catch

Everything else uses Anthropic's error shape — an error object with a type and a message — and a real status code:

  • 400invalid_request_error

    Malformed body — or a conversation that still doesn’t fit after auto-compaction has cut everything it can.

  • 401authentication_error

    Authentication couldn’t be completed on our side. Not your key — a bad key gets a readable reply instead. Retry shortly.

  • 413invalid_request_error

    Request body over 50 MB (an image sent to /tools/understand_image: over 18 MB).

  • 429rate_limit_error

    The global per-IP ceiling — 200 requests a minute, across every key. Honour the Retry-After header.

  • 503overloaded_error

    Scheduled maintenance. Honour the Retry-After header and come back.

  • 529overloaded_error

    Still at capacity after the automatic retries (it can also arrive as a 429). Back off and try again.

Capacity hiccups aren't your problem: rate-limited and overloaded responses are retried automatically before anything reaches you. You only see a 429 or 529 if they persist.

Questions? Check the status page first, then reach your admin.