Provider passthrough
Keep a provider-native SDK or IDE path—change only the base URL. The platform eis_* key is still required. Passthrough paths do not use Console failover routes (model-prefix resolve only). Rate limits still apply when a policy is effective — see Rate limits.
When to use passthrough vs Unified
| Use passthrough (this page) when… | Use Unified /gateway/v1 when… |
|---|---|
| Client must speak Anthropic Messages, raw OpenAI, or another vendor API | One OpenAI-compatible client should call many providers |
| Claude Code / Anthropic SDK / Agno Claude / OpenAI-only Agents SDK | LangChain, Vercel AI, CrewAI, ADK with provider/model ids |
| You accept no Console failover routes on this path | You want Management → Routes failover + one env URL |
| Special case | Surface |
|---|---|
| Cursor IDE Override Base URL | /gateway/cursor adapter — not /gateway/openai/v1 |
| IDE tool / prompt governance | Relay — independent of model base |
Full matrix + mistakes: Choose your surface.
Bases (IDE + SDK)
| Client | Use this base | Notes |
|---|---|---|
| Claude Code / Anthropic SDK / Agno Claude | https://production-api.exemplar.dev/gateway/anthropic | Native Messages API. Client appends /v1/…. Full guide: Claude Code |
| Cursor IDE | https://production-api.exemplar.dev/gateway/cursor | Not a raw OpenAI passthrough—dedicated adapter. Full guide: Cursor IDE |
| OpenAI SDK / Agents SDK / Agno OpenAIChat / ADK→OpenAI | https://production-api.exemplar.dev/gateway/openai/v1 | OpenAI-shaped paths; bare model ids |
| Gemini | https://production-api.exemplar.dev/gateway/genai | |
| Groq | https://production-api.exemplar.dev/gateway/groq/openai/v1 |
Prefer Unified API (/gateway/v1) when one OpenAI-compatible client should reach many providers. Use passthrough (or the Cursor adapter) when the client must keep a native request/response shape.
Anthropic / Claude passthrough
Mount: /gateway/anthropic/v1/*. Set the client base URL to …/gateway/anthropic (no trailing /v1—SDKs and Claude Code add it).
Enable anthropic under AI Gateway → Management → Providers and attach Vault/Connectors credentials.
Anthropic SDK
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: process.env.EXEMPLAR_API_KEY!, // eis_…
baseURL: "https://production-api.exemplar.dev/gateway/anthropic",
});
await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 256,
messages: [{ role: "user", content: "Hello" }],
});import os
from anthropic import Anthropic
client = Anthropic(
api_key=os.environ["EXEMPLAR_API_KEY"], # eis_…
base_url="https://production-api.exemplar.dev/gateway/anthropic",
)
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=256,
messages=[{"role": "user", "content": "Hello"}],
)Native streaming is supported. Use bare Anthropic model ids (claude-sonnet-4-6), not anthropic/claude-… (that form is for /gateway/v1).
Claude Code
Same base URL via ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN. Model aliases, VS Code, and Relay split: Claude Code.
export ANTHROPIC_BASE_URL=https://production-api.exemplar.dev/gateway/anthropic
export ANTHROPIC_AUTH_TOKEN=eis_…Smoke test
curl -sS https://production-api.exemplar.dev/gateway/anthropic/v1/messages \
-H "Authorization: Bearer $EXEMPLAR_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 64,
"messages": [{"role": "user", "content": "ping"}]
}'Cursor (adapter — not OpenAI passthrough)
Cursor’s Override OpenAI Base URL must be:
https://production-api.exemplar.dev/gateway/cursor| Do not use | Why |
|---|---|
/gateway/openai/v1 | OpenAI passthrough expects real Chat Completions; Cursor often sends Responses-shaped bodies |
/gateway/v1 | Same mismatch on /chat/completions |
/gateway/anthropic | Anthropic Messages only—Cursor still talks “OpenAI override” wire format |
/gateway/cursor (and /gateway/cursor/v1/chat/completions) adapts Cursor’s payloads to the gateway Responses/Chat APIs and returns Chat Completions SSE. Telemetry: route_mode=cursor. Setup: Cursor IDE.
curl -sS https://production-api.exemplar.dev/gateway/cursor/chat/completions \
-H "Authorization: Bearer $EXEMPLAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-4o-mini","input":[{"role":"user","content":"hi"}]}'OpenAI passthrough
For OpenAI-compatible SDKs that should hit OpenAI only (native /v1 paths):
https://production-api.exemplar.dev/gateway/openai/v1import OpenAI from "openai";
const openai = new OpenAI({
apiKey: process.env.EXEMPLAR_API_KEY!,
baseURL: "https://production-api.exemplar.dev/gateway/openai/v1",
});
await openai.chat.completions.create({
model: "gpt-4o-mini", // bare OpenAI id on this passthrough
messages: [{ role: "user", content: "Hello" }],
});import os
from openai import OpenAI
openai = OpenAI(
api_key=os.environ["EXEMPLAR_API_KEY"],
base_url="https://production-api.exemplar.dev/gateway/openai/v1",
)
openai.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
)Enable openai under Management → Providers. Use bare OpenAI model ids (gpt-4o-mini), not openai/gpt-4o-mini (that form is for /gateway/v1).
For multi-provider routing with provider/model ids, prefer /gateway/v1 — see Frameworks.
Framework SDKs on passthrough
These examples pin a native provider mount (OpenAI or Anthropic). Swap the base to /gateway/v1 when you need cross-provider provider/model routing instead.
OpenAI Agents SDK
Point OPENAI_BASE_URL at the OpenAI passthrough and use bare model ids. Prefer Chat Completions if the passthrough path you use does not expose Responses the way the Agents SDK expects by default.
import { Agent, run } from "@openai/agents";
process.env.OPENAI_BASE_URL =
"https://production-api.exemplar.dev/gateway/openai/v1";
process.env.OPENAI_API_KEY = process.env.EXEMPLAR_API_KEY!;
const agent = new Agent({
name: "Platform copilot",
model: "gpt-4o-mini",
instructions: "You are an SRE assistant.",
});
await run(agent, "Summarize open incidents");import os
from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client, set_default_openai_api
os.environ["OPENAI_API_KEY"] = os.environ["EXEMPLAR_API_KEY"]
set_default_openai_client(
AsyncOpenAI(
api_key=os.environ["EXEMPLAR_API_KEY"],
base_url="https://production-api.exemplar.dev/gateway/openai/v1",
),
use_for_tracing=False,
)
# Passthrough is Chat Completions–shaped; force that API if the SDK defaults to Responses.
set_default_openai_api("chat_completions")
agent = Agent(
name="Platform copilot",
model="gpt-4o-mini",
instructions="You are an SRE assistant.",
)
Runner.run(agent, "Summarize open incidents")Multi-provider Agents SDK setups (e.g. openai/gpt-4o-mini on a shared client) should use /gateway/v1 — see Frameworks → OpenAI Agents SDK.
Agno
Agno’s OpenAI-compatible model takes base_url. For Claude, point at the Anthropic passthrough.
import os
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.models.anthropic import Claude
# OpenAI passthrough
openai_agent = Agent(
model=OpenAIChat(
id="gpt-4o-mini",
api_key=os.environ["EXEMPLAR_API_KEY"],
base_url="https://production-api.exemplar.dev/gateway/openai/v1",
),
markdown=True,
)
openai_agent.print_response("Summarize open incidents")
# Anthropic / Claude passthrough
claude_agent = Agent(
model=Claude(
id="claude-sonnet-4-6",
api_key=os.environ["EXEMPLAR_API_KEY"],
base_url="https://production-api.exemplar.dev/gateway/anthropic",
),
markdown=True,
)
claude_agent.print_response("Summarize open incidents")Google ADK
ADK’s LiteLLM shim is OpenAI-compatible. Against the OpenAI passthrough, keep the LiteLLM openai/ provider prefix and a bare OpenAI model name; set api_base to /gateway/openai/v1.
import os
from google.adk.models.lite_llm import LiteLlm
llm = LiteLlm(
model="openai/gpt-4o-mini", # LiteLLM provider + OpenAI model id
api_base="https://production-api.exemplar.dev/gateway/openai/v1",
api_key=os.environ["EXEMPLAR_API_KEY"],
)
# Attach llm to your ADK LlmAgent / root agent as usual.For Gemini via the unified multi-provider root (LiteLLM + gateway provider/model):
llm = LiteLlm(
model="openai/gemini/gemini-2.5-flash", # LiteLLM + gateway provider/model
api_base="https://production-api.exemplar.dev/gateway/v1",
api_key=os.environ["EXEMPLAR_API_KEY"],
)That second form is unified, not OpenAI passthrough — details on Frameworks → Google ADK. Native Gemini clients can also use the /gateway/genai mount from the table above.
Other provider mounts
| Provider | Prefix (under /gateway) |
|---|---|
| Gemini | /genai |
| Azure OpenAI | /azure/openai |
| Bedrock | /bedrock, /bedrock-mantle |
| Groq | /groq/openai/v1 |
| Mistral | /mistral/v1 |
| Ollama | /ollama/v1 |
| OpenRouter | /openrouter/api/v1 |
| Cohere | /cohere/v2, /cohere/compatibility/v1 |
| Perplexity | /perplexity/v1 |
| xAI | /xai/v1 |
| Moonshot AI (Kimi) | /moonshot/v1 |
| Hugging Face | /huggingface |
| Vertex | /vertex |
| vLLM / Cerebras / Fireworks / … | see gateway OpenAPI (/gateway/docs) |
When to use which
Same decision as the rest of the gateway docs — prefer this table, or the full guide:
| Need | Prefer |
|---|---|
| One client, many providers | Unified API (/gateway/v1) |
| Anthropic Messages / Claude Code / Claude Agent SDK / Agno Claude | Anthropic passthrough (/gateway/anthropic) |
| OpenAI Agents SDK / Agno OpenAIChat / ADK→OpenAI (single provider) | OpenAI passthrough (/gateway/openai/v1) |
| Cursor Ask/Plan override | Cursor adapter (/gateway/cursor) |
ADK / frameworks with provider/model ids | Unified /gateway/v1 — Frameworks |
→ Choose your surface for the side-by-side comparison and decision flow.
Related
- Choose your surface — when to use Unified vs passthrough vs Cursor
- Getting started — auth and
eis_*keys - Claude Code — settings.json and aliases
- Cursor IDE — Override Base URL and failure modes
- Unified API — Chat Completions and Responses
- Frameworks — LangChain, ADK, Agents SDK, CrewAI on
/gateway/v1