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.
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:
| Setting | Before, on OpenAI | After, Claude on 5abeer |
|---|---|---|
| Base URL | https://api.openai.com/v1 | https://api.5abeer.ai/v1 |
| Key | An OpenAI API key | A 5abeer key for Claude models |
| Model | A GPT model id | A 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:
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:
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:
Claude Sonnet 5.5DefaultInput$0.60Output$3Context1M
Claude Opus 5.5Input$1.20Output$6Context1M
Claude Fable 5.1Input$3Output$15Context—
Claude Fable 5Input$3Output$15Context1M
Claude Opus 4.6Input$1.50Output$7.50Context1M
Claude Opus 4.7Input$1.50Output$7.50Context1M
Official price from the provider's page, checked October 19, 2026.
All models and pricesStart 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:
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_tokensis required, and the instructions go in the top-levelsystemfield.- Thinking is on by default on Claude 5 models. Anthropic counts thinking tokens toward
max_tokensand bills them as output, so leave room: these samples use 4096. - The reply is a list of blocks, and a
thinkingblock can come before the text. Read thetextblocks, 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 Completions | In Messages |
|---|---|
Base URL https://api.5abeer.ai/v1 | Base URL https://api.5abeer.ai, with no /v1 |
The Authorization: Bearer header | The x-api-key and anthropic-version: 2023-06-01 headers; Bearer works too |
A message with the system role | The top-level system field |
max_tokens is optional | max_tokens is required |
choices[0].message.content | The text blocks in content |
stop | stop_sequences |
parameters in a function | input_schema in a tool |
A message with the tool role | A tool_result block in a user message |
reasoning_effort | effort in output_config |
response_format | A tool with a schema |
prompt_tokens and completion_tokens | input_tokens and output_tokens |
Chunks with a delta | Named 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.
| Option | With Claude models on 5abeer |
|---|---|
messages with the system, user, assistant and tool roles | Supported, images included |
max_completion_tokens or max_tokens | Supported |
stream and stream_options | Supported |
tools and tool_choice | Supported; keep tool_choice at auto (see below) |
reasoning_effort | Supported |
temperature and top_p | Passed to the model (see below) |
response_format | Ignored: use a tool with a schema |
stop | Ignored: use stop_sequences in Messages |
parallel_tool_calls, n, seed, the penalties, logprobs, logit_bias and user | Ignored |
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:
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:
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 see | Likely cause | Fix |
|---|---|---|
403 with MODEL_PLATFORM_NOT_ALLOWED | The key is for GPT or Gemini models | Create a key for Claude models, as in One key per provider |
401 with INVALID_API_KEY | The code still sends an OpenAI key | Put your 5abeer key in the variable your code reads |
404 Not Found | /v1 added to the Anthropic SDK's base URL | Use https://api.5abeer.ai |
400 on a request that worked with GPT | A non-default temperature or top_p, or a forced tool call | Leave sampling settings out; set tool_choice to auto |
stop_reason is max_tokens, with little or no text | max_tokens ran out, often on thinking | Raise max_tokens |
AttributeError on choices | Chat Completions code reads a Messages reply | Read 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."}]}'{
"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 endpoint | 5abeer | |
|---|---|---|
| Base URL | https://api.anthropic.com/v1/ | https://api.5abeer.ai/v1 |
| Key | An Anthropic API key | A 5abeer key for Claude models |
| Model id | Anthropic's ids, with a hyphen in the version | Our catalog's ids, such as claude-sonnet-5.5 |
response_format | Only json_schema with strict: true | Ignored: use a tool with a schema |
reasoning_effort | Ignored | Supported |
stop | Works for non-whitespace text | Ignored: use stop_sequences in Messages |
| Prompt caching | Not in this format | Not 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:
6M input tokens and 1.5M output tokens
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:
- Anthropic: OpenAI SDK compatibility
- Anthropic: Using the Messages API
- Anthropic: Define tools
- Anthropic: Thinking
- Anthropic: anthropic-sdk-python library
- OpenAI: openai-python library and openai-node library
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.
Related guides
- What is a base URL? For the OpenAI, Anthropic, Gemini SDKsWhat a base URL is, the official one for the OpenAI, Anthropic and Gemini SDKs, how to set it in code or Claude Code, and how to fix 404 and 401 errors.
- Which Claude model to use: Sonnet, Opus or Fable?Sonnet for everyday work, Opus for long agentic coding, Fable for the hardest jobs. How the three Claude models compare on speed, cost and fit.
Ready to start?
Pick a plan that runs the official apps, or create an API key to use from your own code.