* docs: simplify getting started, installation, and provider setup docs * docs(install): preserve installer step anchors
19 KiB
summary, read_when, title
| summary | read_when | title | |||||
|---|---|---|---|---|---|---|---|
| Use OpenRouter's unified API to access many models in OpenClaw |
|
OpenRouter |
OpenRouter routes requests to many models behind one API and one key. It is
OpenAI-compatible, so OpenClaw talks to it over the same
openai-completions-style transport used for other proxy providers.
Getting started
In a private chat, send /login openrouter or select OpenRouter from /login.
Choose Sign in with OpenRouter, approve access in your browser, and return
to chat. OpenClaw receives the browser callback and saves the credential before
reporting success. Use /login cancel to cancel a pending sign-in.
Login saves access without choosing a starter model. If current model restrictions hide OpenRouter models, choose Show all OpenRouter models or Keep current restrictions. The credential stays saved either way. In the Control UI, use Settings → Models → Connect for the same credential-only flow, then use the model menu to choose a model from the Gateway's catalog.
Chat browser sign-in uses the Gateway's managed Tailscale HTTPS address. With Tailscale Serve, your browser must have access to the same tailnet. If no managed HTTPS address is available, enable Serve and retry, or use the CLI flow below. The callback does not sign you in to the Control UI.
The Control UI receives the return automatically at the managed HTTPS address or when opened directly on the local Gateway's loopback address and port. Other addresses use manual redirect completion. If pasted input is incomplete or invalid, correct it in the same sign-in attempt and submit again.
```bash openclaw onboard --auth-choice openrouter-oauth ``` OpenClaw opens OpenRouter's browser sign-in flow (PKCE), exchanges the
code for an OpenRouter API key, and stores it in the default
OpenRouter auth profile. On remote/headless hosts, OpenClaw prints the
sign-in URL and asks you to paste the redirect URL after signing in.
</Step>
<Step title="(Optional) Switch to a specific model">
Onboarding defaults to `openrouter/auto`. Pick a concrete model later:
```bash
openclaw models set openrouter/<provider>/<model>
```
</Step>
</Steps>
```bash
openclaw models set openrouter/<provider>/<model>
```
</Step>
</Steps>
Config example
{
env: { vars: { OPENROUTER_API_KEY: "sk-or-..." } },
agents: {
defaults: {
model: { primary: "openrouter/auto" },
},
},
}
Model references
Model refs follow the pattern `openrouter//`. For the full list of providers and models OpenRouter routes to, see [OpenRouter's model catalog](https://openrouter.ai/models). For how OpenClaw resolves model refs and failover, see [Model selection](/concepts/model-providers).Bundled starter models enrich a nonempty public catalog. A failed live request reports a discovery failure rather than substituting these rows; a successful empty response stays empty:
| 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> ref, including
openrouter/openrouter/fusion (see Fusion router), resolves
dynamically against OpenRouter's live model catalog.
Discovered models use OpenRouter's advertised tool support. When a model's
supported_parameters list omits tools, OpenClaw sends requests without tool
definitions or tool choice. Models without that metadata keep the default tool
behavior.
Image generation
OpenRouter can back the image_generate tool. Set an OpenRouter image model
under 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,
},
},
},
},
}
OpenClaw sends standard OpenRouter image requests to the dedicated image API
(POST /api/v1/images). Gemini image models additionally receive
aspect_ratio and resolution hints, and image edits pass source images as
input_references. Generated images come back as base64 (b64_json) with an
optional media_type; when media_type is absent, OpenClaw sniffs the image
format from the bytes.
Configured custom OpenRouter baseUrl destinations retain the existing
chat-completions image route for compatibility with proxies that do not expose
the dedicated endpoint. Use agents.defaults.mediaModels.image.timeoutMs for
slower models; the image_generate tool's per-call timeoutMs still wins.
Video generation
OpenRouter can back the video_generate tool through its asynchronous
/videos API. Set 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",
},
},
},
},
}
OpenClaw submits text-to-video and image-to-video jobs, polls the returned
polling_url, and downloads the finished video from OpenRouter's
unsigned_urls or the job content endpoint. Reference images default to
first/last-frame images; images tagged reference_image are sent as input
references instead. The bundled google/veo-3.1-fast default supports 4/6/8
second durations, 720P/1080P resolutions, and 16:9/9:16 aspect ratios.
Video-to-video is not supported: the upstream API only accepts text and image
references.
Music generation
OpenRouter can back the music_generate tool through chat-completions audio
output. Set 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 defaults to google/lyria-3-pro-preview
and also exposes google/lyria-3-clip-preview. OpenClaw sends modalities: ["text", "audio"], streams the response, collects the audio chunks, and saves
the result as generated media for channel delivery. Lyria models accept one
reference image through the shared music_generate image=... parameter.
Streaming audio, transcript retention, and the derived SSE event envelope are
bounded by agents.defaults.mediaMaxMb (the default audio cap is 16 MB).
Text-to-speech
OpenRouter can act as a TTS provider through its OpenAI-compatible
/audio/speech endpoint.
{
tts: {
auto: "always",
provider: "openrouter",
providers: {
openrouter: {
model: "hexgrad/kokoro-82m",
speakerVoice: "af_alloy",
responseFormat: "mp3",
},
},
},
}
If tts.providers.openrouter.apiKey is omitted, TTS falls back to
models.providers.openrouter.apiKey, then OPENROUTER_API_KEY.
Speech-to-text (inbound audio)
OpenRouter can transcribe inbound voice/audio attachments through the shared
tools.media.audio path, using its STT endpoint (/audio/transcriptions).
This applies to any channel plugin that forwards inbound voice/audio into
media understanding preflight.
{
tools: {
media: {
models: [
{
provider: "openrouter",
model: "openai/whisper-large-v3-turbo",
capabilities: ["audio"],
},
],
audio: { enabled: true },
},
},
}
OpenClaw sends OpenRouter STT requests as JSON with base64 audio under
input_audio (OpenRouter's STT contract), not as multipart OpenAI form
uploads.
Fusion router
OpenRouter Fusion sends one OpenClaw model ref to several OpenRouter models in
parallel, has OpenRouter judge their answers, and returns one final response
through the normal OpenRouter endpoint. The upstream model slug is
openrouter/fusion, so the OpenClaw model ref carries both the OpenClaw
provider prefix and the upstream OpenRouter namespace:
openclaw models set openrouter/openrouter/fusion
Configure Fusion's panel and judge through the model's params.extraBody;
those fields forward directly into the OpenRouter chat-completions request
body. Fusion works with either OAuth or API-key onboarding; if you use OAuth,
omit the env.vars.OPENROUTER_API_KEY line 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 is the parallel panel; model inside the Fusion plugin
config is the judge model. Do not set top-level tool_choice to "required"
in normal agent/chat turns to try to force Fusion: OpenClaw turns can include
its own tool definitions, and a top-level required tool choice may pick one of
those instead of the Fusion router. When this Fusion plugin config is present,
OpenClaw adds a sanitized system-prompt note listing the configured analysis
models and judge model, so the agent can answer questions about its own Fusion
panel. Other extraBody fields are not copied into the prompt.
Fusion is slower by design: OpenRouter fans the prompt out to multiple analysis models, then runs a judge/synthesis step, so latency runs higher than a direct single-model request. Use it for deliberate, high-quality answers or escalation paths, not as a latency-sensitive default. Keep the panel small and pick faster analysis/judge models for quicker responses.
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
OpenRouter uses a Bearer token from your API key. OpenRouter OAuth is a PKCE
login flow that issues an OpenRouter API key, so OpenClaw stores the result in
the same openrouter:default API-key auth profile used by 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 requests to OpenRouter endpoints (openrouter.ai), OpenClaw adds OpenRouter's
documented app-attribution headers. This applies to the bundled openrouter
provider and to custom provider ids whose baseUrl points at OpenRouter:
| Header | Value |
|---|---|
HTTP-Referer |
https://openclaw.ai |
X-OpenRouter-Title |
OpenClaw |
X-OpenRouter-Categories |
personal-agent,cli-agent |
Advanced configuration
OpenRouter response caching is opt-in. Enable it per model:```json5
{
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` forces a refresh for
the current request and stores the replacement response. Snake_case
aliases (`response_cache`, `response_cache_ttl_seconds`,
`response_cache_clear`) are accepted, as is `responseCacheTtl` /
`response_cache_ttl` without the `Seconds` suffix.
TTL values are truncated and clamped to 1–86400 seconds; non-finite values are ignored.
This is separate from provider prompt caching and from OpenRouter's
Anthropic `cache_control` markers. It only applies on verified
`openrouter.ai` routes, not custom proxy base URLs.
Models without an effort selector show on/off controls, or **always on**
when reasoning is mandatory. These models receive binary reasoning controls
without a scalar effort. Omitting a thinking request leaves their native
reasoning default unchanged; configured reasoning budgets are preserved.
```json5
{
models: {
providers: {
openrouter: {
params: {
provider: {
sort: "latency",
require_parameters: true,
data_collection: "deny",
},
},
},
},
},
}
```
OpenClaw forwards that object to OpenRouter as the request `provider`
payload. Use OpenRouter's documented snake_case fields, including `sort`,
`only`, `ignore`, `order`, `allow_fallbacks`, `require_parameters`,
`data_collection`, `quantizations`, `max_price`, `preferred_max_latency`,
`preferred_min_throughput`, `zdr`, and `enforce_distillable_text`.
Per-model params override the provider-wide routing object:
```json5
{
agents: {
defaults: {
models: {
"openrouter/anthropic/claude-sonnet-4-6": {
params: {
provider: {
order: ["anthropic"],
allow_fallbacks: false,
},
},
},
},
},
},
}
```
This only applies on OpenRouter chat-completions routes. Direct Anthropic,
Google, OpenAI, or custom provider routes ignore OpenRouter routing params.