Skip to content

Migrate from the OpenAI API to Claude: what changes in code

Move OpenAI API code to Claude: keep the OpenAI SDK and change three settings, or switch to the Anthropic SDK. Field map, 400 errors to avoid, cost.

Updated November 3, 2026Markdown version

To move from OpenAI to Claude, you can keep the OpenAI SDK and change three settings: the base URL https://api.5abeer.ai/v1, a 5abeer key for Claude models, and a Claude model id such as claude-sonnet-5.5. For Claude's own settings, such as prompt caching, switch to the Anthropic SDK at https://api.5abeer.ai. Both routes take the same key.

What changes when you move from OpenAI to Claude?#

5abeer is OpenAI-compatible: change the base URL and keep your code. Three settings change:

SettingBefore, on OpenAIAfter, Claude on 5abeer
Base URLhttps://api.openai.com/v1https://api.5abeer.ai/v1
KeyAn OpenAI API keyA 5abeer key for Claude models
ModelA GPT model idA Claude model id, such as claude-sonnet-5.5

Then pick a route: keep the OpenAI SDK, the smallest change, or move to the Anthropic SDK, which reaches every Claude setting. How an SDK builds each address is in What is a base URL.

Route 1: keep the OpenAI SDK#

Put your key in the KHABEER_API_KEY environment variable, then change the client and the model id:

Python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.5abeer.ai/v1",
    api_key=os.environ["KHABEER_API_KEY"],
)

response = client.chat.completions.create(
    model="claude-sonnet-5.5",
    messages=[
        {"role": "system", "content": "Answer in two sentences."},
        {"role": "user", "content": "What is a context window?"},
    ],
)

print(response.choices[0].message.content)

In the Node.js library the option is called baseURL:

JavaScript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.5abeer.ai/v1",
  apiKey: process.env.KHABEER_API_KEY,
});

const response = await client.chat.completions.create({
  model: "claude-sonnet-5.5",
  messages: [{ role: "user", content: "What is a context window?" }],
});

console.log(response.choices[0].message.content);

Both libraries also read OPENAI_BASE_URL and OPENAI_API_KEY when you don't pass them in code, so a project can switch by setting two variables and changing the model id. Code that calls client.responses.create keeps working too: Claude models are served on Responses as well.

Which Claude model should I pick?#

The Claude models you can call now:

per 1M tokens

Official price from the provider's page, checked October 19, 2026.

All models and prices

Start with claude-sonnet-5.5, the default on 5abeer, and try claude-opus-5.5 or claude-fable-5.1 on your hardest prompts; Which Claude model to use compares them. Copy each id as our catalog writes it, with a dot in the version, even where Anthropic's docs use a hyphen. client.models.list() returns the models your key can use, as in List models.

Route 2: move to the Anthropic SDK#

Claude's own settings, such as cache_control, thinking settings and output_config, live in Anthropic's format. 5abeer is compatible with the Anthropic Messages API, so the official SDK works with it. Install it with pip install anthropic:

Python
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.5abeer.ai",
    api_key=os.environ["KHABEER_API_KEY"],
)

message = client.messages.create(
    model="claude-sonnet-5.5",
    max_tokens=4096,
    system="Answer in two sentences.",
    messages=[{"role": "user", "content": "What is a context window?"}],
)

print("".join(block.text for block in message.content if block.type == "text"))

Four things differ from the OpenAI code:

  • The base URL has no /v1. The Anthropic SDK adds the path itself.
  • max_tokens is required, and the instructions go in the top-level system field.
  • Thinking is on by default on Claude 5 models. Anthropic counts thinking tokens toward max_tokens and bills them as output, so leave room: these samples use 4096.
  • The reply is a list of blocks, and a thinking block can come before the text. Read the text blocks, not the first block.

The SDK also reads ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY from the environment, as in Base URLs.

How do Chat Completions and Messages differ?#

The same conversation sits in different fields. Moving to Messages means renaming these:

