Python integration guide

OpenRouter Python quickstart: OpenAI SDK, base URL, and first request

To call OpenRouter with the OpenAI Python SDK, install openai, set OPENROUTER_API_KEY, and use base_url="https://openrouter.ai/api/v1". Choose an exact chat model ID from OpenRouter’s current catalog, then call client.chat.completions.create. The SDK appends /chat/completions; attribution headers are optional. The native openrouter package is a separate option for OpenRouter-specific resources.

Last reviewed 2026-09-27 · Editorial review: KeepRouter Editorial

Run the first request with the OpenAI Python SDK

  1. Install the package in the Python environment that will run the script: python -m pip install openai.
  2. Set OPENROUTER_API_KEY in that process's environment or deployment secret store. Use an OpenRouter key, not a key issued by another gateway. Do not print it.
  3. Choose a chat model from the OpenRouter catalog and set OPENROUTER_MODEL to its exact ID. Check that model's price and account access before running the request.
  4. Save the following as openrouter_test.py and run python openrouter_test.py in the same environment.
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key=os.environ["OPENROUTER_API_KEY"],
    timeout=30.0,
    max_retries=0,
)
response = client.chat.completions.create(
    model=os.environ["OPENROUTER_MODEL"],
    messages=[{"role": "user", "content": "Return only the word ready"}],
    max_tokens=64,
)
print(response.choices[0].message.content)
print(response.usage.model_dump() if response.usage else "usage missing")

The first test disables automatic SDK retries and limits the response to 64 output tokens, so one script run does not silently become several attempts. It can incur a charge at the selected model's rate. A local KeyError means the Python process cannot read a required environment variable; it is not an API authentication response. Check the variable name and the environment used by your terminal, container, or deployment without printing its value.

OpenRouter documents HTTP-Referer and X-OpenRouter-Title as optional app-attribution headers. The minimal example omits them. Add them through extra_headers only when you want to identify your app, and never put an API secret in their values.

When to use the native OpenRouter SDK

Python optionInstallClient and methodUse it when
OpenAI Python SDKpython -m pip install openaiOpenAI(base_url=...).chat.completions.create(...)You already use OpenAI-shaped chat requests
Native OpenRouter SDKpython -m pip install openrouterOpenRouter(...).chat.send(...)You want typed OpenRouter-specific resources
Raw HTTPYour HTTP clientPOST /api/v1/chat/completionsYou want to manage request and response handling directly

The native package has a different client and method. After installing openrouter, reuse the same environment variables:

import os
from openrouter import OpenRouter

with OpenRouter(api_key=os.environ["OPENROUTER_API_KEY"]) as client:
    response = client.chat.send(
        model=os.environ["OPENROUTER_MODEL"],
        messages=[{"role": "user", "content": "Return only the word ready"}],
        max_tokens=64,
        stream=False,
    )
    print(response)

Pin the package version you test. The native SDK's resource methods are not interchangeable with the OpenAI SDK, and the first text response does not validate async, streaming, tool calls, or error handling.

How the final URL is formed

PartValue
SDK base URLhttps://openrouter.ai/api/v1
Chat operation appended by the SDK/chat/completions
Final request URLhttps://openrouter.ai/api/v1/chat/completions

If the base URL is missing /api/v1, the SDK calls a route that is not the documented API surface. If application code appends /chat/completions itself and the SDK appends it again, the path is duplicated. Log the host and path without the credential when diagnosing a 404.

OpenRouter-specific fields do not migrate automatically

OpenRouter can accept provider preferences, fallback model lists, routing variants, attribution headers, and other extensions. With the OpenAI SDK, some are passed through extra_body or extra_headers. Those fields are not part of a generic OpenAI-compatible contract.

Field or behaviorPortable across compatible gateways?Migration action
messages, basic chat rolesOften, for an implemented chat routeReplay a representative request
Base URL and API keyNoReplace both
Model slugNoMap to the target catalog's exact ID
Provider order, only, ZDR, route sortingNoRemove or rebuild from the target product's public controls
OpenRouter attribution headersNoRemove unless the target documents them
Streaming and toolsSyntax may match, behavior may differTest event order, arguments, continuation, errors, and cancellation

