Skip to main content
Both clients work. Which endpoint you use is a question of which SDK you already have, not which models you can reach — they reach the same ones.

From an OpenAI client

Two lines:
/v1/chat/completions, /v1/completions, /v1/models and /v1/models/{model} all behave as the SDK expects. The model name is the one thing that must change — ours are not OpenAI’s. See Models and resource names.

From an Anthropic client

Give the SDK the origin, not the /v1 base — it appends /v1/messages itself:
x-api-key is accepted, so the SDK’s auth code is untouched. Claude Code works by changing base_url alone. Two differences from Anthropic’s own API:
  • No claude-* aliasing. Model names stay ours.
  • max_tokens is optional. Anthropic requires it; here, omitting it falls back to the model’s default rather than failing the call.

Ignored, or rejected

A parameter this API does not implement is ignored, not rejected — your existing request bodies will not start failing because they carry something extra. The exceptions are the handful that would change the answer if ignored. Those return INVALID_REQUEST:
The reasoning is the same one behind tool calling and structured outputs: silently ignoring a parameter that changes the shape of the answer produces a response that looks right and is not. An error you cannot miss is the better failure.
A few more are accepted and then deliberately dropped — top_k on /v1/messages is accepted so Anthropic clients do not break, and not passed to the model. The per-parameter truth is on each endpoint page in the API reference.

What to check after switching

Model names

The only change that is not configuration. Look them up rather than translating.

Retry logic

Branch on error.code, not on the status — three codes share 429 and one never succeeds.

Usage parsing

Streaming carries usage on the last event without include_usage.

Provider assumptions

Nothing in a response names who served it. Code that branched on that has nothing to branch on.