⚡ New — Kimi K3 is live: bring your own Moonshot key →
Documentation

Client SDKs & frameworks

BharatRouter speaks the OpenAI wire format, so you don't need a special SDK — point the OpenAI-compatible client you already use at the gateway and change nothing else. This page shows the drop-in for the common stacks, and where the four BharatRouterrouting extensions live in each.

The drop-in pattern

Base URLhttps://api.bharatrouter.com/v1
AuthAuthorization: Bearer br-…sign in and mint a key
Extensionsoptimize, provider, data_policy, upstream_key — sent in the request body, consumed by the router, stripped before the request leaves the gateway

The only per-SDK question is where the extensions go — every OpenAI client has an escape hatch for non-standard fields. The table at the end of this page lists each one.

OpenAI SDK — Python

Extensions ride in extra_body.

from openai import OpenAI

client = OpenAI(base_url="https://api.bharatrouter.com/v1", api_key="br-...")

r = client.chat.completions.create(
    model="gemma-4-e4b-it",
    messages=[{"role": "user", "content": "namaste"}],
    extra_body={"data_policy": "india_only", "optimize": "price"},
)
print(r.choices[0].message.content)
# which route served you? use .with_raw_response to read the x-br-provider header:
raw = client.chat.completions.with_raw_response.create(
    model="gemma-4-e4b-it", messages=[{"role": "user", "content": "namaste"}],
)
print("served by:", raw.headers.get("x-br-provider"))

OpenAI SDK — Node / TypeScript

The JS SDK forwards unknown fields, so extensions can sit alongside the standard ones.

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.bharatrouter.com/v1",
  apiKey: "br-...",
});

const r = await client.chat.completions.create({
  model: "gemma-4-e4b-it",
  messages: [{ role: "user", content: "namaste" }],
  // BharatRouter extensions pass straight through:
  data_policy: "india_only",
  optimize: "latency",
} as any);
console.log(r.choices[0].message.content);

Vercel AI SDK

Use the OpenAI-compatible provider with a custom baseURL; pass extensions viaproviderOptions (or extraBody).

import { createOpenAI } from "@ai-sdk/openai";
import { streamText } from "ai";

const bharat = createOpenAI({
  baseURL: "https://api.bharatrouter.com/v1",
  apiKey: process.env.BHARATROUTER_API_KEY,
});

const result = await streamText({
  model: bharat("gemma-4-e4b-it"),
  prompt: "Explain UPI in two lines",
  providerOptions: { openai: { data_policy: "india_only", optimize: "price" } },
});

for await (const delta of result.textStream) process.stdout.write(delta);

LangChain

Point ChatOpenAI at the gateway. Extensions go in model_kwargs(Python) / modelKwargs (JS).

# Python
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    base_url="https://api.bharatrouter.com/v1",
    api_key="br-...",
    model="gemma-4-e4b-it",
    model_kwargs={"extra_body": {"data_policy": "india_only", "optimize": "price"}},
)
print(llm.invoke("namaste").content)
// JavaScript
import { ChatOpenAI } from "@langchain/openai";

const llm = new ChatOpenAI({
  model: "gemma-4-e4b-it",
  apiKey: "br-...",
  configuration: { baseURL: "https://api.bharatrouter.com/v1" },
  modelKwargs: { data_policy: "india_only", optimize: "price" },
});
console.log((await llm.invoke("namaste")).content);

LlamaIndex

Use the OpenAI-like LLM with the gateway base URL.

from llama_index.llms.openai_like import OpenAILike

llm = OpenAILike(
    model="gemma-4-e4b-it",
    api_base="https://api.bharatrouter.com/v1",
    api_key="br-...",
    is_chat_model=True,
    additional_kwargs={"data_policy": "india_only", "optimize": "price"},
)
print(llm.complete("namaste"))

Embeddings

The same swap works for embeddings — point any OpenAI embeddings client at the gateway.

from openai import OpenAI

client = OpenAI(base_url="https://api.bharatrouter.com/v1", api_key="br-...")
e = client.embeddings.create(model="bge-m3", input=["namaste", "vanakkam"])
print(len(e.data[0].embedding))

Where the extensions go, per SDK

SDK / frameworkHow to pass optimize / data_policy / …
OpenAI SDK (Python)extra_body={...}
OpenAI SDK (Node)Top-level fields on the request object (cast as needed)
Vercel AI SDKproviderOptions.openai (or extraBody)
LangChain (Py)model_kwargs={"extra_body": {...}}
LangChain (JS)modelKwargs: {...}
LlamaIndexadditional_kwargs={...}
Raw HTTP / curlTop-level JSON fields in the request body

Building an agent? See Agentsfor tool-calling and MCP. Coming from another platform? Seemigration guides. Recipes live in the Cookbook.