Minimal migration to KeepRouter

Check your credential-free configuration with the browser-local migration checker, then download the Python and Node starter pack. Start with dry-run; live compatibility requires testing your exact route and workload.

KeepRouter does not support the native openrouter package as its client contract. Keep the OpenAI SDK path and change the base URL, credential, and model to a compatible entry from the live KeepRouter catalog. Set KEEPROUTER_MODEL to that ID and KEEPROUTER_KEY to a KeepRouter key that permits it; paid models also require sufficient credit:

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://keeprouter.com/v1",
    api_key=os.environ["KEEPROUTER_KEY"],
    timeout=30.0,
    max_retries=0,
)

response = client.chat.completions.create(
    model=os.environ["KEEPROUTER_MODEL"],
    messages=[{"role": "user", "content": "Return only the word ready"}],
    max_tokens=64,
)
print(response.choices[0].message.content)

Remove OpenRouter-only extra_body and attribution headers unless a target API explicitly documents an equivalent. Confirm that the selected KeepRouter model supports Chat Completions. Current model availability and prices belong to /models, not this tutorial. The OpenAI SDK base URL guide covers Python and Node troubleshooting on the KeepRouter side.

Before moving paid traffic, use the migration checklist to compare one fixed workload. The API cost calculator estimates usage at current KeepRouter catalog rates; calculate the OpenRouter baseline separately from its own rates and billed usage. Follow the free-to-paid key setup when your existing key only permits free models.

Diagnose common failures

SymptomCheck first
401 or authentication errorEnvironment variable exists, key has no quotes or whitespace, and the request reaches the intended host
404Base URL includes exactly /api/v1 for OpenRouter and the operation path is not duplicated
Model not foundUse a current OpenRouter model slug or a current target-gateway ID; namespaces are not shared
Request works without provider rules but fails with themEligible provider set, data policy, ZDR, maximum price, and fallback constraints
Stream stops after a tool callTool-result continuation, event parsing, model support, and SDK version
Migration compiles but output changesModel revision, route, system prompt, tool schema, sampling settings, and fallback path

Production check

Run a deterministic non-streaming request, then streaming, then one real tool round trip. Record the returned model or route evidence, token usage, error body, and billed amount. Keep retry attempts bounded and do not automatically replay requests that can trigger external side effects.

Frequently asked questions

Is there an official OpenRouter Python SDK?

Yes. The current package is named openrouter and its typed client includes synchronous and asynchronous resources. OpenRouter also documents the OpenAI Python SDK as a separate integration.

What is the OpenRouter base URL for the OpenAI SDK?

Use https://openrouter.ai/api/v1. The OpenAI SDK appends the operation path, such as /chat/completions.

Are HTTP-Referer and X-OpenRouter-Title required?

No. OpenRouter's quickstart marks them as optional attribution headers. Never place an API secret in either value.

Can the native OpenRouter SDK call KeepRouter?

It is not a KeepRouter client contract. Use an OpenAI-compatible client or a route-specific HTTP client and follow KeepRouter's published endpoint for the selected model.

Why does a model work in one gateway but not another?

Catalog namespaces, model revisions, eligible providers, endpoint support, policy filters, and account access are product-specific. Map the exact ID and route instead of copying a slug.

Sources reviewed

Sources last reviewed 2026-09-23

  1. [1] OpenRouter quickstart and client SDK examples
  2. [2] OpenRouter Python SDK
  3. [3] OpenRouter OpenAI SDK integration
  4. [4] OpenRouter provider routing
  5. [5] OpenAI Python SDK
  6. [6] KeepRouter OpenAPI

Related guides

Test the portable path

Start with a bounded OpenAI-shaped chat request, remove product-specific routing fields, map one exact target model, and compare response, usage, errors, and charge.

Create a free key · View live models and pricing · Read as Markdown