> ## Documentation Index
> Fetch the complete documentation index at: https://dripart-willie-des-1087-router-migration-block.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Comfy Router API 参考

> 每个 Comfy Router 端点、参数、响应体和错误分类，均由 Comfy API 契约生成。

<div className="router-api-reference-marker" />

Comfy Router 的规范路由，以模型 ID 寻址。

基础 URL：`https://api.comfy.org`

以下每个端点都需要身份验证。请发送 `X-API-Key: <api-key>` 或 `Authorization: Bearer <jwt>`。

Comfy API 密钥也可以作为 Bearer token 发送。当同时提供两个凭证请求头时，以 `X-API-Key` 为准。有关 API 密钥与 JWT 的区别，请参阅[身份验证请求头](/zh/development/comfy-router/quickstart)；有关访问要求，请参阅[快速入门](/zh/development/comfy-router/quickstart)。

## 端点

### `GET /v2/models`

**列出 Comfy Router 可以运行的模型。**

列出可用的模型 ID 和计费信息。当 `has_more` 为是时，使用 `next_cursor`。

**参数**

<ParamField query="cursor" type="RouterPageCursor">
  不透明分页游标。

  类型：[`RouterPageCursor`](#routerpagecursor) -- 作为 `next_cursor` 返回的不透明游标，1 至 512 个字符
</ParamField>

<ParamField query="limit" type="integer">
  单页返回的模型数量。

  最大 100，默认值：20
</ParamField>

**响应**

<ResponseField name="200" type="RouterModelListResponse">
  OK - 模型目录的一页。

  响应体：[`RouterModelListResponse`](#routermodellistresponse) -- 响应头：`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="400" type="RouterErrorResponse">
  请求无效。请检查错误类型和请求体。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="401" type="RouterErrorResponse">
  凭据缺失或无效。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="403" type="RouterErrorResponse">
  该调用方或模型不允许此请求。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="503" type="RouterErrorResponse">
  Router 暂时不可用。请使用退避策略重试。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

### `GET /v2/models/{provider}/{model}`

**通过规范模型 ID 读取单个合作伙伴模型的目录条目。**

无需列出完整目录即可读取单个模型的详情。

**参数**

<ParamField path="provider" type="RouterProviderSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的提供商部分。

  类型：[`RouterProviderSegment`](#routerprovidersegment) -- 字母数字 slug，例如 `anthropic`，最多 64 个字符
</ParamField>

<ParamField path="model" type="RouterModelSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的模型部分。

  类型：[`RouterModelSegment`](#routermodelsegment) -- 字母数字 slug，例如 `claude-opus-4-6`，最多 128 个字符
</ParamField>

**响应**

<ResponseField name="200" type="RouterModelDetail">
  OK - 该模型的目录条目。

  响应体：[`RouterModelDetail`](#routermodeldetail) -- 请求头：`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="401" type="RouterErrorResponse">
  凭据缺失或无效。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 请求头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="403" type="RouterErrorResponse">
  该请求对此调用方或模型不被允许。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 请求头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="404" type="RouterErrorResponse">
  未找到该模型 ID。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 请求头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="503" type="RouterErrorResponse">
  Router 暂时不可用。请使用退避策略重试。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 请求头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

### `POST /v2/models/{provider}/{model}`

**通过规范化模型 ID 同步运行合作伙伴模型。**

运行模型并在同一响应中接收其已完成的结果。

**参数**

<ParamField path="provider" type="RouterProviderSegment" required>
  规范化 `{provider}/{model}` 模型 ID 中的提供商部分。

  类型：[`RouterProviderSegment`](#routerprovidersegment) -- 字母数字 slug，例如 `anthropic`，最多 64 个字符
</ParamField>

<ParamField path="model" type="RouterModelSegment" required>
  规范化 `{provider}/{model}` 模型 ID 中的模型部分。

  类型：[`RouterModelSegment`](#routermodelsegment) -- 字母数字 slug，例如 `claude-opus-4-6`，最多 128 个字符
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  由调用方生成的键，用于让同一逻辑调用的重试变得安全。

  1 至 255 个字符
</ParamField>

<ParamField query="model_provider" type="string">
  为此模型选择一个备用提供商，而不是它当前的默认提供商。
</ParamField>

<ParamField query="strict_mode" type="boolean">
  仅在配合 `model_provider` 时才有意义。

  默认：否
</ParamField>

<ParamField query="fallback_provider" type="string">
  控制当首次尝试失败的原因可归因于 Router 自身一侧或所尝试的特定提供商时（绝不可归因于请求本身，未重试的失败会像以往一样被原样拒绝），Router 是否针对该模型的其他已注册提供商重试此调用。
</ParamField>

**请求体**

`application/json` -- [`RouterModelInput`](#routermodelinput)（必填）

合作伙伴模型的原生 JSON 输入。在没有 `model_provider` 时，或在 `strict_mode=true` 时，原样转发给提供商；在 `strict_mode=true` 下，请求体必须已经是备用提供商自己的真实 schema，而不是此模型的原生 schema（参见 `strict_mode`）。当 `model_provider` 选择了备用提供商且 `strict_mode=false`（默认值）时，请求体会在发送前被转换为该提供商的真实 schema；任何无法精确表达的原生字段都会被丢弃，并通过响应的 `X-Comfy-Router-Dropped-Params` 头予以披露，绝不会静默处理。

**响应**

<ResponseField name="200" type="RouterModelOutput">
  OK - 在没有 `model_provider` 时，或在有 `model_provider` 且 `strict_mode=false`（默认值，在可能时转换回此模型的原生契约，转换失败时回退到备用提供商自己的原始响应，会记录日志，绝不静默）时，形状是此模型自己的原生输出；在 `strict_mode=true` 时，则是原样返回的备用提供商的响应。

  Body：[`RouterModelOutput`](#routermodeloutput) -- Headers：`X-Comfy-Request-Id`、`X-Content-Type-Options`、`X-Comfy-Router-Fallback-Provider`、`X-Comfy-Router-Dropped-Params`、`Idempotent-Replayed`、`X-Committed-Spend-Limit`、`X-Committed-Spend-Current`、`X-Committed-Spend-Remaining`
</ResponseField>

<ResponseField name="400" type="RouterErrorResponse">
  无效请求。检查错误类型和请求体。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`X-Comfy-Upstream-Status`、`Idempotent-Replayed`
</ResponseField>

<ResponseField name="401" type="RouterErrorResponse">
  凭证缺失或无效。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="403" type="RouterErrorResponse">
  该调用方或模型不允许发出此请求。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="404" type="RouterErrorResponse">
  未找到该模型 ID。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="409" type="RouterErrorResponse">
  检查 `X-Comfy-Error-Type`：`concurrency_limit_exceeded` 表示原始调用仍在运行，因此请等待 `Retry-After` 并复用同一个键；`invalid_input` 则需要使用新键。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`Retry-After`（当出现 `concurrency_limit_exceeded` 时）
</ResponseField>

<ResponseField name="413" type="RouterErrorResponse">
  请求体过大。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="422" type="RouterValidationErrorResponse">
  请求的内容未通过模型 schema 的校验而被拒绝。

  Body：[`RouterValidationErrorResponse`](#routervalidationerrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`Idempotent-Replayed`
</ResponseField>

<ResponseField name="429" type="RouterErrorResponse">
  检查 `X-Comfy-Error-Type`：`concurrency_limit_exceeded` 表示减少在途调用数；`rate_limited` 表示等待配额窗口。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`X-Committed-Spend-Limit`、`X-Committed-Spend-Current`、`X-Committed-Spend-Remaining`
</ResponseField>

<ResponseField name="502" type="RouterErrorResponse">
  提供商自身的响应无法被转换为结果（`provider_error`）。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`X-Comfy-Upstream-Status`
</ResponseField>

<ResponseField name="503" type="RouterErrorResponse">
  Router 暂时不可用。请以退避策略重试。

  Body：[`RouterErrorResponse`](#routererrorresponse) -- Headers：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="504" type="RouterErrorResponse">
  请求超出了截止时间。重试前请检查错误类型。

  请求体：[`RouterErrorResponse`](#routererrorresponse)；响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`X-Comfy-Upstream-Status`、`Retry-After`
</ResponseField>

### `GET /v2/models/{provider}/{model}/openapi.json`

**以 OpenAPI 文档形式读取某个合作伙伴模型的输入和输出 schema。**

以独立的 OpenAPI 文档形式读取某个模型的输入和输出 schema。

**参数**

<ParamField path="provider" type="RouterProviderSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的提供商部分。

  类型：[`RouterProviderSegment`](#routerprovidersegment) -- 字母数字 slug，例如 `anthropic`，最多 64 个字符
</ParamField>

<ParamField path="model" type="RouterModelSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的模型部分。

  类型：[`RouterModelSegment`](#routermodelsegment) -- 字母数字 slug，例如 `claude-opus-4-6`，最多 128 个字符
</ParamField>

<ParamField header="If-None-Match" type="string">
  调用方从先前的 `200` 响应中持有的 `ETag`。
</ParamField>

**响应**

<ResponseField name="200" type="RouterModelInputSchemaDocument">
  OK - 该模型的输入和输出 schema，以独立的 OpenAPI 文档形式呈现。

  正文：[`RouterModelInputSchemaDocument`](#routermodelinputschemadocument) -- 响应头：`X-Comfy-Request-Id`、`ETag`、`Cache-Control`
</ResponseField>

<ResponseField name="304" type="no body">
  Not Modified - 自调用方在 `If-None-Match` 中发送的 `ETag` 以来，文档未发生更改。

  响应头：`X-Comfy-Request-Id`、`ETag`、`Cache-Control`
</ResponseField>

<ResponseField name="401" type="RouterErrorResponse">
  凭证缺失或无效。

  正文：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="403" type="RouterErrorResponse">
  该调用方或模型无权发起此请求。

  正文：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="404" type="RouterErrorResponse">
  未找到该模型 ID。

  正文：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="500" type="RouterErrorResponse">
  Router 无法完成该请求。

  正文：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="503" type="RouterErrorResponse">
  Router 暂时不可用。请使用退避策略重试。

  正文：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

### `POST /v2/models/{provider}/{model}/requests`

**将合作伙伴模型运行提交到队列并立即返回。**

Comfy Router 的队列投递模式。请求体与该模型的 `POST /v2/models/{provider}/{model}` 所接受的合作伙伴原生 JSON 输入相同：同一套请求体结构，同一份按模型定义的 schema，两种投递模式。但此路由不会为获取结果而保持连接。它会接纳该次运行，返回 `201` 及一个句柄，调用方稍后可通过下面的三种读取操作获取结果。

**参数**

<ParamField path="provider" type="RouterProviderSegment" required>
  规范 `{provider}/{model}` 模型 ID 中小写的提供商片段：即其模型正在被运行的合作伙伴。

  类型：[`RouterProviderSegment`](#routerprovidersegment) -- 字母数字 slug，例如 `anthropic`，最多 64 个字符
</ParamField>

<ParamField path="model" type="RouterModelSegment" required>
  规范 `{provider}/{model}` 模型 ID 中小写的模型片段：即在该提供商内要运行的模型。

  类型：[`RouterModelSegment`](#routermodelsegment) -- 字母数字 slug，例如 `claude-opus-4-6`，最多 128 个字符
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  由调用方生成的键，让重试单次逻辑调用变得安全。

  1–255 个字符
</ParamField>

**请求体**

`application/json` -- [`RouterModelInput`](#routermodelinput)（必填）

合作伙伴模型的原生 JSON 输入，与此模型的同步路由所接受的请求体完全相同。在接纳该次运行之前，会依据模型自身的输入 schema 进行校验，因此模型会拒绝的请求体在这里会得到 `422`，而不是变成几分钟后才失败的已排队请求。

**响应**

<ResponseField name="201" type="RouterQueueSubmitResponse">
  已创建：该次运行已被接纳进入队列。

  响应体：[`RouterQueueSubmitResponse`](#routerqueuesubmitresponse) -- 响应头：`X-Comfy-Request-Id`、`Idempotent-Replayed`
</ResponseField>

<ResponseField name="401" type="RouterErrorResponse">
  凭据缺失或无效。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="400" type="RouterErrorResponse">
  请求无效。请检查错误类型和请求体。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="413" type="RouterErrorResponse">
  请求体过大。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="402" type="RouterErrorResponse">
  Router 请求级失败：请求从未到达模型，或因模型自身未反馈的原因而失败。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="403" type="RouterErrorResponse">
  该请求对于此调用方或此模型不被允许。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="404" type="RouterErrorResponse">
  未找到该模型 ID。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="409" type="RouterErrorResponse">
  请检查 `X-Comfy-Error-Type`：`concurrency_limit_exceeded` 表示原始调用仍在运行，因此请等待 `Retry-After` 并复用同一个键；`invalid_input` 则需要使用新的键。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`Retry-After`（当出现 `concurrency_limit_exceeded` 时）
</ResponseField>

<ResponseField name="422" type="RouterValidationErrorResponse">
  请求的内容未通过模型 schema 的校验。

  响应体：[`RouterValidationErrorResponse`](#routervalidationerrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`Idempotent-Replayed`
</ResponseField>

<ResponseField name="503" type="RouterErrorResponse">
  Router 暂时不可用。请使用退避策略重试。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

### `GET /v2/models/{provider}/{model}/requests/{request_id}`

**采集单个已提交请求的结果。**

采集端点。对于已成功完成的请求，它返回合作伙伴模型自身的原生输出，与同步路由在同一模型、同一输入下 `200` 所返回的内容逐字节一致，因此两种交付方式产生同一种结果形状，调用方无需第二个解析器即可在两者之间切换。

**参数**

<ParamField path="provider" type="RouterProviderSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的小写提供商片段，即正在运行其模型的合作伙伴。

  类型：[`RouterProviderSegment`](#routerprovidersegment) -- 字母数字 slug，例如 `anthropic`，最多 64 个字符
</ParamField>

<ParamField path="model" type="RouterModelSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的小写模型片段，即在该提供商内要运行的模型。

  类型：[`RouterModelSegment`](#routermodelsegment) -- 字母数字 slug，例如 `claude-opus-4-6`，最多 128 个字符
</ParamField>

<ParamField path="request_id" type="RouterQueueRequestId" required>
  要定位的已执行请求，即提交时在响应体中返回的 `request_id`。

  类型：[`RouterQueueRequestId`](#routerqueuerequestid) -- `pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`，uuid，最多 36 个字符
</ParamField>

**响应**

<ResponseField name="200" type="RouterModelOutput">
  OK：对于产生了输出的请求，返回合作伙伴模型的原生输出；无论是成功完成的请求，还是同时带有已记录费用和已存储结果的终端请求，都按合作伙伴自身的媒体类型原样返回，与同步路由的 `200` 返回方式完全一致。

  响应体：[`RouterModelOutput`](#routermodeloutput) -- 响应头：`X-Comfy-Request-Id`、`X-Content-Type-Options`
</ResponseField>

<ResponseField name="202" type="RouterQueueStatusResponse">
  Accepted：请求尚未完成。

  响应体：[`RouterQueueStatusResponse`](#routerqueuestatusresponse) -- 响应头：`X-Comfy-Request-Id`、`Retry-After`
</ResponseField>

<ResponseField name="401" type="RouterErrorResponse">
  凭证缺失或无效。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="403" type="RouterErrorResponse">
  该调用方或模型不允许执行此请求。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="404" type="RouterErrorResponse">
  未找到该模型 ID。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="410" type="RouterErrorResponse">
  Router 请求级失败：请求从未到达模型，或因模型自身未反馈的原因而失败。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="503" type="RouterErrorResponse">
  Router 暂时不可用。请使用退避策略重试。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="409" type="RouterErrorResponse">
  请求处于与操作冲突的状态。请检查错误类型。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="504" type="RouterErrorResponse">
  请求超出了截止时间。重试前请检查错误类型。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="422" type="RouterValidationErrorResponse">
  请求内容未通过模型 schema 的校验。

  响应体：[`RouterValidationErrorResponse`](#routervalidationerrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`、`Idempotent-Replayed`
</ResponseField>

<ResponseField name="default" type="RouterErrorResponse">
  Router 请求级失败：请求从未到达模型，或因模型自身未反馈的原因而失败。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

### `PUT /v2/models/{provider}/{model}/requests/{request_id}/cancel`

**请求取消某个已提交的请求。**

请求 Comfy 停止一个尚未完成的请求。这只是请求，不是保证，`202` 恰恰说明了这一点：`CANCELLATION_REQUESTED` 表示该请求已被接受，而不是运行已停止。已经在合作伙伴侧上线的运行仍可能照常完成；而合作伙伴侧一旦完成生成就会被计费，无论是否有人去取回结果。因此，需要知道实际发生了什么的调用方，应随后读取状态端点：在那里，真正生效的取消是 `COMPLETED`，并像其他所有终端结果一样携带 `error_type`。

**参数**

<ParamField path="provider" type="RouterProviderSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的小写提供商段，即正在运行其模型的合作伙伴。

  Type: [`RouterProviderSegment`](#routerprovidersegment) -- Alphanumeric slug, e.g. `anthropic`, Up to 64 characters
</ParamField>

<ParamField path="model" type="RouterModelSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的小写模型段，即在该提供商内要运行的模型。

  Type: [`RouterModelSegment`](#routermodelsegment) -- Alphanumeric slug, e.g. `claude-opus-4-6`, Up to 128 characters
</ParamField>

<ParamField path="request_id" type="RouterQueueRequestId" required>
  要处理的排队请求，即提交时在响应体中返回的 `request_id`。

  Type: [`RouterQueueRequestId`](#routerqueuerequestid) -- `pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`, uuid, Up to 36 characters
</ParamField>

**响应**

<ResponseField name="202" type="RouterQueueCancelResponse">
  已接受 - `CANCELLATION_REQUESTED`。

  Body: [`RouterQueueCancelResponse`](#routerqueuecancelresponse) -- Headers: `X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="409" type="RouterQueueCancelResponse">
  冲突 - `ALREADY_COMPLETED`。

  Body: [`RouterQueueCancelResponse`](#routerqueuecancelresponse) -- Headers: `X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="400" type="RouterErrorResponse">
  请求无效。请检查错误类型和请求体。

  Body: [`RouterErrorResponse`](#routererrorresponse) -- Headers: `X-Comfy-Error-Type`, `X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="401" type="RouterErrorResponse">
  凭证缺失或无效。

  Body: [`RouterErrorResponse`](#routererrorresponse) -- Headers: `X-Comfy-Error-Type`, `X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="403" type="RouterErrorResponse">
  该调用方或模型无权执行此请求。

  Body: [`RouterErrorResponse`](#routererrorresponse) -- Headers: `X-Comfy-Error-Type`, `X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="404" type="RouterErrorResponse">
  未找到该模型 ID。

  Body: [`RouterErrorResponse`](#routererrorresponse) -- Headers: `X-Comfy-Error-Type`, `X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="503" type="RouterErrorResponse">
  Router 暂时不可用。请使用退避策略重试。

  Body: [`RouterErrorResponse`](#routererrorresponse) -- Headers: `X-Comfy-Error-Type`, `X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="default" type="RouterErrorResponse">
  Router 请求级失败，即请求从未到达模型，或因模型本身未反馈的原因而失败。

  Body: [`RouterErrorResponse`](#routererrorresponse) -- Headers: `X-Comfy-Error-Type`, `X-Comfy-Request-Id`
</ResponseField>

### `GET /v2/models/{provider}/{model}/requests/{request_id}/status`

**读取单个已提交请求的队列状态。**

轮询端点。它返回请求的当前状态，而绝不返回结果，因此客户端可以监视长时间运行的生成过程，而无需在每次轮询时传输其输出。当此端点返回 `COMPLETED` 时，再通过下方的读取操作一次性获取结果。

**参数**

<ParamField path="provider" type="RouterProviderSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的小写提供商片段，即正在运行其模型的合作伙伴。

  类型：[`RouterProviderSegment`](#routerprovidersegment) -- 字母数字 slug，例如 `anthropic`，最多 64 个字符
</ParamField>

<ParamField path="model" type="RouterModelSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的小写模型片段，即要在该提供商内运行的模型。

  类型：[`RouterModelSegment`](#routermodelsegment) -- 字母数字 slug，例如 `claude-opus-4-6`，最多 128 个字符
</ParamField>

<ParamField path="request_id" type="RouterQueueRequestId" required>
  要处理的排队请求，即提交时在其响应体中返回的 `request_id`。

  类型：[`RouterQueueRequestId`](#routerqueuerequestid) -- `pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`，uuid，最多 36 个字符
</ParamField>

**响应**

<ResponseField name="200" type="RouterQueueStatusResponse">
  OK：请求的当前队列状态。

  响应体：[`RouterQueueStatusResponse`](#routerqueuestatusresponse) -- 响应头：`X-Comfy-Request-Id`、`Retry-After`
</ResponseField>

<ResponseField name="401" type="RouterErrorResponse">
  凭据缺失或无效。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="403" type="RouterErrorResponse">
  该请求不被允许用于此调用方或模型。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="404" type="RouterErrorResponse">
  未找到该模型 ID。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="410" type="RouterErrorResponse">
  Router 请求级失败：请求从未到达模型，或因模型本身未反馈的原因而失败。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="503" type="RouterErrorResponse">
  Router 暂时不可用。请使用退避策略重试。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

<ResponseField name="default" type="RouterErrorResponse">
  Router 请求级失败：请求从未到达模型，或因模型本身未反馈的原因而失败。

  响应体：[`RouterErrorResponse`](#routererrorresponse) -- 响应头：`X-Comfy-Error-Type`、`X-Comfy-Request-Id`
</ResponseField>

此处的描述较为简略。有关模型选择、验证、重试和计费，请参阅[使用 Comfy Router API](/zh/development/comfy-router/api)；有关响应头行为，请参阅[响应头](/zh/development/comfy-router/headers)。

## 错误分类桶

Router 错误的机器可读类别，同时也会在 `X-Comfy-Error-Type` 响应头中发送。

### 请求级分类桶

针对 Router 已接受但随后无法完成的请求抛出。

| `error_type`               | 含义                                                                                                                            |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `invalid_input`            | 请求在到达模型之前就被拒绝：请求体格式错误、分页游标格式错误或已过期、模型自身 schema 不接受的输入，或无法用于此请求的 `Idempotency-Key`（已用于其他请求，即方法、路径与查询或请求体不同；或已被某个其响应无法重放的调用消耗）。 |
| `content_policy_violation` | 提供商基于内容政策理由拒绝了请求。                                                                                                             |
| `provider_error`           | 合作伙伴提供商报告了其自身的故障，或返回了 Router 无法解释为结果的响应。                                                                                      |
| `provider_timeout`         | 合作伙伴提供商未在其截止时间内应答。                                                                                                            |
| `insufficient_credits`     | 发起调用的工作区没有足够的积分来运行该模型。                                                                                                        |
| `model_not_found`          | `{provider}/{model}` ID 未指向任何 Router 可运行的模型；未知提供商也归入此类。                                                                       |

### 传输级分类桶

由 Router 自身抛出，发生在调用模型之前或调用过程之中。

| `error_type`                 | 含义                                                      |
| ---------------------------- | ------------------------------------------------------- |
| `unauthorized`               | 请求未携带可用的凭据。                                             |
| `forbidden`                  | 凭据有效，但无权访问此模型或执行此操作。                                    |
| `concurrency_limit_exceeded` | 工作区已在进行中的调用数量已达到允许的上限；等待其中一项调用完成后重试。                    |
| `client_disconnected`        | 在 Router 能够返回结果之前，调用方关闭了连接。                             |
| `internal_error`             | Router 自身失败。                                            |
| `deadline_exceeded`          | 在应答到达之前，Comfy 已在自身配置的时限处停止保持连接。                         |
| `not_enabled`                | Comfy Router 尚未为该调用方启用。                                 |
| `service_unavailable`        | Comfy Router 依赖的某个服务暂时不可用，调用方没有任何过错。                    |
| `rate_limited`               | 调用方已用尽按窗口计量的配额，必须等待该窗口滚动过去。                             |
| `cancelled`                  | 已排队的请求在产生结果之前被撤回（通过取消路由，或由操作员撤回）；它是终态的，且其本身并不代表关于计费的说明。 |
| `queue_timeout`              | 已排队的请求等待超过了其队列超时时间，始终未被准入。                              |
| `request_not_found`          | `request_id` 未指向该调用方在此模型下的任何请求。                         |

## 响应头

<ResponseField name="Cache-Control" type="string">
  所提供架构文档的新鲜度指令。
</ResponseField>

<ResponseField name="ETag" type="string">
  针对所提供文档字节的强实体标签，用于 `GET /v2/models/{provider}/{model}/openapi.json`。
</ResponseField>

<ResponseField name="Idempotent-Replayed" type="boolean">
  当此响应来自某条 `Idempotency-Key` 的记录，而不是通过再次运行模型产生时，该响应头会出现并且值为 `true`。
</ResponseField>

<ResponseField name="Retry-After" type="integer">
  使用同一个 `Idempotency-Key` 重试同一请求之前需要等待的秒数。
</ResponseField>

<ResponseField name="X-Comfy-Error-Type" type="RouterErrorType">
  失败的粗粒度、机器可读分类，由 Router 在每个错误响应上设置。

  类型：[`RouterErrorType`](#routererrortype)
</ResponseField>

<ResponseField name="X-Comfy-Request-Id" type="string">
  服务器为此次调用生成的标识符，存在于每一个 Router 响应中：成功、4xx 和 5xx 响应均如此，因为错误响应恰恰是用户需要在支持请求中引用某个 ID 的时候。
</ResponseField>

<ResponseField name="X-Comfy-Router-Dropped-Params" type="string">
  一个 JSON 编码的字符串，内含一个字符串数组。请使用 JSON 解析器来解码，而不要按逗号对其分割，因为它在传输时是单个字符串，而不是逗号分隔的 OpenAPI 数组，并且每个条目本身就是一个带有逗号的句子。当一次转换生成了本次调用的请求体，却无法在所服务的提供商上精确表达一个或多个原生字段时，该响应头就会出现，并逐一列出每个被丢弃的字段及其原因；无论调用方是通过 `model_provider`（`strict_mode=false`，默认值）请求该转换，还是由自动的 `fallback_provider` 重试执行了该转换，都是如此。
</ResponseField>

<ResponseField name="X-Comfy-Router-Fallback-Provider" type="string">
  仅当 `fallback_provider` 确实针对第二个提供商重试了此调用，并且该重试成功时，该响应头才会出现并指明该提供商：即最终服务此调用的提供商，绝不是被尝试过但也失败了的那个。
</ResponseField>

<ResponseField name="X-Comfy-Upstream-Status" type="integer">
  模型提供商在此次调用中自身的 HTTP 状态。
</ResponseField>

<ResponseField name="X-Committed-Spend-Current" type="integer">
  调用方当前已承诺给仍在途调用的美分数。
</ResponseField>

<ResponseField name="X-Committed-Spend-Limit" type="integer">
  调用方可承诺给仍在途调用的合作伙伴支出上限，单位为美分。这笔资金从调用被接纳的那一刻起即被保留，并在该调用结束时释放。
</ResponseField>

<ResponseField name="X-Committed-Spend-Remaining" type="integer">
  上限之下剩余的可用额度，单位为美分，最低为零。
</ResponseField>

<ResponseField name="X-Content-Type-Options" type="string">
  在 Router 模型的每次成功运行中都始终为 `nosniff`。
</ResponseField>

## 结果资产

模型可以返回资产 URL、内联字节，或两者兼有。下面的提供商会将已选择的资产复制到 Comfy 存储上并替换其 URL。此行为取决于模型；没有任何请求头能选择它。

| 模型                                                | 复制到 Comfy 存储的内容          | Comfy 托管 URL 的最长有效期 |
| ------------------------------------------------- | ------------------------ | ------------------- |
| `bfl/*`                                           | 已完成资产，以及结果中携带的草稿缓存资产（如有） | 24 小时               |
| `byteplus/*` 视频模型（`seedance`、`dreamina-seedance`） | 已完成视频，以及结果中携带的末帧图像（如有）   | 24 小时               |
| `minimax/*`                                       | 已完成视频                    | 12 小时               |
| `xai/*`                                           | 每一张已生成的图像，以及已完成视频        | 24 小时               |

这些有效期从 URL 签名时开始计算，而不是从你打开它时开始。缓存或重放的 URL 可能剩余时间更少；重放不会为其续期。请及时下载资产。只有每一行中列出的资产会被复制：`byteplus/seedream-*` 和 `byteplus/seededit-*` 图像不在 BytePlus 视频行的覆盖范围内。

**Veo（`veo/*`）有单独的存储路径。** 在 `response.videos[]` 中，读取其中存在的成员：`bytesBase64Encoded` 内联包含视频片段，而当环境配置为提供商直接写入 Comfy 存储时，`gcsUri` 包含一个 Comfy 签名的 HTTPS 链接。该链接自响应起 24 小时内有效。后一种情况是直接写入资产而非复制，因此 Veo 不在重新托管表中。

其他模型返回提供商资产引用或内联字节。提供商 URL 遵循提供商的过期时间，这可能比上述有效期短得多，且 Router 契约未对此作出规定。

复制是按资产尽力而为的。如果某个复制失败，该条目会保留其提供商引用；响应可以同时包含 Comfy 和提供商 URL，且没有明确的按资产复制状态字段。生成仍会成功并计费。不要根据一个成功重新托管的资产来推断每个 URL 的有效期。

结果是否由 Comfy 托管也决定了已完成的调用以后是否仍能从其 `Idempotency-Key` 记录中重放；上面的 `Idempotency-Key` 参数说明了无法重放时重试会得到怎样的回应。

<span id="per-model-input-schemas" />

## 各模型的输入和输出架构

通过 `GET /v2/models/{provider}/{model}/openapi.json` 可读取每个模型的字段。该操作的 `requestBody` 描述了输入验证；在已编写的情况下，其 `200` 响应描述了输出形状和媒体类型。当 `x-comfy-input-schema-authored` 为否时，Router 接受任意 JSON 对象，而不进行特定于模型的预验证。提供商依赖项仍然适用。输出架构描述的是结果；Router 不会依据它们验证提供商返回的载荷。未编写的输出可能使用 `*/*` 而非 `application/json`；在解码之前，请检查响应的内容类型。

<h2 id="schemas">
  模式
</h2>

### RouterChargesOnPolicyRejection

内容策略拒绝是否会对此模型收费。将未知值视为可能收费。

类型：`string`

### RouterErrorResponse

认证、访问、模型查找、配额以及提供商传输失败时的错误响应体。

**字段**

<ResponseField name="detail" type="string" required>
  对失败的可读描述，可安全地展示给最终用户。不会被机器解析，请改为根据 `error_type` 进行分支判断。
</ResponseField>

<ResponseField name="error_type" type="RouterErrorType" required>
  Router 失败的粗粒度、机器可读分类，同时会镜像到 `X-Comfy-Error-Type` 响应头中，以便调用方无需解析响应体即可分支处理。该集合固定为十五个值：六个请求级分类 `invalid_input`、`content_policy_violation`、`provider_error`、`provider_timeout`、`insufficient_credits` 和 `model_not_found`，以及传输级分类 `unauthorized`、`forbidden`、`concurrency_limit_exceeded`、`client_disconnected`、`internal_error`、`deadline_exceeded`、`not_enabled`、`service_unavailable` 和 `rate_limited`。

  类型：[`RouterErrorType`](#routererrortype)
</ResponseField>

### RouterErrorType

机器可读的 Router 错误类别，同时也会在 `X-Comfy-Error-Type` 请求头中发送。

类型：`string`

### RouterModelBilling

调用模型之前需要检查的计费行为。它不包含价格或用量信息。

**字段**

<ResponseField name="charges_on_policy_rejection" type="RouterChargesOnPolicyRejection" required>
  模型因内容政策原因而拒绝的调用，是否仍会向调用方收费。各提供商的做法不同，这种差异在调用时不可见，而用户如果同时看到错误和同一调用被收费，也无从知晓其原因。因此这里在调用之前按模型明确说明，而不是留给各提供商的“民间说法”。

  类型：[`RouterChargesOnPolicyRejection`](#routerchargesonpolicyrejection)
</ResponseField>

### RouterModelDetail

单个 Comfy Router 模型的详细信息：目录列表为其报告的全部内容，以及仅单模型路由携带的按模型字段。

组合 [`RouterModelListEntry`](#routermodellistentry)、[`RouterModelDetailFields`](#routermodeldetailfields)。

类型：`object`

### RouterModelDetailFields

模型详情端点返回的可选字段。

**字段**

<ResponseField name="input_schema_url" type="string">
  此模型的 OpenAPI 文档的 URL，包含其输入和输出 schema。

  HTTPS URL，例如 `https://api.comfy.org/v2/models/bfl/flux-2-pro/openapi.json`，最多 2048 个字符
</ResponseField>

### RouterModelId

`POST /v2/models/{provider}/{model}` 中使用的模型 ID。

类型：`string`。模型 ID，例如 `anthropic/claude-opus-4-6`，最多 193 个字符

### RouterModelInput

模型输入对象。请查阅已选择模型的 OpenAPI 文档，了解其字段与验证要求。

类型：`object`

### RouterModelInputSchemaDocument

针对单个模型输入与输出的独立 OpenAPI 文档。

类型：`object`

### RouterModelListEntry

模型的 ID 与计费信息。

**字段**

<ResponseField name="id" type="RouterModelId" required>
  规范的 Comfy Router 模型 ID，格式为 `{provider}/{model}`，正是用于在 `POST /v2/models/{provider}/{model}` 上寻址该模型的值，因此调用方可以直接将它插值到该路径中，而无需从其他来源重新推导。其 `pattern` 由 `RouterProviderSegment` 与 `RouterModelSegment` 通过单个 `/` 连接而成，`maxLength` 为两者之和加上该分隔符。

  类型：[`RouterModelId`](#routermodelid)，模型 ID，例如 `anthropic/claude-opus-4-6`，最多 193 个字符
</ResponseField>

<ResponseField name="provider" type="RouterProviderSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的小写 `provider` 段，即被寻址模型所属的合作伙伴。调用路由的 `provider` 路径参数与目录条目的 `provider` 字段都引用同一个 schema，这正是让列表中的 ID 与可接受的 ID 保持一致、不会发生偏移的原因。

  类型：[`RouterProviderSegment`](#routerprovidersegment)，字母数字 slug，例如 `anthropic`，最多 64 个字符
</ResponseField>

<ResponseField name="model" type="RouterModelSegment" required>
  规范 `{provider}/{model}` 模型 ID 中的小写 `model` 段，即在该提供商下要运行的模型。调用路由的 `model` 路径参数与目录条目的 `model` 字段共享它，原因与 `RouterProviderSegment` 相同，都是为了避免发生偏移。

  类型：[`RouterModelSegment`](#routermodelsegment)，字母数字 slug，例如 `claude-opus-4-6`，最多 128 个字符
</ResponseField>

<ResponseField name="billing" type="RouterModelBilling" required>
  调用方在调用之前需要了解的各模型计费信息，而非价格。使用量和费用数字绝不会出现在这里。

  类型：[`RouterModelBilling`](#routermodelbilling)
</ResponseField>

### RouterModelListResponse

Router 模型目录的一页。

**字段**

<ResponseField name="data" type="array of RouterModelListEntry" required>
  本页的模型，最多 `limit` 个。

  类型：由 [`RouterModelListEntry`](#routermodellistentry) 组成的数组
</ResponseField>

<ResponseField name="has_more" type="boolean" required>
  本页之后是否还存在另一页。只要该值为 true 就继续遍历；不要因为 `data` 较短或为空就推断目录已到末尾。
</ResponseField>

<ResponseField name="next_cursor" type="RouterPageCursor">
  指向 Router 列表的不透明游标。它由服务器生成，并且只能原样往返传递：它不是偏移量，不是模型 ID，没有顺序，也不跨目录重建保持稳定，因此解析它、对它自增，或在其所属的那次遍历之外持久化它，都超出了约定范围。之所以使用游标而不是偏移量，是因为目录是一个不断变化的列表：当遍历过程中有条目被添加或删除时，基于偏移量的遍历会静默跳过或重复条目，而调用方无法察觉这种情况的发生。

  类型：[`RouterPageCursor`](#routerpagecursor)，即作为 `next_cursor` 返回的不透明游标，1–512 个字符
</ResponseField>

<ResponseField name="limit" type="integer" required>
  实际提供的页大小。请求的 `limit` 若超过上限会被钳制到上限，而不是被拒绝，因此该值可能小于请求值。请用这个数字分页，而不是你发送的那个数字，否则你会误以为收到了从未返回的行。

  1–100
</ResponseField>

### RouterModelOutput

模型结果对象。请阅读已选择模型的输出 schema，以了解其确切形状。

类型：`object`

### RouterModelSegment

`{provider}/{model}` 模型 ID 中的模型部分。

类型：`string`。字母数字 slug，例如 `claude-opus-4-6`，最多 128 个字符

### RouterPageCursor

不透明的目录游标。请原样传回作为 `cursor`。

类型：`string` -- 不透明游标，作为 `next_cursor` 返回，1–512 个字符

### RouterProviderSegment

`{provider}/{model}` 模型 ID 中的提供商部分。

类型：`string`，由字母数字组成的 slug，例如 `anthropic`，最多 64 个字符

### RouterQueueCancelResponse

对取消请求的应答，覆盖描述此路由已处理的请求的两种状态：`202` 和 `400`。两者共用一个响应体形状，而不是成功信封加错误信封，因为二者表达的是同一个陈述，即取消操作发现了什么；而一个必须按状态码解析不同类型的客户端，从这种拆分中得不到任何好处。

**字段**

<ResponseField name="request_id" type="RouterQueueRequestId" required>
  单个排队 Router 请求的标识符，即调用方用于轮询、取消和收集结果的句柄。

  类型：[`RouterQueueRequestId`](#routerqueuerequestid)，`pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`、uuid、最多 36 个字符
</ResponseField>

<ResponseField name="status" type="RouterQueueCancelStatus" required>
  取消请求所发现的内容，对应描述此路由实际处理的请求的两种结果。两者都由 HTTP 状态码体现，因此客户端可以基于任一者进行分支。

  类型：[`RouterQueueCancelStatus`](#routerqueuecancelstatus)
</ResponseField>

### RouterQueueCancelStatus

取消请求所查找到的结果，适用于描述此路由实际已解析的请求的两种结果。两者都会由 HTTP 状态码反映，因此客户端可以基于其中任一进行分支判断。

类型：`string`

### RouterQueuePosition

在响应生成的那一刻，队列中有多少个请求排在此请求之前。零表示此请求位于队首。

类型：`integer`，至少为 0

### RouterQueueRequestId

一个排队中的 Router 请求的标识符，即调用方用于轮询、取消并收集结果的句柄。

类型：`string`；`pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`、uuid、最多 36 个字符

### RouterQueueStatus

已执行 Router 请求的状态。它恰好有三个取值，而且与 `RouterErrorType` 不同，这一个确实是封闭的 `enum`，因为这两个 schema 是有意朝相反方向封闭的。`RouterErrorType` 用于对失败进行分类，其取值集合预期会不断增长，因此一个硬性拒绝无法识别类别的已生成客户端，恰恰会在已经出错的时候失败得最为严重。而这一项描述的是生命周期，日后若新增第四种状态，对每一个针对它编写的轮询循环而言都是破坏性变更，无论它是否被声明为 enum。因此它被声明为 enum，并且把这一约束写在了客户端能够看到的地方。

类型：`string`

### RouterQueueStatusFields

`RouterQueueStatusResponse` 中不属于 URL 块的那一半：一个排队请求的身份标识、它当前的状态，以及（当该状态为终端且运行未成功时）说明原因的粗粒度分类桶。

**字段**

<ResponseField name="request_id" type="RouterQueueRequestId" required>
  标识一个排队的 Router 请求，也就是调用方用于轮询、取消并获取结果的句柄。

  类型：[`RouterQueueRequestId`](#routerqueuerequestid) -- `pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`、uuid、最多 36 个字符
</ResponseField>

<ResponseField name="status" type="RouterQueueStatus" required>
  排队中的 Router 请求的状态。它恰好有三个取值，而且与 `RouterErrorType` 不同，它确实是一个封闭的 `enum`，因为这两个 schema 是有意朝相反方向封闭的。`RouterErrorType` 用于对失败进行分类，其取值集合预期会增长，因此一个会硬性拒绝无法识别分类桶的生成客户端，恰恰会在已经出错的时候失败得最严重。而这个是生命周期，日后为其新增第四个状态，对所有针对它编写的轮询循环来说都是破坏性变更，无论它是否被声明为 enum 都是如此；所以就把它声明为 enum，并把这一约束写在客户端能看到的地方。

  类型：[`RouterQueueStatus`](#routerqueuestatus)
</ResponseField>

<ResponseField name="queue_position" type="RouterQueuePosition">
  在响应被组合出来的那一刻，队列中排在该请求之前的请求数量。为零表示该请求位于队首。

  类型：[`RouterQueuePosition`](#routerqueueposition) -- 至少 0
</ResponseField>

<ResponseField name="error_type" type="RouterErrorType">
  仅出现在未成功的 `COMPLETED` 请求上，携带的是与结果读取在返回该失败时放在 `X-Comfy-Error-Type` 上的同一个粗粒度分类桶。它用于区分成功的终端请求与失败或被取消的终端请求：这两种情况都没有单独的终端状态。成功时它是缺失的，而不是 null，因此请依据其是否存在来分支判断。

  类型：[`RouterErrorType`](#routererrortype)
</ResponseField>

### RouterQueueStatusResponse

单个排队中请求的当前状态，由提交时返回的同样三个 URL 组合而成。

组合了 [`RouterQueueUrls`](#routerqueueurls) 和 [`RouterQueueStatusFields`](#routerqueuestatusfields)。

类型：`object`

### RouterQueueSubmitFields

`RouterQueueSubmitResponse` 中不属于 URL 块的那一半：新请求的身份标识，以及它被接纳那一刻的状态。

**字段**

<ResponseField name="request_id" type="RouterQueueRequestId" required>
  一个已排队的 Router 请求的标识符：调用方据此轮询、取消并获取结果的句柄。

  类型：[`RouterQueueRequestId`](#routerqueuerequestid) -- `pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`，uuid，最多 36 个字符
</ResponseField>

<ResponseField name="status" type="RouterQueueStatus" required>
  已排队的 Router 请求的状态。它恰好有三个取值，而且与 `RouterErrorType` 不同，这个确实是封闭的 `enum`，因为这两个 schema 是有意朝相反方向封闭的。`RouterErrorType` 用于对失败进行分类，其取值集合预计会增长，因此，如果生成的客户端硬性拒绝一个无法识别的分类，那么它恰恰会在已经出错的时候失败得最严重。而这个描述的是生命周期，对一个生命周期而言，日后新增第四种状态，对所有针对它编写的轮询循环来说都是破坏性变更，无论它是否被声明为 enum 都一样。所以这里将其声明为 enum，并把该约束写在客户端能看到的地方。

  类型：[`RouterQueueStatus`](#routerqueuestatus)
</ResponseField>

<ResponseField name="queue_position" type="RouterQueuePosition">
  在响应生成的那一刻，队列中排在此请求前面的请求数量。零表示此请求位于最前面。

  类型：[`RouterQueuePosition`](#routerqueueposition) -- 至少为 0
</ResponseField>

### RouterQueueSubmitResponse

当一次运行被准入队列时返回的句柄：包含请求的身份与状态，并组合了用于访问其生命周期其余部分的三个 URL。

组合了 [`RouterQueueUrls`](#routerqueueurls)、[`RouterQueueSubmitFields`](#routerqueuesubmitfields)。

类型：`object`

### RouterQueueUrls

用于处理某个已排队请求生命周期其余部分的三个 URL。每个携带活动句柄的响应都会返回这三个 URL，因此客户端永远不需要自行拼接队列 URL。

**字段**

<ResponseField name="status_url" type="string" required>
  读取此请求状态的绝对 URL。

  URI
</ResponseField>

<ResponseField name="response_url" type="string" required>
  收集此请求结果的绝对 URL。

  URI
</ResponseField>

<ResponseField name="cancel_url" type="string" required>
  请求取消此请求的绝对 URL。

  URI
</ResponseField>

### RouterValidationErrorContext

提供商提供的、关于未通过的验证规则的详情。

类型：`object`

### RouterValidationErrorDetail

单个字段级验证失败。

**字段**

<ResponseField name="loc" type="array of any" required>
  出错字段的路径，最外层片段在前。例如 `["body", "image_url"]`，或 `["body", "images", 0]`，其中整数表示数组中的索引。
</ResponseField>

<ResponseField name="msg" type="string" required>
  对这一单个失败的人类可读描述。
</ResponseField>

<ResponseField name="type" type="string" required>
  该失败具体且机器可读的原因，由提供商原样透传。类型化 SDK 异常层级正是依据此值进行分支判断；响应头中的 `error_type` 只是它粗粒度的归类。
</ResponseField>

<ResponseField name="ctx" type="RouterValidationErrorContext">
  单个 `RouterValidationErrorDetail` 所违反的界限，由提供商逐字携带。例如 `{"limit_value": 8}` 搭配 `greater_than`，`{"min_width": 512}` 搭配 `image_too_small`，或 `{"max_size_bytes": 10485760}` 搭配 `file_too_large`。其键集合特定于提供商与错误类型，因此这里刻意保持为开放对象：将其收窄为固定字段列表，或把它并入 `msg` 字符串，正是移植集成后能够编译通过、却悄无声息地丢失读取该界限分支的原因。当错误类型不携带界限时此项缺省。

  类型：[`RouterValidationErrorContext`](#routervalidationerrorcontext)
</ResponseField>

<ResponseField name="input" type="RouterValidationErrorInput">
  出错的输入值，原样回显，让调用方无需从 `loc` 重新推导就能看到被拒绝的内容。可为任意 JSON 类型：字符串、数字、布尔、数组、对象或 null，因此该 schema 刻意不做类型约束，而不是收窄为对象。当提供商不回显输入时此项缺省。

  类型：[`RouterValidationErrorInput`](#routervalidationerrorinput)
</ResponseField>

### RouterValidationErrorInput

当提供商包含该值时，即为被拒绝的输入值。

### RouterValidationErrorResponse

`422` 验证错误响应体。读取 `X-Comfy-Error-Type` 以了解其类别。

**字段**

<ResponseField name="detail" type="array of RouterValidationErrorDetail" required>
  请求中发现的每一处验证失败，每个出错的字段对应一个条目。

  类型：[`RouterValidationErrorDetail`](#routervalidationerrordetail) 数组
</ResponseField>