In Chat CompletionsIn Messages
Base URL https://api.5abeer.ai/v1Base URL https://api.5abeer.ai, with no /v1
The Authorization: Bearer headerThe x-api-key and anthropic-version: 2023-06-01 headers; Bearer works too
A message with the system roleThe top-level system field
max_tokens is optionalmax_tokens is required
choices[0].message.contentThe text blocks in content
stopstop_sequences
parameters in a functioninput_schema in a tool
A message with the tool roleA tool_result block in a user message
reasoning_efforteffort in output_config
response_formatA tool with a schema
prompt_tokens and completion_tokensinput_tokens and output_tokens
Chunks with a deltaNamed events such as content_block_delta

Each field is in the Messages reference, and the same tool in each format is in Tool calling.

Which OpenAI options work with Claude on 5abeer?#

From our Chat Completions reference. An ignored option causes no error; it just has no effect.

OptionWith Claude models on 5abeer
messages with the system, user, assistant and tool rolesSupported, images included
max_completion_tokens or max_tokensSupported
stream and stream_optionsSupported
tools and tool_choiceSupported; keep tool_choice at auto (see below)
reasoning_effortSupported
temperature and top_pPassed to the model (see below)
response_formatIgnored: use a tool with a schema
stopIgnored: use stop_sequences in Messages
parallel_tool_calls, n, seed, the penalties, logprobs, logit_bias and userIgnored

Anthropic's docs, checked on 2026-11-03, add two limits. On Claude 4.7 and later models, a non-default temperature or top_p returns a 400 error. On claude-opus-5.5, claude-sonnet-5.5 and claude-fable-5.1, so does a forced tool call through tool_choice. Leave the sampling settings out, keep tool_choice at auto, and name the tool you want in the prompt.

How do I get JSON from Claude?#

response_format has no effect with Claude models on our Chat Completions, so ask for JSON through a tool. With the Anthropic SDK, describe a tool whose input_schema holds the fields you want, and read them from the tool_use block:

Python
tools = [{
    "name": "save_city",
    "description": "Save facts about a city.",
    "input_schema": {
        "type": "object",
        "properties": {
            "city": {"type": "string"},
            "country": {"type": "string"},
            "population": {"type": "integer"},
        },
        "required": ["city", "country", "population"],
    },
}]

message = client.messages.create(
    model="claude-sonnet-5.5",
    max_tokens=4096,
    tools=tools,
    messages=[{"role": "user", "content": "Call save_city with the facts about Tokyo."}],
)

calls = [block for block in message.content if block.type == "tool_use"]
if calls:
    print(calls[0].input["city"], calls[0].input["population"])
else:
    print("No tool call, stop_reason:", message.stop_reason)

With tool_choice at auto, the model decides whether to call the tool, so keep the check for a missing tool_use block. How to send a tool's result back is in Tool calling.

Does prompt caching carry over?#

Not on its own. With Claude models, you mark what to cache by adding cache_control to a content block, and that field exists only in Messages. If your prompts repeat long instructions or documents, that alone is a reason to take route 2; see Prompt caching.

Does streaming work?#

Yes, on both routes. With the OpenAI SDK, stream=True works as before. With the Anthropic SDK, the messages.stream helper yields the text as it is written:

