SuperRouter: Unified OpenAI & Anthropic Gateway for FastAPI

SuperRouter: Unified OpenAI & Anthropic Gateway for FastAPI

SuperRouter: Unified OpenAI & Anthropic Gateway for FastAPI

When building LLM-powered applications, managing different client SDKs and upstream provider protocols often introduces messy glue code. SuperRouter solves this by providing a dual-format FastAPI router that exposes both OpenAI-compatible and Anthropic-compatible endpoints within the same application.

It seamlessly bridges the gap across architectures: point an OpenAI client or Anthropic client at your server, and SuperRouter automatically detects, translates, and forwards requests and streaming responses (SSE) to the appropriate upstream provider.

Key Features

  • Bi-Directional Format Translation: Exposes /v1/chat/completions and /v1/messages. It automatically maps wire formats back and forth—send Anthropic-style payloads to OpenAI endpoints or vice-versa.

  • Full SSE Streaming Support: Translates real-time Server-Sent Events (SSE) streams between OpenAI and Anthropic formats on the fly.

  • Smart Model & Provider Routing:

  • Routes models starting with claude* automatically to Anthropic upstreams.

  • Falls back cleanly to configured default providers.

  • Allows manual routing overrides using the x-super-upstream header.

  • Drop-in FastAPI Integration: Mounts directly onto any existing FastAPI instance as a standard APIRouter.

  • Unified Client Authentication: Secure incoming client traffic with custom API keys via Bearer tokens, x-api-key headers, or query parameters.

  • Passthrough & Aggregation Endpoints: Supports passthrough for embeddings, legacy completions, token counting, and aggregates model lists from all registered providers.

Supported Endpoints

MethodPathUpstream Handling
POST/v1/chat/completionsTranslated to upstream provider format
POST/v1/messagesTranslated to upstream provider format
POST/v1/completionsOpenAI passthrough
POST/v1/embeddingsOpenAI passthrough
POST/v1/messages/count_tokensAnthropic passthrough
GET/v1/modelsAggregated list across all active providers
GET/healthLocal health check

Installation

Install using pip:

pip install superrouter

# With server and dev dependencies:
pip install "superrouter[dev,server]"

Or using uv:

uv add superrouter
uv sync --extra server

Quickstart

Add SuperRouter to an existing FastAPI app in just a few lines:

from fastapi import FastAPI
from superrouter import SuperRouter

app = FastAPI(title="LLM Gateway")

router = SuperRouter(
    providers={
        "openai": {
            "base_url": "https://api.openai.com/v1",
            "api_key": "sk-openai-...",
            "kind": "openai",
        },
        "anthropic": {
            "base_url": "https://api.anthropic.com/v1",
            "api_key": "sk-ant-...",
            "kind": "anthropic",
        },
    },
    default="openai",
    api_keys=["sk-my-router-key"],  # Protect your router endpoints
    timeout=(10, 600),             # (connect, read) timeouts in seconds
)

app.include_router(router)

Run the server with Uvicorn:

uv run uvicorn main:app --reload --port 8000

Client Usage Examples

Once running, point standard official SDKs directly to your local endpoint.

1. Using the OpenAI Python SDK

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="sk-my-router-key",
)

# Call an OpenAI model (routed to OpenAI)
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Explain SSE in one sentence."}],
)
print(response.choices[0].message.content)

# Call a Claude model via the OpenAI endpoint (translated to Anthropic wire format)
claude_response = client.chat.completions.create(
    model="claude-3-5-sonnet-20241022",
    messages=[{"role": "user", "content": "Hello Claude via OpenAI API format!"}],
)
print(claude_response.choices[0].message.content)

2. Using the Anthropic Python SDK

import anthropic

client = anthropic.Anthropic(
    base_url="http://localhost:8000/v1",
    api_key="sk-my-router-key",
)

# Automatically translates Anthropic messages payload to the appropriate provider
message = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Stream a short haiku."}],
)
print(message.content[0].text)

3. Forcing Upstreams with Headers

If you have multiple providers or self-hosted models (like vLLM or Ollama), route explicitly with the x-super-upstream header:

curl http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer sk-my-router-key" \
  -H "x-super-upstream: openai" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "Ping!"}]
  }'

Routing & Authentication Rules

Provider Selection Priority

  1. Explicit Header: x-super-upstream: <provider_name> takes precedence.
  2. Model Matching: Model names prefixed with claude are routed to the first configured anthropic provider.
  3. Fallback: All other requests fall back to the designated default provider (or the first registered provider).

Client Authentication

When api_keys is configured, all endpoints (except /health) require authentication via any of:

  • Authorization: Bearer <key>
  • x-api-key: <key>
  • Query parameter: ?key=<key>