Routeplane speaks the OpenAI wire protocol, so no Routeplane SDK is required. You keep the client library you already use and change one value: the base URL.
That is the whole integration. Everything else — routing, fallback, residency enforcement, guardrails, budgets — is configured server-side against your virtual key, or per-request through x-routeplane-* headers your SDK already knows how to send. This page covers that base-URL-only path and the full header reference.
Prefer a typed helper? Optional official SDKs add ergonomics on top of this — a typed x-routeplane-* header builder, a drop-in client that reads the gateway’s decision metadata, and typed access to the non-OpenAI surfaces. See the Python and TypeScript SDKs, the CLI, and the MCP server. They are conveniences, never a requirement: pointing base_url back at the provider is still a one-line revert.
Python
from openai import OpenAI
client = OpenAI(
base_url="https://<gateway-host>/v1", # the only change
api_key="rp_...", # your Routeplane virtual key
default_headers={
"x-routeplane-provider": "openai,anthropic", # optional fallback chain
},
)
resp = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)
TypeScript / JavaScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://<gateway-host>/v1", // the only change
apiKey: process.env.ROUTEPLANE_KEY, // rp_...
defaultHeaders: {
"x-routeplane-provider": "openai,anthropic",
},
});
const resp = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello" }],
});
Go
Using sashabaranov/go-openai:
cfg := openai.DefaultConfig("rp_...")
cfg.BaseURL = "https://<gateway-host>/v1" // the only change
client := openai.NewClientWithConfig(cfg)
resp, err := client.CreateChatCompletion(ctx, openai.ChatCompletionRequest{
Model: "gpt-4o",
Messages: []openai.ChatCompletionMessage{{Role: "user", Content: "Hello"}},
})
Any other language
If your language has an OpenAI client, set its base URL and you are done. If it does not, the surface is ordinary HTTP and JSON — there is nothing Routeplane-specific to implement:
curl https://<gateway-host>/v1/chat/completions \
-H "content-type: application/json" \
-H "x-routeplane-api-key: rp_..." \
-d '{"model":"gpt-4o","messages":[{"role":"user","content":"Hello"}]}'
Authentication accepts either x-routeplane-api-key or the standard Authorization: Bearer header, so a client that only knows how to send an OpenAI key still works.
Request headers you can send
All optional. Every one has a server-side default, so an SDK that cannot set custom headers still works — it simply uses your key's configured behaviour.
| Header | Effect |
|---|---|
x-routeplane-provider | Provider, or a comma-separated fallback chain. |
x-routeplane-residency | Requested jurisdiction, e.g. IN. Enforced when the request carries regulated personal data. |
x-routeplane-strategy | priority (default), weighted, cost, or latency. |
x-routeplane-config | A full declarative routing config for this request. |
idempotency-key | Safe retries — a replayed key returns the stored response. |
Response headers you get back
These are the headers the gateway actually sets, and they are exposed through CORS so a browser client can read them too.
| Header | Meaning |
|---|---|
x-routeplane-provider | Which provider actually served the request — after fallback. |
x-routeplane-trace-id | Correlation id. Send it back to POST /v1/feedback to attach a quality score. |
x-routeplane-request-id | Per-request id for support and log correlation. |
x-routeplane-guardrails | Guardrail verdicts for this request. |
x-routeplane-cache | Cache outcome: hit, miss, or bypass. |
x-routeplane-hedged | Present when a hedged request served the response. |
x-routeplane-idempotent-replayed | Present when this was a stored replay rather than a fresh call. |
x-routeplane-budget-remaining | Remaining spend on the applicable budget scope. |
x-routeplane-budget-warning | Present as you approach a budget threshold. |
x-routeplane-compliance-warning | Present when a compliance framework flagged the request without blocking it. |
Note. x-routeplane-residency is a request header only. The gateway does not echo it back; to see where a request was actually served, read x-routeplane-provider.
Streaming
Set stream: true exactly as you would against the provider. The response is a standard text/event-stream of data: chunks terminated by data: [DONE], so your SDK's existing streaming code path is unchanged.
One behaviour worth knowing: fallback to another provider is possible only until the first chunk is sent. After that the gateway is committed, and an upstream failure ends the stream rather than silently switching providers mid-answer.