> ## Documentation Index
> Fetch the complete documentation index at: https://docs.comfy.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 通过 Comfy Router 使用 Kling 4.0

> 通过 Comfy Router 调用 kling/kling-4.0：端点、请求形状以及 Router 返回的响应。

`kling/kling-4.0` 的 API 参考，由 Comfy Router 从 Kling 提供。

**输入：** 文本 · **输出：** 视频

## 快速开始

在[你的 Comfy 工作区](https://platform.comfy.org/profile/api-keys?onboarding=router)中创建密钥，并将其导出为 `COMFY_API_KEY`。Python 和 TypeScript 代码片段使用 Comfy SDK（`pip install comfy-sdk` 和 `npm install @comfyorg/sdk`）；cURL 代码片段则是通过原生 HTTP 发起的同一调用。

**模型 ID：** `kling/kling-4.0`

**端点：** `POST https://api.comfy.org/v2/models/kling/kling-4.0`

> [tab] 等待结果
>
> ```python Python theme={null}
> from comfy_sdk import Comfy
>
> # 从环境变量读取 COMFY_API_KEY。
> # SDK 会自动创建幂等键，并在自动重试时复用它。
> with Comfy() as client:
>     result = client.models.run(
>         "kling/kling-4.0",
>         {
>             "contents": [
>                 {
>                     "text": "The fox turns toward the camera.",
>                     "type": "prompt",
>                 },
>                 {
>                     "type": "first_frame",
>                     "url": "https://example.com/fox.png",
>                 },
>             ],
>             "settings": {
>                 "duration": 3,
>                 "resolution": "720p",
>             },
>         },
>     )
>
> print(result)
> ```
>
> ```typescript TypeScript theme={null}
> import { comfy } from "@comfyorg/sdk";
>
> // 从环境变量读取 COMFY_API_KEY。
> // SDK 会自动创建幂等键，并在自动重试时复用它。
> const { data } = await comfy.models.run("kling/kling-4.0", {
>   contents: [
>     {
>       text: "The fox turns toward the camera.",
>       type: "prompt",
>     },
>     {
>       type: "first_frame",
>       url: "https://example.com/fox.png",
>     },
>   ],
>   settings: {
>     duration: 3,
>     resolution: "720p",
>   },
> });
>
> console.log(data);
> ```
>
> ```bash cURL theme={null}
> curl https://api.comfy.org/v2/models/kling/kling-4.0 \
>   -H "X-API-Key: $COMFY_API_KEY" \
>   -H "Idempotency-Key: $(uuidgen)" \
>   -H "Content-Type: application/json" \
>   -d "{\"contents\": [{\"text\":\"The fox turns toward the camera.\",\"type\":\"prompt\"},{\"type\":\"first_frame\",\"url\":\"https://example.com/fox.png\"}], \"settings\": {\"duration\":3,\"resolution\":\"720p\"}}"
> ```

> [tab] 排队并稍后收集
>
> 同一个请求体，发送到 `POST https://api.comfy.org/v2/models/kling/kling-4.0/requests`。只要运行被接纳，Router 就会返回 `201` 和 `request_id`，结果准备就绪后即可收集，无论是在本进程还是另一个进程中。[队列交付](https://docs.comfy.org/zh/development/comfy-router/queue.md) 介绍了状态、取消和收集的流程。
>
> ```python Python theme={null}
> import asyncio
> from comfy_sdk import AsyncComfy
>
> # 从环境变量读取 COMFY_API_KEY。
> # 每次 submit() 调用都会生成自己的 Idempotency-Key，并在自动重试时复用它。
> async def main():
>     async with AsyncComfy() as client:
>         handle = await client.models.submit(
>             "kling/kling-4.0",
>             {
>                 "contents": [
>                     {
>                         "text": "The fox turns toward the camera.",
>                         "type": "prompt",
>                     },
>                     {
>                         "type": "first_frame",
>                         "url": "https://example.com/fox.png",
>                     },
>                 ],
>                 "settings": {
>                     "duration": 3,
>                     "resolution": "720p",
>                 },
>             },
>         )
>         print("request_id:", handle.request_id)  # 加上模型 ID，就是另一个进程所需的全部信息
>
>         # 轮询直到请求完成，按服务器给出的 Retry-After 等待。
>         async for update in handle.iter_events():
>             print(update.status, update.queue_position)
>
>         # 提供商自己的负载，与 models.run() 返回的值相同。
>         # 失败或已取消的请求会在此处抛出带类型的 Router 错误。
>         result = await handle.get()
>
>     print(result)
>
> asyncio.run(main())
> ```
>
> ```typescript TypeScript theme={null}
> import { comfy } from "@comfyorg/sdk";
>
> // 从环境变量读取 COMFY_API_KEY。
> // 每次 submit() 调用都会生成自己的 Idempotency-Key，并在自动重试时复用它。
> const handle = await comfy.models.submit("kling/kling-4.0", {
>   contents: [
>     {
>       text: "The fox turns toward the camera.",
>       type: "prompt",
>     },
>     {
>       type: "first_frame",
>       url: "https://example.com/fox.png",
>     },
>   ],
>   settings: {
>     duration: 3,
>     resolution: "720p",
>   },
> });
> console.log("requestId:", handle.requestId); // 加上模型 ID，就是另一个进程所需的全部信息
>
> // 轮询直到请求完成，按服务器给出的 Retry-After 等待。
> for await (const update of handle.events()) {
>   console.log(update.status, update.queuePosition);
> }
>
> // 与 models.run() 返回的结果相同。失败或已取消的请求会在此处被拒绝。
> const result = await handle.get();
>
> console.log(result.data);
> ```
>
> ```bash cURL theme={null}
> # 1. 提交。Router 返回 201，并带有 request_id、status_url、response_url 和 cancel_url。
> curl https://api.comfy.org/v2/models/kling/kling-4.0/requests \
>   -H "X-API-Key: $COMFY_API_KEY" \
>   -H "Idempotency-Key: $(uuidgen)" \
>   -H "Content-Type: application/json" \
>   -d "{\"contents\": [{\"text\":\"The fox turns toward the camera.\",\"type\":\"prompt\"},{\"type\":\"first_frame\",\"url\":\"https://example.com/fox.png\"}], \"settings\": {\"duration\":3,\"resolution\":\"720p\"}}"
>
> # 2. 轮询直到 status 为 COMPLETED，按每个响应给出的 Retry-After 秒数等待。
> REQUEST_ID="<request_id from the 201 body>"
> curl -i https://api.comfy.org/v2/models/kling/kling-4.0/requests/$REQUEST_ID/status \
>   -H "X-API-Key: $COMFY_API_KEY"
>
> # 3. 收集。仍在运行时返回 202 和状态响应体；完成时返回 200 和模型的原生输出。
> curl https://api.comfy.org/v2/models/kling/kling-4.0/requests/$REQUEST_ID \
>   -H "X-API-Key: $COMFY_API_KEY"
> ```

## Schema

### 输入

**contents** `object[]`

提示词与输入媒体。仅包含 "prompt"、"first\_frame"、"middle\_frame" 和 "last\_frame" 项时选择图生视频（一个提示词和最多 10 帧）；包含任何 "refer\_image"、"feature\_video"、"base\_video"、"element" 或 "voice" 时选择 omni video（最多 15 个输入，其中最多 10 张图像、5 个视频、7 个元素和 3 个音色）。带有 "feature\_video"、"base\_video" 或视频角色元素的请求按视频输入费率计费。

**contents\[].element\_id** `string`

元素 ID，当 type 为 "element" 时使用。

**contents\[].id** `string`

该输入的引用 ID，在提示词中用作 @id。必须在任务内唯一。"element" 和 "voice" 必填。

**contents\[].text** `string`

文本提示词，当 type 为 "prompt" 时使用。最多 26,000 个英文字符或 11,000 个非英文字符；comfy-api 强制限制为 1 到 26,000 个字符，而 Kling 本身会拒绝更长的非英文文本。可使用 @id 引用其他输入。

**contents\[].type** `string` *required*

输入类型。图生视频仅接受 "prompt"、"first\_frame"、"middle\_frame" 和 "last\_frame"，并拒绝任何其他类型。omni video 还接受 "refer\_image"、"feature\_video"（参考视频）、"base\_video"（要编辑的视频，最多一个）、"element" 和 "voice"。

可能的值：`prompt`, `first_frame`, `middle_frame`, `last_frame`, `refer_image`, `feature_video`, `base_video`, `element`, `voice`

**contents\[].url** `string`

图像或视频 URL，当 type 为某一帧、"refer\_image"、"feature\_video" 或 "base\_video" 时使用。图像也可以使用 Base64。图像为 .jpg、.jpeg 或 .png，最大 30MB，每边至少 300px，宽高比在 2:5 到 5:2 之间。视频为 .mp4 或 .mov，最大 300MB，时长 3 到 30 秒。

**contents\[].voice\_id** `string`

音色 ID，当 type 为 "voice" 时使用。可以是 Kling 预设音色或自定义音色。

**options** `object`

常规配置，例如水印选项。Kling 4.0 不支持 `options.callback_url` 和 `options.external_task_id`；Comfy Router 会拒绝在 `options` 内设置其中任意一项的请求。顶层的 `callback_url` 或 `external_task_id` 不属于此 schema，会在请求到达 Kling 之前被移除。

**options.watermark\_info** `object`

是否同时生成带水印的结果。不支持自定义水印。显式的 null 会被视为未提供，与 /proxy 的 Kling 4.0 检查和 Kling 的行为一致。

**options.watermark\_info.enabled** `boolean`

true 表示生成带水印的结果，false 表示不生成。默认为 false。

**prompt** `string`

文生视频提示词。当 `contents` 缺失或为空时必填，与非空 `contents` 同时提供时会被拒绝。最多 26,000 个英文字符或 11,000 个非英文字符；comfy-api 强制限制为 1 到 26,000 个字符，而 Kling 本身会拒绝更长的非英文文本。

**settings** `object` *required*

输出配置，例如分辨率、宽高比和时长。

**settings.aspect\_ratio** `string`

已生成画面的宽高比（宽度:高度）。文生视频为 "21:9"、"16:9"、"9:16" 或 "1:1" 之一（默认 "16:9"）；omni video 为这些值或 "adaptive"（默认 "adaptive"）。图生视频则跟随图像。显式的 null 会被视为未提供，与 /proxy 的 Kling 4.0 检查和 Kling 的行为一致。

可能的值：`21:9`, `16:9`, `9:16`, `1:1`, `adaptive`

**settings.duration** `integer`

视频时长，单位为秒，3 到 30。除非 `contents` 包含 "base\_video"（此时编辑操作可省略该字段以保留基础视频的时长），否则为必填。此类调用会被挂起，并按所请求分辨率下的 30 秒上限进行估算，这只是上限而非实际价格，最终按 Kling 为已完成任务上报的价格计费。

范围：`3` 到 `30`

**settings.resolution** `string` *required*

已生成视频的分辨率。"720p" 或 "1080p" 之一。必填。

可能的值：`720p`, `1080p`

根据 Router 在 `GET /v2/models/kling/kling-4.0/openapi.json` 提供的 schema 生成，该文档也是它在请求到达提供商之前用于校验调用的同一份文档。

### 输出

**code** `integer`

错误代码。0 表示成功。

**data** `object[]`

与查询匹配的任务。

**data\[].billing** `object[]`

任务的计费详情。

**data\[].billing\[].amount** `string`

消费金额，精确到小数点后两位。

**data\[].billing\[].cash\_type** `string`

扣费所用的现金账户（仅当 charge\_type 为 "cash" 时存在），例如 "balance"。部分任务会返回该字段，其他任务可能省略。

**data\[].billing\[].charge\_type** `string`

消费账户类型。"cash" 表示余额，"unit" 表示资源包。

**data\[].billing\[].currency** `string`

`amount` 和 `list_price` 的 ISO 4217 货币代码，例如 "USD"。部分任务会返回该字段，其他任务可能省略。

**data\[].billing\[].list\_price** `string`

任务在任何折扣之前的标价，以十进制字符串表示。部分任务会返回该字段，其他任务可能省略。

**data\[].billing\[].package\_type** `string`

消耗性资源包类型（仅当 charge\_type 为 "unit" 时存在）。取值为 "video"、"image" 或 "audio" 之一。

**data\[].create\_time** `integer`

任务创建时间。Unix 时间戳，单位为毫秒。

格式：`int64`

**data\[].external\_id** `string`

此任务的自定义任务 ID（如有）。

**data\[].id** `string`

任务 ID。

**data\[].message** `string`

任务状态信息，任务失败时显示失败原因。

**data\[].outputs** `object[]`

任务已生成的输出。

**data\[].outputs\[].duration** `string`

已生成视频的时长，单位为秒。

**data\[].outputs\[].group\_id** `string`

分组标记，仅对分组图像存在。

**data\[].outputs\[].id** `string`

系统生成的输出 ID。

**data\[].outputs\[].mp3\_duration** `string`

已生成 MP3 音频的时长，单位为秒。

**data\[].outputs\[].mp3\_url** `string`

已生成音频的 MP3 URL（防盗链）。

**data\[].outputs\[].name** `string`

已生成材质的名称。

**data\[].outputs\[].owned\_by** `string`

材质来源。"kling" 表示官方库；数字为创作者 ID。

**data\[].outputs\[].status** `string`

材质状态。取值为 "succeeded" 或 "deleted" 之一。

**data\[].outputs\[].type** `string`

输出内容类型。取值为 "video"、"image"、"audio"、"voice" 或 "element" 之一。

**data\[].outputs\[].url** `string`

已生成结果的 URL（防盗链）。30 天后清除。

**data\[].outputs\[].watermark\_url** `string`

带水印结果的 URL（防盗链）。

**data\[].outputs\[].wav\_duration** `string`

已生成 WAV 音频的时长，单位为秒。

**data\[].outputs\[].wav\_url** `string`

已生成音频的 WAV URL（防盗链）。

**data\[].status** `string`

任务状态。取值为 "submitted"、"processing"、"succeeded" 或 "failed" 之一。

**data\[].update\_time** `integer`

任务更新时间。Unix 时间戳，单位为毫秒。

格式：`int64`

**message** `string`

报错信息。

**request\_id** `string`

系统生成的请求 ID。

## 示例

### 输入

```json theme={null}
{
  "contents": [
    {
      "text": "The fox turns toward the camera.",
      "type": "prompt"
    },
    {
      "type": "first_frame",
      "url": "https://example.com/fox.png"
    }
  ],
  "settings": {
    "duration": 3,
    "resolution": "720p"
  }
}
```

### 输出

```json theme={null}
{
  "code": 0,
  "data": [
    {
      "create_time": 1798761600000,
      "id": "kling-v2-task-7c8d9e0f1a2b",
      "message": "",
      "outputs": [
        {
          "duration": "5",
          "id": "kling-v2-output-2b1a0f9e8d7c",
          "type": "video",
          "url": "https://example.invalid/kling/v2/generated.mp4"
        }
      ],
      "status": "succeeded",
      "update_time": 1798761820000
    }
  ],
  "message": "SUCCEED",
  "request_id": "3d7e5c91-0b42-4f68-9a13-8e2c6d4b0a75"
}
```

## 发布前须知

SDK 会生成 `Idempotency-Key` 并在自动重试中复用它。手动重试时，请复用原始 key。Router 最长可保持连接 10 分钟。

请求失败时，Router 会发送 `X-Comfy-Error-Type` 响应头说明原因。`422` 表示 Router 在调用提供商之前就拒绝了输入，`413` 表示请求体超出了 Router 可接受的大小。已生成的资源请及时下载，因为[结果 URL 会过期](https://docs.comfy.org/zh/development/comfy-router/reference.md#结果资产)。

上文任何字段描述中提到的尺寸限制，都是提供商对该字段自身的限定，引自提供商的规范。Router 会对整个请求体另行设置上限，base64 编码的媒体内容也计入其中：参见[请求体大小](https://docs.comfy.org/zh/development/comfy-router/limitations.md)。

本页记录的是通过 Comfy Router 调用的某一个合作伙伴模型。同一个 `comfy-sdk` / `@comfyorg/sdk` 包还提供第二个客户端，用于在 Comfy Cloud 上运行完整的 ComfyUI 工作流图：`Comfy(api_key=...)` / `new Comfy({ apiKey })`，并带有 `client.workflows`、`client.assets` 和 `client.jobs`。请参阅 [Comfy SDKs](https://docs.comfy.org/zh/development/api-development/sdks.md)。

> [card] [请求头](https://docs.comfy.org/zh/development/comfy-router/headers.md)
>
> 身份验证、幂等性、请求 ID、错误分类、重试节奏、消费限额。

> [card] [使用 Router API](https://docs.comfy.org/zh/development/comfy-router/api.md)
>
> 模型发现、验证错误、重试与计费。

> [card] [限制](https://docs.comfy.org/zh/development/comfy-router/limitations.md)
>
> Router 目前不支持的功能，以及替代方案。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.