OpenRouter Provider Setup and Model Reference for OpenClaw
Learn how to connect OpenClaw to OpenRouter's unified API, covering OAuth and API key onboarding, model selection, and configuration examples.
Read this when
- You want a single API key for many LLMs
- You want to run models via OpenRouter in OpenClaw
- You want to use OpenRouter for image generation
- You want to use OpenRouter for music generation
- You want to use OpenRouter for video generation
OpenRouter exposes a single API and key that fronts a large collection of models. Because it follows OpenAI's conventions, OpenClaw interacts with it using the same openai-completions-style transport applied to other proxy providers.
Getting started
OAuth
Run OAuth onboarding
openclaw onboard --auth-choice openrouter-oauth
OpenRouter's browser-based sign-in flow (PKCE) is launched by OpenClaw, which then trades the authorization code for an OpenRouter API key and saves it to the default OpenRouter auth profile. When running on remote or headless machines, OpenClaw shows the sign-in URL and waits for you to paste the redirect URL once authentication finishes.
(Optional) Switch to a specific model
The onboarding process starts with openrouter/auto as its default. A specific model can be chosen later:
openclaw models set openrouter/<provider>/<model>
API key
Get your API key
Head to openrouter.ai/keys to generate an API key.
Run API-key onboarding
openclaw onboard --auth-choice openrouter-api-key
(Optional) Switch to a specific model
Onboarding sets openrouter/auto as the default. You can select a concrete model afterward:
openclaw models set openrouter/<provider>/<model>
Config example
{
env: { vars: { OPENROUTER_API_KEY: "sk-or-..." } },
agents: {
defaults: {
model: { primary: "openrouter/auto" },
},
},
}
Model references
Note
Model references follow the
openrouter/<provider>/<model>format. Consult /concepts/model-providers for a complete listing of providers and models.
Fallback models bundled for cases where live catalog discovery is unavailable:
| Model ref | Notes |
|---|---|
openrouter/auto | OpenRouter automatic routing |
openrouter/moonshotai/kimi-k2.6 | Kimi K2.6 via MoonshotAI |
openrouter/moonshotai/kimi-k2.5 | Kimi K2.5 via MoonshotAI |
Any other openrouter/<provider>/<model> reference, including openrouter/openrouter/fusion (see Fusion router), is resolved on the fly against OpenRouter's current model catalog.
Image generation
The image_generate tool can be powered by OpenRouter. Configure an OpenRouter image model through agents.defaults.mediaModels.image:
{
env: { vars: { OPENROUTER_API_KEY: "sk-or-..." } },
agents: {
defaults: {
mediaModels: {
image: {
primary: "openrouter/google/gemini-3.1-flash-image-preview",
timeoutMs: 180000,
},
},
},
},
}
Canonical OpenRouter image requests are sent by OpenClaw to the dedicated image endpoint (POST /api/v1/images). Gemini image models also get aspect_ratio and resolution hints, while image edits pass source images along as input_references. Output images arrive base64-encoded (b64_json) with an optional media_type; when media_type is missing, OpenClaw determines the image format by inspecting the bytes.
Custom OpenRouter baseUrl endpoints keep the existing chat-completions image route so proxies lacking the dedicated endpoint remain compatible. Slower models benefit from agents.defaults.mediaModels.image.timeoutMs; the image_generate tool's per-call timeoutMs takes precedence regardless.
Video generation
Through its asynchronous /videos API, OpenRouter can serve as the backend for the video_generate tool. Assign an OpenRouter video model under agents.defaults.mediaModels.video:
{
env: { vars: { OPENROUTER_API_KEY: "sk-or-..." } },
agents: {
defaults: {
mediaModels: {
video: {
primary: "openrouter/google/veo-3.1-fast",
},
},
},
},
}
Text-to-video and image-to-video jobs are submitted by OpenClaw, which then polls the returned polling_url and fetches the completed video from OpenRouter's unsigned_urls or the job content endpoint. Reference images default to first/last-frame images; images marked reference_image are forwarded as input references instead. The bundled google/veo-3.1-fast default handles 4/6/8 second lengths, 720P/1080P resolutions, and 16:9/9:16 aspect ratios. Video-to-video is unsupported, since the upstream API accepts only text and image references.
Music generation
Chat-completions audio output lets OpenRouter back the music_generate tool. Specify an OpenRouter audio model under agents.defaults.mediaModels.music:
{
env: { vars: { OPENROUTER_API_KEY: "sk-or-..." } },
agents: {
defaults: {
mediaModels: {
music: {
primary: "openrouter/google/lyria-3-pro-preview",
timeoutMs: 180000,
},
},
},
},
}
The bundled OpenRouter music provider uses google/lyria-3-pro-preview as its default setting, while google/lyria-3-clip-preview is also made available. OpenClaw transmits modalities: ["text", "audio"], processes the response as a stream, gathers the audio segments, and stores the output as generated media for channel delivery. A single reference image can be supplied to Lyria models through the shared music_generate image=... parameter. Both streaming audio and transcript retention, along with the derived SSE event envelope, are constrained by agents.defaults.mediaMaxMb, with the default audio cap sitting at 16 MB.
Text-to-speech
Through its OpenAI-compatible /audio/speech endpoint, OpenRouter can function as a TTS provider.
{
tts: {
auto: "always",
provider: "openrouter",
providers: {
openrouter: {
model: "hexgrad/kokoro-82m",
speakerVoice: "af_alloy",
responseFormat: "mp3",
},
},
},
}
When tts.providers.openrouter.apiKey is not provided, TTS defaults to models.providers.openrouter.apiKey, and then to OPENROUTER_API_KEY.
Speech-to-text (inbound audio)
Inbound voice and audio attachments can be transcribed by OpenRouter via the shared tools.media.audio path, using its STT endpoint at /audio/transcriptions. This holds for any channel plugin that routes inbound voice or audio into the media understanding preflight stage.
{
tools: {
media: {
models: [
{
provider: "openrouter",
model: "openai/whisper-large-v3-turbo",
capabilities: ["audio"],
},
],
audio: { enabled: true },
},
},
}
OpenRouter STT requests from OpenClaw are sent as JSON carrying base64 audio under input_audio, which is OpenRouter's STT contract, rather than as multipart OpenAI form uploads.
Fusion router
OpenRouter Fusion dispatches a single OpenClaw model ref to multiple OpenRouter models in parallel, has OpenRouter evaluate their responses, and delivers one final answer through the standard OpenRouter endpoint. The upstream model slug is openrouter/fusion, meaning the OpenClaw model ref combines both the OpenClaw provider prefix and the upstream OpenRouter namespace:
openclaw models set openrouter/openrouter/fusion
The model's params.extraBody is where you configure Fusion's panel and judge; those fields pass straight into the OpenRouter chat-completions request body. Fusion supports both OAuth and API-key onboarding, and with OAuth you should omit the env.vars.OPENROUTER_API_KEY line shown below.
{
env: { vars: { OPENROUTER_API_KEY: "sk-or-..." } },
agents: {
defaults: {
model: { primary: "openrouter/openrouter/fusion" },
models: {
"openrouter/openrouter/fusion": {
params: {
extraBody: {
plugins: [
{
id: "fusion",
analysis_models: [
"google/gemini-3.5-flash",
"moonshotai/kimi-k2.6",
"deepseek/deepseek-v4-pro",
],
model: "google/gemini-3.5-flash",
},
],
},
},
},
},
},
},
}
analysis_models designates the parallel panel, while model within the Fusion plugin config identifies the judge model. Avoid setting top-level tool_choice to "required" in regular agent or chat turns to force Fusion: OpenClaw turns may carry their own tool definitions, and a top-level required tool choice could select one of those instead of the Fusion router. When this Fusion plugin config is present, OpenClaw appends a sanitized system-prompt note that lists the configured analysis models and judge model, letting the agent address questions about its own Fusion panel. Other extraBody fields are not carried into the prompt.
Fusion is intentionally slower: OpenRouter spreads the prompt across multiple analysis models, then performs a judge and synthesis step, so latency exceeds that of a direct single-model request. Reserve it for deliberate, high-quality responses or escalation paths, not as a latency-sensitive default. Keep the panel small and choose faster analysis and judge models to shorten response times.
Test a configured ref with a one-shot local call:
openclaw infer model run --local \
--model openrouter/openrouter/fusion \
--prompt "Reply with exactly: FUSION_OK" \
--json
Authentication and headers
A Bearer token derived from your API key is what OpenRouter expects. OpenRouter OAuth follows a PKCE login flow that produces an OpenRouter API key, so OpenClaw stores the outcome in the same openrouter:default API-key auth profile used for manual API-key setup.
To sign in or rotate the stored key on an existing install without rerunning full onboarding:
openclaw models auth login --provider openrouter --method oauth
openclaw models auth login --provider openrouter --method api-key
On verified OpenRouter requests (https://openrouter.ai/api/v1), OpenClaw attaches OpenRouter's documented app-attribution headers:
| Header | Value |
|---|---|
HTTP-Referer | https://openclaw.ai |
X-OpenRouter-Title | OpenClaw |
X-OpenRouter-Categories | cli-agent,cloud-agent,programming-app,creative-writing,writing-assistant,general-chat,personal-agent |
Warning
If you repoint the OpenRouter provider at some other proxy or base URL, OpenClaw does not inject those OpenRouter-specific headers or Anthropic cache markers.
Advanced configuration
Response caching
OpenRouter response caching is something you opt into. Enable it per model:
{
agents: {
defaults: {
models: {
"openrouter/auto": {
params: {
responseCache: true,
responseCacheTtlSeconds: 300,
},
},
},
},
},
}
OpenClaw sends X-OpenRouter-Cache: true and, when configured, X-OpenRouter-Cache-TTL. responseCacheClear: true triggers a refresh for the current request and stores the replacement response. Snake_case aliases (response_cache, response_cache_ttl_seconds, response_cache_clear) are recognized, as are responseCacheTtl / response_cache_ttl without the Seconds suffix.
This operates independently of provider prompt caching and OpenRouter's Anthropic cache_control markers. It applies only on verified openrouter.ai routes, not custom proxy base URLs.
Anthropic cache markers
On verified OpenRouter routes, Anthropic model refs preserve OpenRouter's Anthropic cache_control markers to improve prompt-cache reuse on system and developer prompt blocks.
Anthropic reasoning prefill
On verified OpenRouter routes, Anthropic model refs with reasoning enabled drop trailing assistant prefill turns before the request reaches OpenRouter, aligning with Anthropic's requirement that reasoning conversations conclude with a user turn.
Thinking / reasoning injection
On supported non-auto routes, OpenClaw maps the selected thinking level to OpenRouter proxy reasoning payloads. openrouter/auto and unsupported model hints bypass that injection. Stale openrouter/hunter-alpha refs also bypass it, since OpenRouter could return final answer text in reasoning fields on that retired route.
DeepSeek V4 reasoning replay
For verified OpenRouter routes, openrouter/deepseek/deepseek-v4-flash and openrouter/deepseek/deepseek-v4-pro supply any absent reasoning_content values on replayed assistant turns, which preserves the follow-up format DeepSeek V4 expects for thinking and tool interactions. On such routes, OpenClaw transmits reasoning.effort values that OpenRouter recognizes: xhigh/max correspond to xhigh, while every other non-off level is translated to high.
OpenAI-only request shaping
Because OpenRouter operates through the proxy-style OpenAI-compatible interface, request shaping that is exclusive to native OpenAI, including serviceTier, Responses store, OpenAI reasoning-compat payloads, and prompt-cache hints, is never passed along.
Gemini-backed routes
OpenRouter refs backed by Gemini continue to use the proxy-Gemini path: OpenClaw applies Gemini thought-signature sanitation there, yet native Gemini replay validation and bootstrap rewrites remain disabled.
Provider routing metadata
For routing among underlying providers, OpenRouter accepts a provider request object. To establish a default policy covering every OpenRouter text-model request, use models.providers.openrouter.params.provider:
{
models: {
providers: {
openrouter: {
params: {
provider: {
sort: "latency",
require_parameters: true,
data_collection: "deny",
},
},
},
},
},
}
OpenClaw sends that object to OpenRouter as the request provider payload. Stick to OpenRouter's documented snake_case fields, such as sort, only, ignore, order, allow_fallbacks, require_parameters, data_collection, quantizations, max_price, preferred_max_latency, preferred_min_throughput, zdr, and enforce_distillable_text.
The provider-wide routing object can be overridden by per-model parameters:
{
agents: {
defaults: {
models: {
"openrouter/anthropic/claude-sonnet-4-6": {
params: {
provider: {
order: ["anthropic"],
allow_fallbacks: false,
},
},
},
},
},
},
}
This behavior is limited to OpenRouter chat-completions routes. Direct Anthropic, Google, OpenAI, or custom provider routes disregard OpenRouter routing parameters.
Related
-
Model selection, How providers, model refs, and failover behavior are chosen.
-
Configuration reference, Complete configuration reference covering agents, models, and providers.