Python
with client.messages.stream(
    model="claude-sonnet-5.5",
    max_tokens=4096,
    messages=[{"role": "user", "content": "Write a short poem about the sea."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

The events behind it are in Streaming.

Common errors#

What you seeLikely causeFix
403 with MODEL_PLATFORM_NOT_ALLOWEDThe key is for GPT or Gemini modelsCreate a key for Claude models, as in One key per provider
401 with INVALID_API_KEYThe code still sends an OpenAI keyPut your 5abeer key in the variable your code reads
404 Not Found/v1 added to the Anthropic SDK's base URLUse https://api.5abeer.ai
400 on a request that worked with GPTA non-default temperature or top_p, or a forced tool callLeave sampling settings out; set tool_choice to auto
stop_reason is max_tokens, with little or no textmax_tokens ran out, often on thinkingRaise max_tokens
AttributeError on choicesChat Completions code reads a Messages replyRead the text blocks in content

Every code is in Errors and fixes and Limits.

Test it with one request#

Before you change a large project, send one request with your Claude key. A reply means the base URL, the key and the model id are right:

curl --request POST "https://api.5abeer.ai/v1/messages" \
  --header "x-api-key: $KHABEER_API_KEY" \
  --header "Content-Type: application/json" \
  --header "anthropic-version: 2023-06-01" \
  --data '{"model":"claude-sonnet-5.5","max_tokens":512,"messages":[{"role":"user","content":"Write a product idea in one sentence."}]}'
Response
{
  "id": "msg_01Xh7",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-5.5",
  "content": [
    {
      "type": "text",
      "text": "Hello! How can I help you today?"
    }
  ],
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 21,
    "output_tokens": 12
  }
}

The key is read from KHABEER_API_KEY, so it never appears in your code.

Anthropic's OpenAI endpoint or 5abeer's?#

Anthropic runs its own OpenAI-compatible endpoint. Checked on 2026-11-03 in Anthropic's docs and ours:

Anthropic's OpenAI endpoint5abeer
Base URLhttps://api.anthropic.com/v1/https://api.5abeer.ai/v1
KeyAn Anthropic API keyA 5abeer key for Claude models
Model idAnthropic's ids, with a hyphen in the versionOur catalog's ids, such as claude-sonnet-5.5
response_formatOnly json_schema with strict: trueIgnored: use a tool with a schema
reasoning_effortIgnoredSupported
stopWorks for non-whitespace textIgnored: use stop_sequences in Messages
Prompt cachingNot in this formatNot in this format; use cache_control in Messages

Anthropic calls its layer "primarily intended to test and compare model capabilities" and points to its native API for the full feature set. The same holds here: the OpenAI SDK is the quick way in, and Messages is where Claude's own settings live.

What does the move cost?#

A 5abeer API key pays per token from your balance, and every model priced per token costs less than its official price. As an example, 3,000 requests to claude-sonnet-5.5, each with about 2,000 input tokens and 500 output tokens, thinking included:

Example: what Claude Sonnet 5.5 costs

6M input tokens and 1.5M output tokens

Our price$8.1070% below the official price
Official price$27.00

Official price from the provider's page, checked October 19, 2026.

Live prices are on Claude API, and What is a token shows how a request turns into tokens. Each key can have a spend limit, an expiry date and an IP allow-list, as in Control every key.

Plans are for the supported apps; to use the models from your own code, create an API key. For Claude in the terminal rather than in your code, see Claude Code.

FAQ#

Can I keep my OpenAI code and call Claude?#

Yes. Point the OpenAI SDK at https://api.5abeer.ai/v1, use a key for Claude models and pass a Claude model id. Chat Completions and Responses both work.

When is the Anthropic SDK worth the rewrite?#

When you need cache_control, thinking settings or output_config. For plain chat and tool calls, the three settings are enough, and one code path can still call several providers.

Why does Claude return 400 for a request that worked on GPT?#

The usual cause is a sampling setting or a forced tool call. Anthropic's newest models reject a non-default temperature or top_p, and a tool_choice that forces a tool. Remove them and try again.

Do I need a new key for Claude?#

Yes. A 5abeer key works with one provider's models, so a key for GPT models can't call Claude. Create one for Claude models; all your keys draw on the same balance.

Should I rewrite my prompts?#

Anthropic suggests reviewing them: a prompt tuned closely for GPT models may need changes to get the best from Claude. Try your main prompts with the test request above before you move the rest.

Sources#

Checked on 2026-11-03:

Get started#

Create a key for Claude models, set it as KHABEER_API_KEY, run the test request above, then change the base URL and the model id across your project.