OpenRouter
LLM inference with 300+ models via OpenRouter.
A single AI node that talks to GPT, Claude, Gemini, and 300+ other models through OpenRouter. You bring one API key, pick a model from the dropdown (or type any model ID), and reference the result downstream as {aiResponse.data}.
Quick start
- Add an OpenRouter API key under Credentials.
- Drop an AI node onto the canvas, pick the credential, choose a model.
- Write a prompt - e.g.
Summarize this token: {json birdeyeResponse.data}. - Wire the next node to read
{aiResponse.data}.
That's the whole loop. Everything below is detail for when you need it.
Prerequisites
- OpenRouter API key (get one here)
- Add it as a credential in Credentials
Operations
| Operation | Description |
|---|---|
| Chat completion | Send a prompt, get a response |
Input modes
| Mode | When to use |
|---|---|
| Prompt | Default. Write a natural language prompt with template expressions like {birdeyeResponse.data.value}. |
| JSON Request | When you need multi-turn messages, a developer role, or multimodal content parts. Send an OpenAI-compatible chat-completions body - see JSON Request mode. |
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| OpenRouter API Key | select | Yes | Your OpenRouter credential from Connections. |
| Response Name | text | Yes | The variable name downstream nodes use to reference this node's output. Defaults to aiResponse, so you read the reply as {aiResponse.data}. Rename it if you have multiple AI nodes in one workflow. |
| model | searchable select | Yes | Pick from loaded OpenRouter models or type a full model ID. Defaults to gpt-5-mini if left blank in non-strict execution. |
| prompt | string | Yes (prompt mode) | User message. Supports template expressions. |
| requestJson | string | Yes (JSON mode) | OpenAI-compatible JSON body - see JSON Request mode. |
| systemPrompt | string | No | System instructions. Also templated - undefined paths fail the same way as in prompt. |
| temperature | number | No | 0–2, controls randomness. |
| maxTokens | number | No | Maximum response length. |
| responseFormat | string | No | text (default) or json_object. See Response format. |
Select an OpenRouter credential first to load the live model list. You can also type a full model ID manually (e.g. openai/gpt-5-mini) if it doesn't appear in the suggestions.
The user prompt is hard-capped at 200,000 characters. Anything longer is truncated with a marker ([Prompt truncated by Solaris to stay within model context limits]) before the call goes out.
Advanced parameters
| Field | Type | Description |
|---|---|---|
| topP | number | Nucleus sampling threshold. Range (0, 1] (0 is invalid; values above 1 are clamped to 1). |
| frequencyPenalty | number | Penalize repeated tokens. Range -2 to 2. |
| presencePenalty | number | Penalize tokens already present. Range -2 to 2. |
| stop | string | Comma-separated stop sequences. Up to 4 (extras are dropped). |
| seed | number | Deterministic output seed (model-dependent). Must be an integer. |
Reasoning
Some models support extended reasoning. When enabled, the model may return additional reasoning metadata alongside the reply.
| Field | Type | Description |
|---|---|---|
| reasoningEnabled | boolean | Enable extended thinking. |
| reasoningEffort | string | xhigh, high, medium, low, minimal, or none. Roughly: xhigh ≈ 95% of token budget on reasoning, high ≈ 80%, medium ≈ 50%, low ≈ 20%, minimal ≈ 10%. |
Reasoning is model-dependent. Claude 4.6 uses adaptive thinking automatically (the effort setting is ignored). Models that don't support reasoning will reject the call.
JSON Request mode
When inputMode is json, the body must be an object with an OpenAI-compatible messages[] array. This is the only shape the runtime forwards to OpenRouter.
Static JSON is checked in the editor before the workflow runs. If the JSON contains template expressions, the final shape is checked after those templates render at runtime. Legacy provider formats such as Gemini contents[] or Anthropic top-level system are rejected when the rendered request is parsed.
{
"messages": [
{ "role": "system", "content": "You are a concise assistant." },
{ "role": "user", "content": "Summarize: {json birdeyeResponse.data}" }
]
}role must be one of system, user, assistant, developer. content is a non-empty string, or an OpenAI-format content-parts array ([{ "type": "text", "text": "..." }, { "type": "image_url", "image_url": { "url": "..." } }]) for multimodal models.
The body may also set:
| Field | Effect |
|---|---|
temperature | Overrides the node-level temperature. |
max_tokens (or maxOutputTokens) | Overrides the node-level maxTokens. Capped at 128,000. |
All other fields in the body are ignored - advanced parameters (topP, frequencyPenalty, etc.) and responseFormat come from node settings, not the JSON body. Set them in the editor's Advanced parameters panel or Response format toggle.
Template expressions inside requestJson are resolved before the body is parsed as JSON, so a path like {json codeResponse.data} interpolates a JSON value at that position. Undefined paths fail loudly with AI JSON input uses undefined variables: <path> instead of producing invalid JSON or empty substitutions.
Response format
The responseFormat setting controls how the model's reply lands in the output envelope. It must agree with what your prompt asks for - instructing the model to respond in JSON without flipping this toggle leaves .data as a string that downstream nodes can't traverse with field paths.
| Value | Behavior |
|---|---|
text (default) | The reply is returned verbatim. .data is a string. Use {aiResponse.data} to drop it into a downstream prompt or HTTP body. |
json_object | OpenRouter is asked for structured output and the reply is JSON.parsed before it lands in the envelope. .data is a parsed object you can address with field paths like {json aiResponse.data.summary}. If the model returns invalid JSON, the node fails with a clear error. |
Some models don't support structured outputs and will fail when json_object is set - pick a model that does, or fall back to text and parse downstream.
Output
In text mode (default):
{
"success": true,
"data": "The current price of SOL is approximately $150.",
"model": "openai/gpt-5-mini",
"usage": { "promptTokens": 42, "completionTokens": 18 }
}In json_object mode:
{
"success": true,
"data": { "price": 150, "asset": "SOL", "confidence": "high" },
"model": "openai/gpt-5-mini",
"usage": { "promptTokens": 42, "completionTokens": 18 }
}Reasoning models may add a reasoning field when reasoning is enabled.
Reference patterns:
{aiResponse.data}- the model's reply as a string. Intextmode this is the raw model output. Injson_objectmode.datais an object, so without thejsonprefix the template substitutes[object Object](string coercion). Use{json aiResponse.data}instead when.datais an object.{aiResponse.data.field}- a scalar field (string / number / boolean) from ajson_objectreply, dropped in unquoted. The right shape for prompts and most string fields in HTTP query strings.{json aiResponse.data.field}- the same field JSON-encoded (strings get quotes, objects/arrays get JSON syntax). Use this when interpolating into JSON HTTP bodies, or when the field itself is an object or array.{json aiResponse}- the full response envelope, useful for HTTP bodies or debugging.
Template variables
The system prompt, prompt, and JSON-input fields all support template expressions like {json codeResponse.data.field}. Two things to know:
- Use the variable picker (the
{ }button next to any text field). It walks upstream nodes and suggests valid paths, including nested field paths once the workflow has run once. Before the first run, it falls back to a static schema for known node types so you still get useful suggestions. - Undefined paths fail loudly. If a path doesn't resolve (typo, wrong nesting, upstream node didn't emit that field), the node fails before calling the model - checked across all three template fields (
systemPrompt,prompt,requestJson) so a single failure surfaces every offending path at once. The error message mentions the offending path:Prompt template uses undefined variables: <path>in prompt mode (covers system prompt + prompt),AI JSON input uses undefined variables: <path>in JSON Request mode (covers system prompt + JSON body). This is the most common cause of "I don't see any data" replies - fix the path instead of debugging the model. A path that resolves tonull(e.g.,balanceResponse.minton a SOL balance) is treated as a present value, not a missing one.
Common use cases
- Analyze on-chain data and generate trading signals
- Summarize token metrics into human-readable alerts
- Parse unstructured data into structured JSON with
json_objectresponse format - Use reasoning models for complex multi-step analysis
Next steps
- Jupiter - connect AI to on-chain swaps
- Configuring Nodes - template expressions for dynamic prompts
