Most n8n automations stall when a single task needs different LLMs for different substeps. To connect n8n to n4n.ai multi-model workflow, point n8n’s HTTP Request node at the OpenAI-compatible endpoint and pass the model name per request—no dedicated n8n integration needed. You get 240+ models behind one credential and a uniform request shape.
Step 1: Provision credentials and base URL
Generate an API key from your gateway account. The base URL is a single OpenAI-compatible endpoint; export it as BASE_URL in your shell or n8n environment variables. Store the key in n8n as a generic HTTP Header Auth credential named Authorization with value Bearer <key>.
Test connectivity before touching n8n:
curl $BASE_URL/v1/models \
-H "Authorization: Bearer $N4N_API_KEY" | head -c 200
A JSON array of model ids confirms the credential works. In n8n, create the credential once and reuse it across every model node. This avoids scattering secrets across workflows.
Step 2: Scaffold the workflow with a manual trigger
Start a blank workflow. Add a Manual Trigger node. Immediately after, add an HTTP Request node named Call Model A.
Configure the node:
- Method:
POST - URL:
{{ $env.BASE_URL }}/v1/chat/completions - Authentication: select the header credential from Step 1
- Send Body: true
- Body Content Type: JSON
- Body (JSON tab):
{
"model": "openai/gpt-4o-mini",
"messages": [
{ "role": "user", "content": "Summarize: {{ $json.inputText }}" }
],
"max_tokens": 256
}
The {{ $json.inputText }} expression pulls from whatever upstream node you later attach. Keep the payload minimal; the gateway forwards unknown fields but some models ignore them.
Step 3: Parameterize the model per node
A multi-model flow means different nodes call different models. Duplicate Call Model A, rename to Call Model B, and swap the model field:
{
"model": "anthropic/claude-3.5-sonnet",
"messages": [
{ "role": "user", "content": "Extract entities: {{ $json.inputText }}" }
],
"max_tokens": 512
}
Because the endpoint speaks the OpenAI chat format, n8n treats both calls identically. You avoid branching auth logic or maintaining separate base URLs. If you later need a dynamic model, replace the literal with {{ $vars.modelName }} and set the variable at workflow runtime.
Step 4: Pass routing directives and cache hints
When you need to pin a provider or exploit prompt caching, add route and cache to the body. The gateway honors client routing directives and forwards provider cache-control hints, so you can force a specific backend or set TTL without custom headers:
{
"model": "meta-llama/llama-3.1-70b-instruct",
"messages": [{ "role": "user", "content": "{{ $json.inputText }}" }],
"route": { "provider": "groq" },
"cache": { "ttl": 300 }
}
n8n sends this verbatim. No extra node config. This is the cleanest way to control cost and latency from inside the workflow logic.
Step 5: Merge outputs and branch on results
Add a Merge node (mode: append) after both model calls. Then add an IF node to validate responses:
// IF node condition (n8n expression)
{{ $json.choices[0].message.content.length > 0 }}
If you want a third model as arbiter, chain another HTTP Request node with model: "google/gemini-1.5-pro" and feed both prior outputs into its messages array. Use a Code node to assemble the conversation:
const a = $items("Call Model A")[0].json.choices[0].message.content;
const b = $items("Call Model B")[0].json.choices[0].message.content;
return [{ json: { messages: [
{ role: "user", content: `A says: ${a}\nB says: ${b}\nReconcile.` }
]}}];
This pattern scales to any number of models without changing the transport.
Step 6: Handle rate limits and fallback
Providers throttle. n4n.ai automatically falls back when a provider is rate-limited or degraded, so you can skip custom retry loops for model unavailability. Still, configure n8n node retries for transport errors:
- Settings → Retry On Fail: true
- Max Tries: 2
- Wait Between Tries: 2000ms
If the gateway returns HTTP 200 with finish_reason: "error", parse it downstream and route to an alert. Do not assume non-200 is the only failure mode.
Step 7: Meter usage and track cost
The response includes a usage object. Capture it:
{
"usage": {
"prompt_tokens": 42,
"completion_tokens": 17,
"total_tokens": 59
}
}
Map {{ $json.usage.total_tokens }} to a Google Sheet or Postgres node. In a high-volume workflow, write these rows asynchronously with a separate branch to avoid blocking the main path.
Step 8: Verify the workflow end-to-end
Trigger the manual execution with a sample inputText from a Set node. Expect two model responses merged. Check the execution log: each HTTP node should show 200, and the Merge node should output an array of two items.
Add a verification Code node after Merge:
const items = $input.all();
if (items.length !== 2) throw new Error("expected 2 model outputs");
for (const i of items) {
if (!i.json.choices?.[0]?.message?.content) throw new Error("empty completion");
}
return items;
If it passes, you have a working connect n8n to n4n.ai multi-model workflow. From here, swap models via workflow variables, add a Switch node to pick models by input type, or parallelize calls with a Loop node.
Caveats
n8n expressions can break JSON if you concatenate unescaped strings. Use {{ JSON.stringify($json.text) }} inside message content when needed. The OpenAI-compatible surface does not support every provider-specific extension; test a new model id with curl $BASE_URL/v1/chat/completions before wiring it into n8n. Keep credentials in n8n’s vault, not in node bodies.