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

# Use Kling V3 with Comfy Router

> Call kling/kling-v3 through Comfy Router: endpoint, request shape and the response Router returns.

API Reference for `kling/kling-v3`, served by Comfy Router from Kling.

## Quick start

Create a key in [your Comfy workspace](https://platform.comfy.org/profile/api-keys?onboarding=router) and export it as `COMFY_API_KEY`. The Python and TypeScript snippets use the Comfy SDKs (`pip install comfy-sdk` and `npm install @comfyorg/sdk`); the cURL snippet is the same call over raw HTTP.

**Model ID:** `kling/kling-v3`

**Endpoint:** `POST https://api.comfy.org/v2/models/kling/kling-v3`

<Tabs defaultTabIndex={1}>
  <Tab title="Wait for the result">
    <CodeGroup>
      ```python Python theme={null}
      from comfy_sdk import Comfy

      # Reads COMFY_API_KEY from the environment.
      # The SDK automatically creates an idempotency key and reuses it for automatic retries.
      with Comfy() as client:
          result = client.models.run(
              "kling/kling-v3",
              {
                  "aspect_ratio": "16:9",
                  "duration": "5",
                  "mode": "std",
                  "prompt": "A red fox trotting through falling snow, cinematic lighting.",
              },
          )

      print(result)
      ```

      ```typescript TypeScript theme={null}
      import { comfy } from "@comfyorg/sdk";

      // Reads COMFY_API_KEY from the environment.
      // The SDK automatically creates an idempotency key and reuses it for automatic retries.
      const { data } = await comfy.models.run("kling/kling-v3", {
        aspect_ratio: "16:9",
        duration: "5",
        mode: "std",
        prompt: "A red fox trotting through falling snow, cinematic lighting.",
      });

      console.log(data);
      ```

      ```bash cURL theme={null}
      curl https://api.comfy.org/v2/models/kling/kling-v3 \
        -H "X-API-Key: $COMFY_API_KEY" \
        -H "Idempotency-Key: $(uuidgen)" \
        -H "Content-Type: application/json" \
        -d "{\"aspect_ratio\": \"16:9\", \"duration\": \"5\", \"mode\": \"std\", \"prompt\": \"A red fox trotting through falling snow, cinematic lighting.\"}"
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Queue and collect later">
    The same body, sent to `POST https://api.comfy.org/v2/models/kling/kling-v3/requests`. Router answers `201` with a `request_id` as soon as the run is admitted, and the result is collected once it is ready, from this process or another one. [Queued delivery](/development/comfy-router/queue) walks through status, cancellation and collection.

    <CodeGroup>
      ```python Python theme={null}
      import asyncio
      from comfy_sdk import AsyncComfy

      # Reads COMFY_API_KEY from the environment.
      # Each submit() call mints its own Idempotency-Key and reuses it for automatic retries.
      async def main():
          async with AsyncComfy() as client:
              handle = await client.models.submit(
                  "kling/kling-v3",
                  {
                      "aspect_ratio": "16:9",
                      "duration": "5",
                      "mode": "std",
                      "prompt": "A red fox trotting through falling snow, cinematic lighting.",
                  },
              )
              print("request_id:", handle.request_id)  # with the model ID, all another process needs

              # Poll until the request completes, waiting the Retry-After the server names.
              async for update in handle.iter_events():
                  print(update.status, update.queue_position)

              # The provider's own payload, the same value models.run() returns.
              # A request that failed or was cancelled raises the typed Router error here.
              result = await handle.get()

          print(result)

      asyncio.run(main())
      ```

      ```typescript TypeScript theme={null}
      import { comfy } from "@comfyorg/sdk";

      // Reads COMFY_API_KEY from the environment.
      // Each submit() call mints its own Idempotency-Key and reuses it for automatic retries.
      const handle = await comfy.models.submit("kling/kling-v3", {
        aspect_ratio: "16:9",
        duration: "5",
        mode: "std",
        prompt: "A red fox trotting through falling snow, cinematic lighting.",
      });
      console.log("requestId:", handle.requestId); // with the model ID, all another process needs

      // Poll until the request completes, waiting the Retry-After the server names.
      for await (const update of handle.events()) {
        console.log(update.status, update.queuePosition);
      }

      // The same result models.run() returns. A request that failed or was cancelled rejects here.
      const result = await handle.get();

      console.log(result.data);
      ```

      ```bash cURL theme={null}
      # 1. Submit. Router answers 201 with request_id, status_url, response_url and cancel_url.
      curl https://api.comfy.org/v2/models/kling/kling-v3/requests \
        -H "X-API-Key: $COMFY_API_KEY" \
        -H "Idempotency-Key: $(uuidgen)" \
        -H "Content-Type: application/json" \
        -d "{\"aspect_ratio\": \"16:9\", \"duration\": \"5\", \"mode\": \"std\", \"prompt\": \"A red fox trotting through falling snow, cinematic lighting.\"}"

      # 2. Poll until status is COMPLETED, waiting the Retry-After seconds each response names.
      REQUEST_ID="<request_id from the 201 body>"
      curl -i https://api.comfy.org/v2/models/kling/kling-v3/requests/$REQUEST_ID/status \
        -H "X-API-Key: $COMFY_API_KEY"

      # 3. Collect. 200 with the model's native output, 202 with the status body while it is still running.
      curl https://api.comfy.org/v2/models/kling/kling-v3/requests/$REQUEST_ID \
        -H "X-API-Key: $COMFY_API_KEY"
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Serving providers

This model is served by Comfy Router directly unless the request names another provider. The providers below serve it too, on the same endpoint and with the same model ID, selected with the `model_provider` query parameter.

* **Comfy** (default): `POST https://api.comfy.org/v2/models/kling/kling-v3`
* **Higgsfield**, as `higgsfield/higgsfield-kling-3-std`: `POST https://api.comfy.org/v2/models/kling/kling-v3?model_provider=higgsfield`

`strict_mode` defaults to false, so Router translates the native request body documented on this page into the provider's own schema and translates the response back. See [`model_provider`, `strict_mode` and `fallback_provider`](/development/comfy-router/reference#post-v2modelsprovidermodel) in the API reference, and [Serving providers](/development/comfy-router/providers) for every model routed this way.

## Schema

### Input

<ParamField body="aspect_ratio" type="string" default="&#x22;16:9&#x22;">
  Video aspect ratio

  Possible values: `16:9`, `9:16`, `1:1`
</ParamField>

<ParamField body="callback_url" type="string (uri)">
  The callback notification address

  Format: `uri`
</ParamField>

<ParamField body="camera_control" type="object" />

<ParamField body="camera_control.config" type="object" />

<ParamField body="camera_control.config.horizontal" type="number">
  Controls camera's movement along horizontal axis (x-axis). Negative indicates left, positive indicates right.

  Range: `-10` to `10`
</ParamField>

<ParamField body="camera_control.config.pan" type="number">
  Controls camera's rotation in vertical plane (x-axis). Negative indicates downward rotation, positive indicates upward rotation.

  Range: `-10` to `10`
</ParamField>

<ParamField body="camera_control.config.roll" type="number">
  Controls camera's rolling amount (z-axis). Negative indicates counterclockwise, positive indicates clockwise.

  Range: `-10` to `10`
</ParamField>

<ParamField body="camera_control.config.tilt" type="number">
  Controls camera's rotation in horizontal plane (y-axis). Negative indicates left rotation, positive indicates right rotation.

  Range: `-10` to `10`
</ParamField>

<ParamField body="camera_control.config.vertical" type="number">
  Controls camera's movement along vertical axis (y-axis). Negative indicates downward, positive indicates upward.

  Range: `-10` to `10`
</ParamField>

<ParamField body="camera_control.config.zoom" type="number">
  Controls change in camera's focal length. Negative indicates narrower field of view, positive indicates wider field of view.

  Range: `-10` to `10`
</ParamField>

<ParamField body="camera_control.type" type="string">
  Predefined camera movements type. simple: Customizable camera movement. down\_back: Camera descends and moves backward. forward\_up: Camera moves forward and tilts up. right\_turn\_forward: Rotate right and move forward. left\_turn\_forward: Rotate left and move forward.

  Possible values: `simple`, `down_back`, `forward_up`, `right_turn_forward`, `left_turn_forward`
</ParamField>

<ParamField body="cfg_scale" type="number" default="0.5">
  Flexibility in video generation. The higher the value, the lower the model's degree of flexibility, and the stronger the relevance to the user's prompt.

  Range: `0` to `1`

  Format: `float`
</ParamField>

<ParamField body="duration" type="string" default="&#x22;5&#x22;">
  Video length in seconds

  Possible values: `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`
</ParamField>

<ParamField body="external_task_id" type="string">
  Customized Task ID
</ParamField>

<ParamField body="mode" type="string" default="&#x22;std&#x22;">
  Video generation mode. std: Standard Mode, which is cost-effective. pro: Professional Mode, generates videos with longer duration but higher quality output.

  Possible values: `std`, `pro`
</ParamField>

<ParamField body="model_name" type="string">
  Model name. Omit it or send null when using Comfy Router; the model is selected by the request path. A supplied name must match that path.
</ParamField>

<ParamField body="multi_prompt" type="object[]">
  Information about each storyboard, such as prompts and duration. Supports up to 6 storyboards, with a minimum of 1. Required when multi\_shot is true and shot\_type is customize.
</ParamField>

<ParamField body="multi_prompt[].duration" type="string">
  Duration of this storyboard in seconds. Must not exceed total task duration and must not be less than 1. Sum of all storyboard durations equals total task duration.
</ParamField>

<ParamField body="multi_prompt[].index" type="integer">
  Shot sequence number
</ParamField>

<ParamField body="multi_prompt[].prompt" type="string">
  Prompt word for this storyboard. Maximum length 512 characters.
</ParamField>

<ParamField body="multi_shot" type="boolean" default="false">
  Whether to generate multi-shot video. When true, the prompt parameter is invalid. When false, the shot\_type and multi\_prompt parameters are invalid.
</ParamField>

<ParamField body="negative_prompt" type="string">
  Negative text prompt. It is recommended to supplement negative prompt information through negative sentences directly within positive prompts.
</ParamField>

<ParamField body="prompt" type="string">
  Positive text prompt. Use \<\<\<voice\_1>>> to specify a voice matching the voice\_list parameter order. A task can reference up to 2 tones. When specifying a tone, the sound parameter value must be on.
</ParamField>

<ParamField body="shot_type" type="string">
  Storyboard method. Required when the multi\_shot parameter is set to true.

  Possible values: `customize`, `intelligence`
</ParamField>

<ParamField body="sound" type="string" default="&#x22;off&#x22;">
  Whether to generate sound simultaneously when generating videos. Only V2.6 and subsequent versions of the model support this parameter.

  Possible values: `on`, `off`
</ParamField>

<ParamField body="watermark_info" type="object">
  Whether to generate watermarked results simultaneously. Custom watermark is not supported at this time.
</ParamField>

<ParamField body="watermark_info.enabled" type="boolean">
  true means generate watermark, false means do not generate.
</ParamField>

Generated from the schema Router serves at `GET /v2/models/kling/kling-v3/openapi.json`, the same document it validates a call against before the request reaches the provider.

### Output

<ResponseField name="code" type="integer">
  Error code
</ResponseField>

<ResponseField name="data" type="object" />

<ResponseField name="data.created_at" type="integer">
  Task creation time, Unix timestamp in milliseconds
</ResponseField>

<ResponseField name="data.final_unit_deduction" type="string">
  The deduction units of task
</ResponseField>

<ResponseField name="data.task_id" type="string">
  Task ID
</ResponseField>

<ResponseField name="data.task_info" type="object" />

<ResponseField name="data.task_info.external_task_id" type="string" />

<ResponseField name="data.task_result" type="object" />

<ResponseField name="data.task_result.videos" type="object[]" />

<ResponseField name="data.task_result.videos[].duration" type="string">
  Total video duration in seconds
</ResponseField>

<ResponseField name="data.task_result.videos[].id" type="string">
  Generated video ID
</ResponseField>

<ResponseField name="data.task_result.videos[].url" type="string (uri)">
  URL for generated video

  Format: `uri`
</ResponseField>

<ResponseField name="data.task_result.videos[].watermark_url" type="string (uri)">
  URL for generated video with watermark, hotlink protection format

  Format: `uri`
</ResponseField>

<ResponseField name="data.task_status" type="string">
  Task Status

  Possible values: `submitted`, `processing`, `succeed`, `failed`
</ResponseField>

<ResponseField name="data.task_status_msg" type="string">
  Task status information, displaying the failure reason when the task fails
</ResponseField>

<ResponseField name="data.updated_at" type="integer">
  Task update time, Unix timestamp in milliseconds
</ResponseField>

<ResponseField name="data.watermark_info" type="object" />

<ResponseField name="data.watermark_info.enabled" type="boolean" />

<ResponseField name="message" type="string">
  Error message
</ResponseField>

<ResponseField name="request_id" type="string">
  Request ID
</ResponseField>

## Examples

### Input

```json theme={null}
{
  "aspect_ratio": "16:9",
  "duration": "5",
  "mode": "std",
  "prompt": "A red fox trotting through falling snow, cinematic lighting."
}
```

### Output

```json theme={null}
{
  "code": 0,
  "data": {
    "created_at": 1798761600000,
    "task_id": "kling-task-1a2b3c4d5e6f",
    "task_result": {
      "videos": [
        {
          "duration": "5",
          "id": "kling-video-6f5e4d3c2b1a",
          "url": "https://example.invalid/kling/kling-v2-5-turbo/generated.mp4"
        }
      ]
    },
    "task_status": "succeed",
    "task_status_msg": "",
    "updated_at": 1798761840000
  },
  "message": "SUCCEED",
  "request_id": "9f2c1a04-7b6e-4d38-8a51-3c0e7d9b2f46"
}
```

## Before you ship

The SDKs create an `Idempotency-Key` and reuse it for automatic retries. For manual retries, reuse the original key. Router can hold the connection for up to 10 minutes.

When a request fails, Router sends an `X-Comfy-Error-Type` response header explaining why. A `422` means Router rejected the input before calling the provider, and a `413` means the request body was larger than Router accepts. Download generated assets promptly because [result URLs can expire](/development/comfy-router/reference#result-assets).

Any size limit named in a field description above is the provider's own bound on that field, quoted from the provider's specification. Router applies a separate cap to the whole request body, which base64-encoded media counts against: see [request body size](/development/comfy-router/limitations#request-bodies-are-capped).

This page documents one partner model called through Comfy Router. The same `comfy-sdk` / `@comfyorg/sdk` package also ships a second client, for running a whole ComfyUI workflow graph on Comfy Cloud: `Comfy(api_key=...)` / `new Comfy({ apiKey })`, with `client.workflows`, `client.assets` and `client.jobs`. See [Comfy SDKs](/development/api-development/sdks).

<CardGroup cols={3}>
  <Card title="Headers" icon="list" href="/development/comfy-router/headers">
    Authentication, idempotency, request IDs, error buckets, retry pacing, spend limits.
  </Card>

  <Card title="Using the Router API" icon="code" href="/development/comfy-router/api">
    Model discovery, validation errors, retries, and billing.
  </Card>

  <Card title="Limitations" icon="triangle-exclamation" href="/development/comfy-router/limitations">
    What Router does not do today, and what to use instead.
  </Card>
</CardGroup>
