OpenAI SDK Drop-in

Reuse the official OpenAI SDKs (Python, Node, Go, Java, etc.) with AllRoutes by changing only the base URL and API key.

Overview

You don't have to install an AllRoutes SDK to use AllRoutes. The gateway is byte-compatible with the OpenAI HTTP API, which means the official OpenAI SDKs in every language work out of the box -- you just point them at https://api.allroutes.ai/v1 with your AllRoutes key.

This guide shows the two-line swap for the most common SDKs, and which advanced features (routing, presets, plugins) you can still pass through via custom headers and request fields.

The Two-Line Swap

Every OpenAI SDK exposes:

  1. A way to set the API key (api_key, OPENAI_API_KEY, etc.)
  2. A way to override the base URL (base_url, baseURL, OPENAI_BASE_URL, etc.)

Set both, and you're done.

Python (openai-python)

from openai import OpenAI

client = OpenAI(
    api_key="allroutes_sk_...",
    base_url="https://api.allroutes.ai/v1",
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)

Or via environment variables:

export OPENAI_API_KEY="allroutes_sk_..."
export OPENAI_BASE_URL="https://api.allroutes.ai/v1"
from openai import OpenAI
client = OpenAI()  # picks up env vars

Node.js (openai npm)

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "allroutes_sk_...",
  baseURL: "https://api.allroutes.ai/v1",
});

const completion = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello!" }],
});

Go (openai-go)

import (
    "github.com/sashabaranov/go-openai"
)

config := openai.DefaultConfig("allroutes_sk_...")
config.BaseURL = "https://api.allroutes.ai/v1"
client := openai.NewClientWithConfig(config)

resp, err := client.CreateChatCompletion(ctx, openai.ChatCompletionRequest{
    Model: "gpt-4o",
    Messages: []openai.ChatCompletionMessage{{Role: "user", Content: "Hello!"}},
})

Java (openai-java)

import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;

OpenAIClient client = OpenAIOkHttpClient.builder()
    .apiKey("allroutes_sk_...")
    .baseUrl("https://api.allroutes.ai/v1")
    .build();

.NET (Azure.AI.OpenAI / official OpenAI .NET)

using OpenAI;

OpenAIClient client = new(
    new ApiKeyCredential("allroutes_sk_..."),
    new OpenAIClientOptions { Endpoint = new Uri("https://api.allroutes.ai/v1") }
);

Ruby (ruby-openai)

client = OpenAI::Client.new(
  access_token: "allroutes_sk_...",
  uri_base: "https://api.allroutes.ai"
)

LangChain (Python)

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="claude-sonnet-4-20250514",  # any AllRoutes-supported model
    api_key="allroutes_sk_...",
    base_url="https://api.allroutes.ai/v1",
)

LlamaIndex (Python)

from llama_index.llms.openai_like import OpenAILike

llm = OpenAILike(
    model="gpt-4o",
    api_key="allroutes_sk_...",
    api_base="https://api.allroutes.ai/v1",
)

Multi-Provider Models Just Work

After the swap, you can pass any AllRoutes-supported model identifier as model:

client.chat.completions.create(model="claude-sonnet-4-20250514", messages=msgs)
client.chat.completions.create(model="gemini-2.0-flash", messages=msgs)
client.chat.completions.create(model="meta-llama/llama-3.1-405b-instruct", messages=msgs)

The OpenAI SDK doesn't validate the model name -- it just forwards the string. AllRoutes does the model-to-provider routing.

Using AllRoutes-Specific Features

The OpenAI SDKs accept arbitrary extra fields in the request body via extra_body (Python), body (Node), or by sending raw JSON. Use these to pass AllRoutes-specific parameters:

Python (extra_body)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
    extra_body={
        "models": ["gpt-4o", "claude-sonnet-4-20250514"],  # fallback chain
        "plugins": [{"id": "web"}],
        "preset": "support-bot",
        "guardrail": "hipaa",
        "session_id": "sess_456",
        "metadata": {"feature": "chat-widget"},
    },
)

Node.js (body)

const completion = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello!" }],
  // @ts-expect-error - AllRoutes-specific fields
  models: ["gpt-4o", "claude-sonnet-4-20250514"],
  plugins: [{ id: "web" }],
  preset: "support-bot",
});

Go

The Go SDKs typically expose a generic JSONBody or ExtraBody option. Check your SDK's docs.

Headers

If you prefer headers over body fields, AllRoutes accepts the OpenRouter-style headers as well:

HeaderPurpose
HTTP-RefererOrigin URL for analytics
X-TitleApp name for analytics
X-AllRoutes-PresetApply a preset
X-AllRoutes-GuardrailApply a guardrail profile
X-AllRoutes-Session-IdSession grouping
response = client.chat.completions.create(
    model="gpt-4o",
    messages=msgs,
    extra_headers={
        "HTTP-Referer": "https://your-app.com",
        "X-Title": "My App",
        "X-AllRoutes-Preset": "support-bot",
    },
)

What's Different from Direct OpenAI

The wire format is identical for the chat completions, embeddings, and audio endpoints, but a few areas need attention:

FeatureNotes
StreamingIdentical SSE protocol; no changes needed
Tool callingIdentical schema
VisionIdentical (multimodal image_url content)
Beta endpoints (Assistants, Vector Stores)Some are not yet supported -- check the API reference
Error envelopeAllRoutes adds error.allroutes_request_id for support tickets
Response headersAllRoutes adds X-AllRoutes-* headers (cost, cache, provider)

Migration Checklist

  1. Set OPENAI_API_KEY=allroutes_sk_... and OPENAI_BASE_URL=https://api.allroutes.ai/v1
  2. Run your existing test suite -- no other code changes should be needed
  3. Verify the X-AllRoutes-Provider header on a sample response
  4. Decide whether to keep the OpenAI SDK or switch to the Python / Node / Go SDK for richer typed support of AllRoutes features

Troubleshooting

SymptomCauseFix
404: model_not_foundModel identifier is OpenAI-onlyUse AllRoutes naming (e.g., claude-sonnet-4-20250514)
401 even though key is setKey has wrong prefixDouble-check allroutes_sk_ not sk-
Extra fields ignoredStrict-mode SDK strips unknown keysUse extra_body (Python) or raw JSON
Type errors on extra_bodyTypeScript Strict ModeAdd // @ts-expect-error or augment the type

See Also