n8n with an OpenAI-compatible endpoint
n8n runs AI inside workflows: a trigger fires, a node calls a model, the result branches onward. Its OpenAI nodes accept a custom base URL on the credential, so one credential puts every model the endpoint exposes into every workflow. This page covers the credential, the single toggle that quietly sends requests to the wrong path, and why workflow costs are driven by execution count rather than request size.
Set the base URL on the credential, not the node
The base URL lives on the credential, not on individual nodes. Create an OpenAI API credential, set your key, then expand the additional fields and set the base URL — ending in /v1. Every OpenAI node that uses this credential inherits it, which means changing endpoints later is one credential edit rather than a tour of every workflow.
n8n validates the credential by calling GET /v1/models, so the model list you see is what your key can actually reach rather than a hardcoded catalogue.
# n8n validates the credential with this exact call. Run it yourself
# to see which model IDs your key can actually reach.
curl "$GATEWAY_BASE_URL/models" \
-H "Authorization: Bearer $GATEWAY_API_KEY"
Turn off Use Responses API
This is the setting that costs people the most time. On an OpenAI Chat Model sub-node there is a Use Responses API toggle. When it is on, the node posts to /v1/responses; when off, it posts to /v1/chat/completions. OpenAI-compatible endpoints generally implement chat completions, so leaving this on produces failures that look like model errors but are path errors.
Set it explicitly rather than relying on the default — the default has changed between n8n versions.
When to use the HTTP Request node instead
The OpenAI nodes are convenient, but they expose only the fields n8n chose to surface. The HTTP Request node gives you the full request body, which is what you want for low-temperature classification, for max_tokens caps on bulk jobs, or for any parameter the node does not expose.
{
"model": "deepseek-v4-flash",
"messages": [
{ "role": "system", "content": "Classify the ticket. Reply with one word." },
{ "role": "user", "content": "={{ $json.ticket_body }}" }
],
"temperature": 0,
"max_tokens": 16
}
Two reasons this matters for cost. A classification job does not need a long answer, and capping max_tokens at sixteen turns an open-ended generation into a bounded one. It also does not need creativity, and temperature: 0 makes repeated runs reproducible — which is worth a lot when a workflow runs unattended.
Workflow cost is execution count, not request size
Individual workflow requests are small: a few thousand input tokens, a few hundred output. What makes them expensive is that they run unattended, on a schedule, hundreds or thousands of times. The variable to control is the number of executions and the cost of each, not the sophistication of any single call.
| Model | Vendor | Rate in / out per 1M | Per run | Per month |
|---|---|---|---|---|
| gpt-5.6-luna | OpenAI | $0.1 / $0.6 | $0.0009 | $8 |
| MiniMax-M3 | MiniMax | $0.15 / $0.6 | $0.0011 | $10 |
| deepseek-v4-flash | DeepSeek | $0.22 / $0.66 | $0.0015 | $13 |
| gemini-3.7-flash | $0.375 / $1.875 | $0.0032 | $29 | |
| claude-haiku-4-5-20251001 | Anthropic | $0.5 / $2.5 | $0.0043 | $38 |
| deepseek-v4-pro | DeepSeek | $0.66 / $1.98 | $0.0044 | $40 |
| glm-5.3 | Zhipu | $0.7 / $2.2 | $0.0048 | $43 |
| qwen3.8-max | Alibaba | $1 / $3 | $0.0067 | $60 |
| claude-sonnet-5 | Anthropic | $1 / $5 | $0.0085 | $77 |
| gpt-5.6-terra | OpenAI | $1 / $6 | $0.0094 | $85 |
| kimi-k3 | Moonshot | $1.5 / $7.5 | $0.0128 | $115 |
| claude-opus-5 | Anthropic | $2.5 / $12.5 | $0.0212 | $191 |
How this fails in practice
| What you see | What it usually is | Fix |
|---|---|---|
| Requests hit /v1/responses | Use Responses API left enabled on the chat model sub-node | Turn it off so the node posts to /v1/chat/completions |
| Credential validation fails | Base URL not ending in /v1, or /v1/models rejects the key | Confirm the URL and query /v1/models with the same key |
| Model list empty | The key cannot reach any model on that endpoint | Check what the endpoint exposes; enter the ID manually if the dropdown does not populate |
| 404 from the endpoint | Base URL missing /v1 | Set the credential base URL to a URL ending in /v1 |
| Cannot reach a host service | n8n runs in Docker; localhost is the container | Use host.docker.internal, or the host gateway address on Linux |
| Costs climb with no traffic change | A retry loop, or a trigger firing more often than intended | Check execution history before changing models; cap retries |
https://aicomp.ai/v1).
Create one free →
FAQ
Where do I set the base URL in n8n?
On the credential, not the node. Create an OpenAI API credential, set your key, then expand the additional fields and set the base URL. Every node using that credential inherits it.
Why do my requests go to /v1/responses?
Because Use Responses API is enabled on the chat model sub-node. Turn it off to use /v1/chat/completions, which is what OpenAI-compatible endpoints generally implement.
Should I use the OpenAI node or the HTTP Request node?
The OpenAI node for convenience; HTTP Request when you need the full request body — temperature, max_tokens, or a parameter the node does not expose. Bulk classification usually wants the latter.
Does the base URL need /v1?
Yes. n8n validates the credential against GET /v1/models and appends the rest of the request path itself.
Can n8n reach a model running on the same host?
Not via localhost if n8n runs in Docker — that resolves to the container. Use host.docker.internal on Docker Desktop, or the host gateway address on Linux.
How do I keep workflow costs down?
Cap max_tokens, set temperature to zero for classification, and watch execution counts. In automation the multiplier is how often it runs, not how big each request is.