Skip to content

Architecture and migrationGuide

Use the OpenAI SDK with Claude and Gemini: what works, what doesn't

Anthropic and Google both let you call their models with the OpenAI SDK by changing the base URL. Both also say, in their own documentation, what that costs you: ignored fields, missing caching, and a beta or test-only label.

By INFRO Editorial

Published

6 min read

One amber channel on a dark ground splitting into three glass lanes of different widths, representing one SDK reaching three providers with different support

In short

Anthropic's compatibility endpoint is https://api.anthropic.com/v1/ and Google's is https://generativelanguage.googleapis.com/v1beta/openai/; both accept the OpenAI SDK with the provider's own key and model names. Anthropic says its layer is primarily for testing and comparing models: it ignores strict function schemas and response_format, does not support prompt caching, and hoists every system message to the top. Google labels its layer beta and passes Gemini-specific options through extra_body. For production, use the native SDKs or a gateway that translates to each provider's own API.

Key takeaways

  • Claude: base URL https://api.anthropic.com/v1/ with a Claude API key. Gemini: https://generativelanguage.googleapis.com/v1beta/openai/ with a Gemini API key.
  • Anthropic calls its layer primarily for testing and comparison, not a long-term production solution for most use cases.
  • On Claude, strict schemas and response_format are ignored and prompt caching is unsupported, so JSON and cost behave differently than on the native API.
  • Google labels its layer beta; Gemini-only options such as cached content and search grounding go through extra_body.
  • For production multi-provider code, use native SDKs behind your own interface, or a gateway that speaks each provider's own API.

Can you call Claude and Gemini with the OpenAI SDK? Yes. Point the client at Anthropic's https://api.anthropic.com/v1/ or Google's https://generativelanguage.googleapis.com/v1beta/openai/, use that provider's API key and model name, and Chat Completions calls work12. Both providers are also clear about the cost: Anthropic says its layer is "primarily intended to test and compare model capabilities" and is not considered a long-term or production-ready solution for most use cases1, and Google labels its support beta2.

This guide shows the setup for each, lists what each layer ignores, and gives a rule for when to use it and when not to.

Claude through the OpenAI SDK

claude_via_openai_sdk.py
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ANTHROPIC_API_KEY"],
    base_url="https://api.anthropic.com/v1/",
)

reply = client.chat.completions.create(
    model="claude-sonnet-5-5",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "Name three uses of a message queue."},
    ],
)
print(reply.choices[0].message.content)

A key with access to several workspaces must also send the anthropic-workspace-id header on every request1.

What Anthropic's layer ignores or changes

OpenAI featureThrough the compatibility layer
strict on function schemasIgnored: tool JSON is not guaranteed to match the schema
response_formatIgnored
Prompt cachingNot supported (supported in Anthropic's SDKs)
System and developer messagesHoisted and concatenated into one top-level system prompt
Audio input, file partsIgnored or stripped
reasoning_effort, seed, logprobs, user, metadataIgnored
nMust be 1
temperature, top_pNon-default values return 400 on Claude 4.7 and later
Forced tool_choiceReturns an error on Opus 5.5, Sonnet 5.5 and Fable 5.1; use auto
usage.prompt_tokens_detailsAlways empty
From Anthropic's OpenAI SDK compatibility page, 2026-10-20.

Three of these change production behaviour more than they look:

  • No guaranteed JSON. With strict and response_format ignored, code that relied on OpenAI's structured outputs gets well-formed JSON most of the time and not always. Anthropic points to Structured Outputs on its native API for guaranteed conformance1. Structured outputs across providers compares the options.
  • No prompt caching. A long system prompt or document context is billed at the full input rate on every request through this layer, where the native API could read it from cache for a small fraction of that rate.
  • Thinking is invisible. Thinking can be switched on with extra_body, but the OpenAI SDK does not return Claude's thinking1.

Most unsupported fields are silently ignored rather than rejected1, so a migration that "works" on the first test can still be running without the behaviour you assumed.

Gemini through the OpenAI SDK

gemini_via_openai_sdk.py
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["GEMINI_API_KEY"],
    base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
)

reply = client.chat.completions.create(
    model="gemini-3.8-flash",
    reasoning_effort="low",
    messages=[{"role": "user", "content": "Name three uses of a message queue."}],
)
print(reply.choices[0].message.content)

