POST /v2/models/{provider}/{model}。路由和身份验证在所有模型间保持一致。
探索模型目录
使用与生成时相同的 API 密钥列出模型:id。billing 对象包含的是计费事实,而不是价格。在依赖它之前,请先阅读策略拒绝计费。
分页
- 当
has_more为true时,将返回的next_cursor作为cursor传入。当has_more为false时停止,即使之前的某一页比请求的数量更少。 - 将游标视为不透明值。对值进行 URL 编码,例如使用 cURL
--get --data-urlencode "cursor=$NEXT_CURSOR";不要计算偏移量或修改游标。 limit默认为 20,上限为 100。超过上限的值会被截断;零和负值会选择默认值。响应中会报告实际使用的 limit。- 无效游标会返回
400/invalid_input,而不会静默地重新开始该列表。 - 游标在目录更新后可能仍然有效,但遍历并不是快照:在你当前位置之前新增的模型可能不会出现在该次遍历中。
503 / service_unavailable 是临时性的。请使用退避策略重试;不要将其视为空目录。SDK 的 run 方法会直接调用已选择的模型。
读取单个模型
当你知道模型 ID 时,可以直接获取目录条目:读取输入和输出 schema
每个模型都公开一份独立的 OpenAPI 文档:requestBody 描述输入,而在已编写输出 schema 的情况下,200 响应描述输出。输入验证与输出文档说明是两回事:Router 会依据其输入 schema 进行验证,但不会依据输出 schema 验证返回的提供商结果。
既要检查输出的媒体类型,也要检查其字段。未编写输出 schema 时可能使用 */*,并且有些模型返回的是二进制数据而非 JSON。
缓存 schema
保存该 schema 及其ETag。在之后获取 schema 时,将该 ETag 传入 If-None-Match。304 没有响应体;请保留缓存的文档。200 会提供一份替换文档和新的 ETag。
Cache-Control: private, must-revalidate。请勿将需要身份验证的响应放入共享缓存。此 ETag/304 行为仅适用于 schema 端点。
验证与回退 schema
已编写的输入 schema 会在调用提供商之前,通过422 和 detail[] 数组拒绝无效字段。请读取 loc 中的字段路径;参见验证错误。
某些 schema 接受任意 JSON 对象,并设置 x-comfy-input-schema-authored: false。Router 转发这些请求时不会执行针对模型的验证,因此提供商仍可能拒绝它们。
bfl/flux-2-pro 目前使用此回退方案。请查阅提供商文档或其模型页面,了解必填字段。
读取结果
Router 返回每个模型的最终结果结构。没有通用的图像、视频或文本封装:BFL 图像输出使用result.sample,而其他模型可以返回 URL 列表或内联字节。
部分资产 URL 由 Comfy 重新托管;其他则仍为提供商 URL 或内联字节。查看结果资产,并及时下载即将过期的资产。重放不会续期 URL。
处理错误、重试与计费
防御性地读取错误
失败的请求可能返回代理的 HTML 错误页面、被截断的 JSON 或纯文本。不要让 JSON 解析错误掩盖 HTTP 状态码或请求 ID。以下辅助函数在 Python 中使用httpx.Response,在 TypeScript 中使用 Fetch 的 Response;对于常规的 SDK 调用,SDK 已经暴露了错误字段。
验证错误
Router 的422 表示在调用提供商之前验证失败,且不会计费。其响应体包含一个 detail[] 数组,每个被拒绝的字段对应一个条目。错误类别位于 X-Comfy-Error-Type 中,而不是在响应体里。例如:
422。
400 描述的是请求级别的问题,例如格式错误的游标,而不是这种逐字段的验证响应体。错误参考列出了受支持的分类。在控制流中,将未知类别视为 internal_error,但要保留原始值以便诊断。不要硬性拒绝新的错误值,也不要将预测中的错误类别当作已经出现那样去实现。
安全重试
在发送之前,将密钥与模型 ID 和请求体一起持久化保存。对该逻辑调用的每一次尝试都复用它。Router 不会在响应中向你返回Idempotency-Key。Python SDK 会在抛出的异常中附带该密钥;在 TypeScript 中,你需要自行保存所提供的密钥。
密钥在凭证所携带的工作区内共享;若凭证不携带工作区,则作用域限定为该用户。使用在该作用域内唯一的 UUID,并使用同一凭证重试。复用其他工作区成员的密钥可能会返回他们已记录的结果,或导致冲突;更换凭证则可能启动一次单独的、计费的调用。
超时与收集
Router 会将带密钥的响应或集合状态保留 24 小时;重试不会开启新的保留窗口。一旦该状态过期,就不要指望旧密钥能恢复结果或阻止新的派发。密钥也无法让已过期的资源 URL 重新可用。重试结果
冲突判定会比较方法、模型路径、查询和请求体。在响应过大、响应写入失败,或某个资产无法安全重放之后,键可能变为不可重放。等待无法恢复已被消耗的结果。新键会发起一次新调用,而不会取回旧的输出。
在提供商派发之前的拒绝会释放该键。已派发的调用可能保留提供商句柄,或变为不可重放。不要仅凭状态码推断键的状态或计费情况。
不要仅仅因为调用超时或连接已断开就生成全新的键。如果路由器已经接受了该生成任务,使用新键可能创建第二次逻辑运行,从而产生第二次计费结果。在确认原始调用无法恢复之前,请复用同一个键。
超时与结果收集
一次路由器调用默认最多可保持连接 10 分钟。请将客户端超时设置为高于该上限,这样你拿到的是带类型的504 和请求 ID,而不是一个含义不明的本地中止。
deadline_exceeded 是路由器自身的等待上限;provider_timeout 是提供商的截止时间。即使调用方收到超时或已断开连接,只要提供商的生成任务完成,就可能产生计费。客户端取消会停止等待和 SDK 重试,但不一定会取消已被提供商接受的工作。
对于提交并轮询式提供商,保留的句柄可让使用同一个键的请求继续收集原始生成结果。被派发但在中断时未留下可恢复句柄的调用,可能消耗掉该键却得不到可重放的结果;此时用同一个键重试会返回 409。若提供商归因的瞬时故障并未捕获到成功结果,该键仍可能被释放以进行另一次尝试。仅凭句柄缺失这一事实,无法判断属于哪种结果。
SDK 会在有界预算内重试部分失败。一旦它们返回错误,请保留原请求和键,而不是生成新的。对于原生 HTTP,以下示例只对两种明确的收集提示进行重试:
Retry-After。HTTP 错误会保留响应以供检查;传输层错误会直接向上传播,且不会替换该键。如果你的应用需要更长的恢复窗口,可使用已保存的键安排在稍后收集结果。
模型计费事实
GET /v2/models 和模型详情响应都包含 billing.charges_on_policy_rejection。它描述的是策略拒绝,而不是所有失败情形,也不是价格估算。
请显式比较这些字符串:
"no" 在 Python 和 JavaScript 中都是真值。任何无法识别的值都视为 unknown。因积分不足而被拒绝的请求会报告 insufficient_credits。
提供商返回的载荷可能包含它们自己的成本或用量数字;这些并不是 Comfy 的扣费。X-Comfy-Credits-Used 可能对允许列表中的提供商出现,但它并不通用,也不会被重放。请使用工作区用量和发票进行对账。调查扣费时请保留请求 ID。
各模型示例
- Google Gemini
- Nano Banana 2
- Nano Banana 2 Lite
- Nano Banana Pro
- FLUX 1.1 Pro Ultra
- FLUX Kontext
- FLUX Video Upscale
- FLUX 3 Video
- Ideogram 4