Skip to Content
AI GatewayProvider passthrough

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 APIOne OpenAI-compatible client should call many providers
Claude Code / Anthropic SDK / Agno Claude / OpenAI-only Agents SDKLangChain, Vercel AI, CrewAI, ADK with provider/model ids
You accept no Console failover routes on this pathYou want Management → Routes failover + one env URL
Special caseSurface
Cursor IDE Override Base URL/gateway/cursor adapter — not /gateway/openai/v1
IDE tool / prompt governanceRelay — independent of model base

Full matrix + mistakes: Choose your surface.

Bases (IDE + SDK)

ClientUse this baseNotes
Claude Code / Anthropic SDK / Agno Claudehttps://production-api.exemplar.dev/gateway/anthropicNative Messages API. Client appends /v1/…. Full guide: Claude Code
Cursor IDEhttps://production-api.exemplar.dev/gateway/cursorNot a raw OpenAI passthrough—dedicated adapter. Full guide: Cursor IDE
OpenAI SDK / Agents SDK / Agno OpenAIChat / ADK→OpenAIhttps://production-api.exemplar.dev/gateway/openai/v1OpenAI-shaped paths; bare model ids
Geminihttps://production-api.exemplar.dev/gateway/genai
Groqhttps://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 useWhy
/gateway/openai/v1OpenAI passthrough expects real Chat Completions; Cursor often sends Responses-shaped bodies
/gateway/v1Same mismatch on /chat/completions
/gateway/anthropicAnthropic 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/v1
import 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

ProviderPrefix (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:

NeedPrefer
One client, many providersUnified API (/gateway/v1)
Anthropic Messages / Claude Code / Claude Agent SDK / Agno ClaudeAnthropic passthrough (/gateway/anthropic)
OpenAI Agents SDK / Agno OpenAIChat / ADK→OpenAI (single provider)OpenAI passthrough (/gateway/openai/v1)
Cursor Ask/Plan overrideCursor adapter (/gateway/cursor)
ADK / frameworks with provider/model idsUnified /gateway/v1Frameworks

Choose your surface for the side-by-side comparison and decision flow.

Last updated on