n8n 接自定义 API:Base URL 就在凭据里,测试通过也会 404
n8n 的 OpenAI 凭据从 1.73.0 起就有 Base URL 这一栏,官方文档至今没写。实测 2.36.9:凭据测试只打 /models,节点默认打 /responses。
n8n 的 OpenAI 凭据里有 Base URL 这一栏,从 n8n@1.73.0 起就有,只是官方文档到今天也没写。 填上 https://api.ofox.io/v1,内置的 OpenAI 节点、AI Agent、模型下拉全都能直接指向你自己的网关,不用退回 HTTP Request 节点手写请求体。

真正会咬人的不是这一栏找不找得到,是它填对了、凭据测试也是绿的,工作流照样 404。下面那一段是本文的重点,我在一个真实实例上把两种情况各跑了一遍。
本文所有运行结果来自 2026-09-01 在 Docker 里起的 n8n 2.36.9 实例,模型端点指向一个会记录请求路径的本地服务,因此每一次请求打在哪个 URL 上都是原始记录,不是推断。
n8n 到底能不能填自定义 Base URL?
能,而且这一栏已经存在快两年了。
一手证据有四条,从产品往回追到代码:
| 证据 | 内容 |
|---|---|
| 官方 PR #12175 | 《refactor: Move OpenAI Base URL option to credentials》,2024-12-17 合并 |
| 首个含它的版本 | n8n@1.73.0(该合并提交领先于 1.72.0、落后于 1.73.0) |
| 官方对功能请求的回复 | issue #14431 请求为 Novita 等加 base URL,n8n 成员回「This is already possible」并附截图关闭 |
| 凭据源码 | OpenAiApi.credentials.ts 里 displayName: 'Base URL'、name: 'url'、默认值 https://api.openai.com/v1 |
PR 的描述写得很直白,它做的是搬家不是新增:
Removes the Base URL parameters from the OpenAI nodes and uses the new Base URL parameters in the OpenAI credentials.
也就是说这个能力更早就存在于节点选项里,1.73.0 只是把它挪到了凭据里,并且做了版本兼容让老节点继续读节点上的那份。
我从跑着的实例里把凭据定义原样导出,字段清单是这样:
| 字段 | 类型 | 默认值 |
|---|---|---|
| API Key | string(密码) | 空 |
| Organization ID (optional) | string | 空 |
| Base URL | string | https://api.openai.com/v1 |
| Add Custom Header | boolean | false |
| Header Name / Header Value | string | 空 |
顺带一个连社区都很少提的:这套凭据还能加一对自定义请求头。需要给网关带 X-Title、路由标签或者自家鉴权头的,不用为此绕去 HTTP Request 节点。
为什么满世界都说 n8n 不能填?
因为文档确实没写,而且不是漏了一句,是整栏都没有。
我不想凭一两个页面下结论,所以把 n8n 的全文档索引拉下来搜过一遍:
| 检索项 | 结果 |
|---|---|
| 文档索引条目数 | 1,339 |
| 「base url」在索引里命中 | 2 次,同一个页面的标题与描述各一次 |
| 那个页面讲的是什么 | n8n 自己前后端 REST API 的地址,与模型端点无关 |
| 凭据文档源文件里「base url」命中 | 0 次 |
凭据文档页列出的要求,到今天仍然只有两项:
An API Key
An Organization ID: Required if you belong to multiple organizations; otherwise, leave this blank.
有意思的是,n8n 并不是不会写这一栏。同一个文档仓库里,Ollama、Milvus、Chroma、NVIDIA 的凭据页都老老实实写了 Base URL,NVIDIA 那页甚至直接把它描述成「the OpenAI-spec compatible endpoint to call」,还提醒你路径要带 /v1。所以这不是产品理念问题,是这一页漏了。
漏在哪一步,PR 自己留了痕迹。#12175 的评审清单里,「PR title and summary are descriptive」打了勾,而下面这一项没打:
- Docs updated or follow-up ticket created.
这个没打勾的复选框,就是后面将近两年混乱的全部来源。
这篇文章的初稿就是栽在这里的。 我把上面这份检索当成了结论,写成「n8n 不支持自定义端点,得换 HTTP Request 节点」。检索本身没问题——1,339、2 次、0 次都复现得了——错的是从「文档没有」推出「产品没有」。判断一个功能不存在,光查文档不够,还得查 issue tracker、release notes 和社区,因为文档滞后于产品是常态——n8n 这次从 2024-12-17 合并那天算到今天是 623 天,快两年了,凭据文档一个字没动。
对你的实际影响是:遇到「n8n 不能接第三方端点」的说法,先去凭据弹窗里看一眼再信,包括本文发布之后可能又变过的部分。
凭据测试是绿的,工作流为什么还是 404?
因为这两件事打的根本不是同一个端点。
凭据测试在源码里就一行,它只发一次 GET {Base URL}/models:
| 路径 | 实际请求 |
|---|---|
| 凭据测试 | GET {Base URL}/models |
| 运行时(默认) | POST {Base URL}/responses |
| 运行时(关掉开关) | POST {Base URL}/chat/completions |
原因是 OpenAI Chat Model 子节点里有个叫 Use Responses API 的开关,源码里写着 default: true,且只在 @version >= 1.3 时出现。换句话说,你新拖出来的节点,默认走的是 Responses 端点。
而文档在这一点上写反了。 节点文档写的是:
Toggle to Use Responses API if you want the model to generate output using the Responses API. Otherwise, the OpenAI Chat Model node will default to using the Chat Completions API.
按这句话,不动开关就该走 Chat Completions。实测不是。我用同一套凭据、同一个工作流跑了两遍,只改这一个开关,服务端收到的请求是:
| 实验 | Use Responses API | 服务端收到 | 结果 |
|---|---|---|---|
| A | true(默认) | POST /v1/responses | 404 |
| B | false | POST /v1/chat/completions | 成功 |
而凭据测试在两种情况下都是绿的——它打的是 /v1/models,那个端点一直都在。
最难受的是报错本身会误导人。执行记录里那条错误除了 404,还挂着一个 LangChain 的排障链接,归类是 MODEL_NOT_FOUND:
Troubleshooting URL:
https://docs.langchain.com/oss/javascript/langchain/errors/MODEL_NOT_FOUND/
模型没找到——于是你会去改模型名、去核对模型是否上架、去怀疑网关目录。而问题跟模型无关,是那个端点整个不存在。 这也是为什么这个坑值得单独写一节:它的表征把人引向了完全错误的方向。
处理办法很简单,先关掉 Use Responses API 让工作流跑通,再回头判断你的模型支不支持 Responses。
有多少模型支持 chat/completions 却不支持 responses?
拿我们自己的目录做个量:
| 端点 | 支持的模型条目 |
|---|---|
/v1/chat/completions | 111 |
/v1/responses | 75 |
| 两者同时支持 | 72 |
| 列出端点的条目总数 | 138 |
支持聊天端点的 111 条里,有 39 条不吃 Responses。 这个比例放在别的网关上只会更高,Responses 是相对新的端点,实现进度参差。
所以这个开关的正确用法是:先去模型页看端点那一栏,确认支持再打开;只是想跑通,就让它关着。Responses 能换来的是一次请求里跑多轮内置工具、以及用 conversation_id 做持久会话,代价是端点兼容面窄得多。
还有一条同类的:文档写明内置工具(Web Search、File Search、Code Interpreter)只在 OpenAI Chat Model 配 AI Agent 节点时可用,配 Basic LLM Chain 就没有。把 Agent 换成 Chain 图省事,会静默丢掉一批能力。
那个绿勾到底验证了什么?
验证了你的 Base URL 能连通,不一定验证了你的 key 是对的。
n8n 的测试确实会看状态码——我拿一个瞎编的 key 去测 api.openai.com,返回的是 Error: Unauthorized,拦住了。但它拦不拦得住,取决于你的网关保不保护模型列表:
| 端点 | 无鉴权直接请求 /models | 无效 key 能测出绿勾吗 |
|---|---|---|
| api.ofox.ai | 200 | 能 |
| openrouter.ai | 200 | 能 |
| api.openai.com | 401 | 不能 |
| api.deepseek.com | 401 | 不能 |
| api.z.ai | 401 | 不能 |
这一条对我们自己不利,但你该在接入前知道: api.ofox.ai/v1/models 是公开端点,不带任何鉴权头也返回 200 和完整模型目录。好处是模型下拉在配 key 之前就能用;代价是 n8n 那个绿勾在我们这里完全不能用来验证 API Key。你把 key 打错一个字符,凭据页照样绿,然后在第一次真实调用时才报 401。
所以那个绿勾的正确读法是:它说明地址填对了,不说明这条路能跑通。 真要确认,跑一次工作流。
同一个 Base URL,n8n 有几个地方在读?
三个地方,各读各的——这是理解前面所有现象的底层原因。
| 代码路径 | 怎么用你填的 URL |
|---|---|
| 凭据测试 | 原样当 baseURL,拼 /models |
| 模型下拉 | 按 / 切开,去掉最后一段当 baseURL,再拿最后一段拼 /models |
| 运行时 | 原样交给 OpenAI SDK,由它拼 /responses 或 /chat/completions |
中间那条最反直觉,它对你填的 URL 形状是有假设的:默认值 https://api.openai.com/v1 结尾有一个版本段,切分逻辑正是按这个形状写的。
社区里流传「Base URL 结尾不要带斜杠」,我在 2.36.9 上专门测了:没能复现。 带斜杠时凭据测试仍然打到 /v1/models 并通过,运行时仍然打到 /v1/chat/completions 并成功,没有出现双斜杠。这条建议在当前版本上更像是历史遗留,不是必须遵守的规则——但它的由来是真的,那套字符串切分确实对 URL 形状敏感。稳妥的做法是照着默认值的形状填:协议 + 域名 + 一个版本段,比如 https://api.ofox.io/v1。
子节点里的表达式为什么只认第一条?
这条跟端点无关,但它是 n8n 里最花钱的一个坑,而且文档专门写了一节。
普通节点会对每一条输入分别求值:五个 name 进去,{{ $json.name }} 依次解析成五个不同的值。但子节点不是这样,OpenAI Chat Model 自己的 Common Issues 页原文是:
In sub-nodes, the expression always resolves to the first item.
而 OpenAI Chat Model 正是子节点。所以你在循环里给它传动态提示词时,实际发出去的是同一个提示词跑五遍——结果全是重复的,账单一次不少。这类错误不会报错,只会让你在月底看着用量发呆。
这也是定时工作流的通病:聊天应用是人点一次跑一次,写臃肿了用的人当场就嫌慢;定时触发没有这个反馈回路,跑错了也按点跑。所以两件事比选哪个模型更值得先做——先算单次触发的 token 量再乘触发频率,以及把节点选项里的 Maximum Number of Tokens 和 Timeout 填上别留空。Max Retries 同理,重试是要付钱的,失败调用在多数供应商那里照样计费,这一项的口径我们在AI 视频 API 一秒多少钱里单独算过。
什么时候还是该用 HTTP Request 节点?
当你要的东西超出了 OpenAI 协议本身的时候。
凭据里能填 Base URL 之后,HTTP Request 从主路降级成兜底,但它没有失去价值。《Custom API actions for existing nodes》那页写着,内置节点没覆盖的操作「You can work around this by making a custom API call using the HTTP Request node」,并且可以在 Authentication 里选 Predefined Credential Type 复用已建好的凭据,不用另做一套认证。
三条路现在是这样分工的:
| 路径 | 什么时候用 | 代价 |
|---|---|---|
| OpenAI 凭据填 Base URL | 走 OpenAI 协议的绝大多数情况 | 受节点支持的参数集限制 |
| HTTP Request 节点 | 要用节点没暴露的字段,或非 OpenAI 协议 | 请求体自己写,模型下拉和 Agent 挂载都用不上 |
| n8n Cloud Gateway credits | 只想在 Cloud 上先跑通 | 账单落在 n8n 积分上,自建实例没有 |
Gateway credits 那条值得单说一句,顺带也是本文主题的又一个例子:同一件事,两个文档页写得不一样。OpenAI Chat Model 节点页说的是在 n8n Cloud 上可以「use the OpenAI Chat Model node with Gateway credits instead of your own OpenAI API key」,选上 Use Gateway credits 就能「run the node without an OpenAI account」;凭据页则写成「skip setting up OpenAI credentials by selecting Use Gateway credits in the credential field of nodes that support it」。这跟 ComfyUI 的合作节点是同一种设计——平台替你垫付调用,代价是账单落在平台的积分体系里,不落在你自己的模型账户上。方便程度和可控程度永远是一组反向的东西。
同一件事在别的工具上的配法:Dify 有现成的 OpenAI-API-compatible 供应商可选,步骤在Dify 接入 ofox API 完全指南;Coze 侧写在Coze(扣子)怎么配置第三方 API;自建网关和商业网关怎么选在企业级 LLM Gateway 选型。
这套配置该怎么落地?
- 凭据里填 Base URL,形状照着默认值来:
https://api.ofox.io/v1。需要额外请求头就打开 Add Custom Header。 - 别信那个绿勾。它只证明地址通,在模型列表公开的网关上连 key 对不对都不验。
- 新建节点先把 Use Responses API 关掉。它默认开着,而运行时打的
/responses是兼容面最窄的端点;等工作流跑通了,再对着模型页决定要不要打开。 - 看到 MODEL_NOT_FOUND 先查端点,别先查模型名。这个归类会把你带偏。
- 循环里给子节点传动态提示词之前,先读一遍那条「只认第一条」。它不报错,只多花钱。
反过来说清楚:如果你的工作流只调 OpenAI 官方、也不打算换模型,本文这套对你没有价值,默认配置就是最舒服的一条路,别为了统一而统一。
n8n 文档页支持在 URL 后加 .md 取 Markdown 原文,上面每一条文档引文都可以这样自行复核。运行结果来自 2026-09-01 的 n8n 2.36.9,版本行为会变,落地前以你自己实例上跑出来的那一次为准。
参考信息来源
- n8n PR #12175:Move OpenAI Base URL option to credentials
- n8n issue #14431:官方回复「This is already possible」
- n8n 源码:OpenAiApi.credentials.ts
- n8n 源码:LmChatOpenAi.node.ts
- n8n:OpenAI credentials 文档
- n8n:OpenAI Chat Model 节点参数
- n8n:OpenAI Chat Model Common Issues(子节点表达式那条)
- n8n:NVIDIA 凭据文档,同一仓库里写了 Base URL 的那页
- n8n:Custom API actions for existing nodes
- Ofox 模型与端点清单 llms-full.txt
常见问题
- n8n 的 OpenAI 节点能填自定义 Base URL 吗
- 能。OpenAI 凭据里有一栏就叫 Base URL,默认值 https://api.openai.com/v1,改成 https://api.ofox.io/v1 即可。这一栏是 n8n 官方 PR #12175《refactor: Move OpenAI Base URL option to credentials》加的,2024-12-17 合并,首个包含它的版本是 n8n@1.73.0。混淆的来源是官方凭据文档至今只写 API Key 和 Organization ID,没有提这一栏——但字段确实在产品里,我在 n8n 2.36.9 上截了图。
- 为什么凭据测试是绿的,工作流一跑还是 404
- 因为两者打的不是同一个端点。凭据测试只发一次 GET {Base URL}/models;而 OpenAI Chat Model 子节点在 typeVersion 1.3 上有个「Use Responses API」开关,默认值是 true,运行时打的是 POST {Base URL}/responses。节点文档在这里写反了,它说不动开关就默认走 Chat Completions;我在 n8n 2.36.9 上实测的是相反的:同一套凭据,开关默认开着时请求落在 /v1/responses 并 404,把开关关掉后落在 /v1/chat/completions 并成功。更麻烦的是这个 404 被 LangChain 归类成 MODEL_NOT_FOUND,会把你引去查模型名,而问题根本不在模型。
- n8n 凭据测试通过能说明 API Key 是对的吗
- 不一定,取决于你的网关保不保护 /models。n8n 的测试就是拿你的 key 发一次 GET {Base URL}/models,它确实会看状态码——我拿一个无效 key 测 api.openai.com,返回的是 Error: Unauthorized。但很多网关的模型列表是公开的:实测无鉴权直接请求,ofox.ai 和 OpenRouter 都返回 200,OpenAI、DeepSeek、Z.ai 都是 401。也就是说在前两家上,无效 key 照样能测出绿勾。
- 支持 chat/completions 却不支持 responses 的模型有多少
- 以 Ofox 目录为例,138 条列出端点的模型里,111 条支持 /v1/chat/completions,75 条支持 /v1/responses,两者都支持的是 72 条。也就是说支持聊天端点的 111 条里有 39 条不吃 Responses。n8n 的 Use Responses API 默认开着,模型又落在这 39 条里,工作流就会在运行时报错——而且定时触发的话是半夜报。
- Base URL 结尾能不能带斜杠
- 在 n8n 2.36.9 上实测两条路径都不受影响:带斜杠时凭据测试仍打到 /v1/models 并通过,运行时仍打到 /v1/chat/completions 并成功,没有出现双斜杠。社区里流传的「结尾不要带斜杠」我没能在当前版本上复现,但它有源码上的由来——模型下拉那条路径会对 URL 做字符串切分,按最后一段拼 /models,写法确实对 URL 形状敏感。稳妥起见按默认值的形状填,即协议加域名加一个版本段。


