OpenAI-compatible clients¶
The gateway is OpenAI Chat Completions-compatible. Any client that takes an OpenAI base URL + API key will work. The only things to be careful about are:
- The base URL must include
/v1. - The
modelfield must be one of the four aliases. - Bearer token is the gateway key, not the OpenRouter key.
Python (openai SDK)¶
import os
from openai import OpenAI
client = OpenAI(
base_url=os.environ["SMART_GATEWAY_BASE_URL"] + "/v1",
api_key=os.environ["SMART_GATEWAY_API_KEY"],
)
resp = client.chat.completions.create(
model="smart-router",
messages=[{"role": "user", "content": "Reply with the word PONG."}],
max_tokens=8,
)
print(resp.choices[0].message.content)
Set the environment variables first:
export SMART_GATEWAY_BASE_URL="https://smart-openrounter.bee1x.one"
export SMART_GATEWAY_API_KEY="$YOUR_GATEWAY_KEY"
Node / TypeScript (openai SDK)¶
import OpenAI from "openai";
const client = new OpenAI({
baseURL: `${process.env.SMART_GATEWAY_BASE_URL}/v1`,
apiKey: process.env.SMART_GATEWAY_API_KEY,
});
const completion = await client.chat.completions.create({
model: "smart-router",
messages: [{ role: "user", content: "Reply with the word PONG." }],
max_tokens: 8,
});
console.log(completion.choices[0].message.content);
Streaming in the Python SDK¶
stream = client.chat.completions.create(
model="smart-router-flash",
stream=True,
messages=[{"role": "user", "content": "Count to 5 slowly."}],
max_tokens=64,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
Tool calling¶
The gateway forwards tool definitions and tool messages to OpenRouter unchanged. The OpenAI SDK pattern works as-is:
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
resp = client.chat.completions.create(
model="smart-router",
messages=[{"role": "user", "content": "Weather in Tokyo?"}],
tools=tools,
tool_choice="auto",
)
The response follows OpenAI's standard tool_calls shape.
Headers / metadata¶
To set sensitive, reasoning, session_id, goal_id, task_id,
use the metadata field in the request body:
resp = client.chat.completions.create(
model="smart-router",
messages=[{"role": "user", "content": "..."}],
extra_body={
"metadata": {
"sensitive": True,
"reasoning": "high",
"session_id": "proj-A-2026-08-23",
"goal_id": "fix-flaky",
"task_id": "task-17",
}
},
)
The OpenAI SDK supports extra_body for forwarding fields that are
not part of the typed schema. The OpenAI Node SDK uses metadata
directly in the request body.
To send control headers (X-Pro, X-Scout, etc.) you need to drop
down to the raw HTTP layer (httpx in Python, fetch in Node) or use a
custom HTTP client.
Responses API is not supported¶
The OpenAI Responses API (/v1/responses) is not implemented in
v1.0.0. If you try it, you will get a 404. Use Chat Completions.
LiteLLM proxying¶
If you want to use the gateway as the upstream for a self-hosted LiteLLM proxy, point LiteLLM at the gateway exactly as you would point it at OpenAI:
model_list:
- model_name: smart-router
litellm_params:
model: openai/smart-router
api_base: https://smart-openrounter.bee1x.one/v1
api_key: os.environ/SMART_GATEWAY_API_KEY
Note that the gateway itself already runs on OpenRouter direct
(frozen-v3/15-transport-decision.md). Adding LiteLLM in front is
optional and most useful if you need multi-provider governance or
virtual keys; it does not make the routing decisions.
LangChain / LlamaIndex¶
Both frameworks have an "OpenAI-compatible" mode. Use the gateway
base URL as the openai_api_base (LangChain) or
api_base (LlamaIndex), pass the gateway key, and use
model="smart-router" (or one of the other aliases).