Google's layer is broader than Anthropic's. Its page covers chat completions with streaming, function calling, structured output and image and audio input; image generation; video generation through an asynchronous /videos endpoint; embeddings; batch jobs (with file upload and download through Google's own SDK); and model listing2.

Things to know:

  • Thinking maps to reasoning_effort. Values minimal, low, medium and high map to Gemini's thinking levels; none works only on 2.5 models, because reasoning cannot be turned off on 2.5 Pro or Gemini 3 models. Do not combine reasoning_effort with Gemini's own thinking settings2.
  • Gemini-only features go in extra_body. Thinking configuration with thought summaries, cached_content for context caching, Google Search grounding (Gemini 3 or newer) and video options are passed that way2.
  • Unlisted image parameters are silently ignored, and the whole layer is labelled beta2.

When the compatibility layers are the right tool

SituationUse the compatibility layer?
Comparing models on your own prompts this weekYes: fastest way to try them
A prototype or internal toolUsually yes
Production traffic that needs guaranteed JSONNo, on Claude
Long repeated prompts where caching mattersNo, on Claude; check extra_body on Gemini
Features that exist only natively (Claude's citations, PDFs, thinking blocks)No
A product that may move between providersNot on its own: see below

The layers solve "I want to try another model without rewriting my client". They do not solve "my product should run on several providers and fail over between them": each layer only reaches its own provider, each has different gaps, and a request that fails on one has nowhere to go.

A checklist for comparing models through these layers

Compatibility layers are a good way to run a quick comparison, provided the comparison is fair:

  • Same prompts, adapted once. Anthropic notes that a prompt tuned heavily for OpenAI's models may need reworking for Claude1. Give each model one honest prompt pass, then freeze the prompts.
  • Same output contract. If your code relies on JSON, validate every answer against the schema yourself during the test, because neither layer guarantees it the way OpenAI's strict mode does.
  • Same sampling settings where the model accepts them. Claude 4.7 and later reject non-default temperature and top_p1, so remove them for every model rather than comparing different settings.
  • Cost in dollars, not tokens. Tokenizers differ, and the usage details these layers return can be empty; compute cost from each provider's own token counts and rates.
  • Latency from your region. Measure time to first token and total time from where your application runs.
  • A reason to stop. Decide in advance what result would make you move a workload, so the comparison ends in a decision.

Once a model wins, move that workload to the provider's native API or to a gateway that calls it natively, and re-run the comparison there: caching and structured outputs can change both the cost and the reliability you measured.

Two production patterns for multiple providers

Native SDKs behind your own interface. Write a thin internal interface — complete(messages, schema, model_class) — and implement it with each provider's own SDK. You get every native feature, including caching and structured outputs, at the cost of maintaining the adapters. Multi-model API architecture covers the design.

A gateway that speaks each provider's own API. Your application speaks one dialect to the gateway; the gateway translates to each provider's native API and can fail over between them. Ask any gateway exactly which fields it translates and which it drops per provider, because that list is the real product.

Using INFRO

INFRO is a gateway on provider accounts you connect. Your application calls https://api.infro.io/v1 in OpenAI's shape and names a model such as anthropic/claude-sonnet-5.5 or google/gemini-3.8-flash; INFRO calls each provider's own API with your key, so you are not limited to the compatibility layers above. Parameters a model does not accept are adjusted per model and named in the X-INFRO-Params-Dropped header rather than dropped silently. For code that wants Anthropic's own API, INFRO also answers POST /v1/messages in Anthropic's shape, sent to Anthropic as written. Routes can fail over from one provider to another for the same request, and every request is recorded with an estimated provider cost.

Summary

Use Anthropic's and Google's OpenAI-compatible endpoints to try models quickly. Before shipping on them, read each provider's list of ignored fields against the features you depend on — JSON guarantees and prompt caching above all — and for production multi-provider code, either own the adapters or use a gateway that calls each provider natively.

Questions readers ask

Can I use the OpenAI Python SDK with Claude?
Yes. Set base_url to https://api.anthropic.com/v1/, use a Claude API key and a Claude model name. Anthropic describes the layer as primarily for testing and comparing models: strict function schemas and response_format are ignored, prompt caching is not supported, and audio input is stripped.
What is the Gemini OpenAI-compatible base URL?
https://generativelanguage.googleapis.com/v1beta/openai/, used with a Gemini API key. Google's page covers chat completions with streaming, function calling and structured output, images, video, embeddings, batch and model listing, and labels OpenAI library support as beta.
Does prompt caching work through Claude's OpenAI compatibility layer?
No. Anthropic's compatibility page says prompt caching is not supported there; it is supported in Anthropic's own SDKs. On long, repeated prompts that difference can change the cost of a request several times over.

From the team that builds it

Where this shows up in INFRO

INFRO is a control plane in front of the provider accounts you already hold. The capabilities below are the parts of it this article touches, each with the documentation that defines its behaviour.

INFRO accounts are self-serve. Provider usage is billed to you by your providers; INFRO charges a software subscription and takes 0% of model spend. See plans.

Sources

Numbered in order of first citation. Each was opened and checked against the claim on the date shown.

  1. 1.OpenAI SDK compatibility (opens in a new tab) — Anthropic. Accessed Oct 20, 2026.
  2. 2.OpenAI compatibility (opens in a new tab) — Google. Accessed Oct 20, 2026.

About this article

Every behaviour described comes from Anthropic's OpenAI SDK compatibility page and Google's OpenAI compatibility page, both opened on 2026-10-20. No compatibility layer was benchmarked. INFRO's behaviour is described from its documentation. Written by the team that builds INFRO.

Last checked against its sources on . The next review is due by . No separate named reviewer is recorded for this article.

How articles are written, sourced and corrected is set out in the editorial standards.