> ## 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.

# Use HappyHorse 1.1 I2V with Comfy Router

> Python, TypeScript and cURL snippets for calling wan/happyhorse-1.1-i2v over HTTP through Comfy Router, plus the request fields and the result shape

API Reference for HappyHorse 1.1 I2V. HappyHorse 1.1 image-to-video animates a still first frame and renders synchronized dialogue, effects and music in the same pass.

**Input:** Image, Text · **Output:** Video

## 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:** `wan/happyhorse-1.1-i2v`

**Endpoint:** `POST https://api.comfy.org/v2/models/wan/happyhorse-1.1-i2v`

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

      # Reads COMFY_API_KEY from the environment.
      # The SDK automatically creates an idempotency key and reuses it for automatic retries.
      async def main():
          async with AsyncComfy() as client:
              result = await client.models.run(
                  "wan/happyhorse-1.1-i2v",
                  {
                      "input": {
                          "prompt": "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady",
                          "media": [
                              {
                                  "type": "first_frame",
                                  "url": "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png",
                              },
                          ],
                      },
                      "parameters": {
                          "resolution": "720P",
                          "duration": 5,
                      },
                  },
              )

          print("video:", result["output"]["video_url"])

      asyncio.run(main())
      ```

      ```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.
      type Result = { output: { video_url: string } };
      const result = await comfy.models.run<Result>("wan/happyhorse-1.1-i2v", {
        input: {
          prompt: "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady",
          media: [
            {
              type: "first_frame",
              url: "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png",
            },
          ],
        },
        parameters: {
          resolution: "720P",
          duration: 5,
        },
      });
      if (result.kind !== "json") throw new Error("expected a JSON result");

      console.log("video:", result.data.output.video_url);
      ```

      ```bash cURL theme={null}
      curl https://api.comfy.org/v2/models/wan/happyhorse-1.1-i2v \
        -H "X-API-Key: $COMFY_API_KEY" \
        -H "Idempotency-Key: $(uuidgen)" \
        -H "Content-Type: application/json" \
        -d "{\"input\": {\"prompt\":\"the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady\",\"media\":[{\"type\":\"first_frame\",\"url\":\"https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png\"}]}, \"parameters\": {\"resolution\":\"720P\",\"duration\":5}}"
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Queue and collect later">
    The same body, sent to `POST https://api.comfy.org/v2/models/wan/happyhorse-1.1-i2v/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(
                  "wan/happyhorse-1.1-i2v",
                  {
                      "input": {
                          "prompt": "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady",
                          "media": [
                              {
                                  "type": "first_frame",
                                  "url": "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png",
                              },
                          ],
                      },
                      "parameters": {
                          "resolution": "720P",
                          "duration": 5,
                      },
                  },
              )
              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("video:", result["output"]["video_url"])

      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.
      type Result = { output: { video_url: string } };
      const handle = await comfy.models.submit<Result>("wan/happyhorse-1.1-i2v", {
        input: {
          prompt: "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady",
          media: [
            {
              type: "first_frame",
              url: "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png",
            },
          ],
        },
        parameters: {
          resolution: "720P",
          duration: 5,
        },
      });
      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();
      if (result.kind !== "json") throw new Error("expected a JSON result");

      console.log("video:", result.data.output.video_url);
      ```

      ```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/wan/happyhorse-1.1-i2v/requests \
        -H "X-API-Key: $COMFY_API_KEY" \
        -H "Idempotency-Key: $(uuidgen)" \
        -H "Content-Type: application/json" \
        -d "{\"input\": {\"prompt\":\"the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady\",\"media\":[{\"type\":\"first_frame\",\"url\":\"https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png\"}]}, \"parameters\": {\"resolution\":\"720P\",\"duration\":5}}"

      # 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/wan/happyhorse-1.1-i2v/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/wan/happyhorse-1.1-i2v/requests/$REQUEST_ID \
        -H "X-API-Key: $COMFY_API_KEY"
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Schema

### Input

<ParamField body="input" type="object" required>
  Enter basic information, such as prompt words, etc.
</ParamField>

<ParamField body="input.audio_url" type="string">
  Audio file download URL. Supported formats: mp3 and wav. Cannot be used with reference\_video\_urls.
</ParamField>

<ParamField body="input.img_url" type="string">
  First frame image URL or Base64 encoded data. Required for the wan2.5-i2v-preview and
  wan2.6-i2v models. The happyhorse-1.x i2v spellings do NOT take their first frame here
  \-- they take it as a media element of type first\_frame (see media below), and an
  img\_url body that succeeds on wan2.6-i2v is refused by the provider on
  happyhorse-1.0-i2v and happyhorse-1.1-i2v -- and the wan2.7/wan3.0 spellings take their
  reference assets in media as well. Image formats: JPEG, JPG, PNG, BMP, WEBP.
  Resolution: 360-2000 pixels. File size: max 10MB.
</ParamField>

<ParamField body="input.media" type="object[]">
  Media asset list. Specifies reference materials (image, audio, video) for video
  generation. Each element contains a type and url field. This field is shared by every
  model served from this component, and which type values a given model accepts -- and
  whether it carries its image or video input here at all rather than in img\_url or
  reference\_video\_urls -- varies by model. Supported type values, per model:

  * wan2.7-i2v: first\_frame, last\_frame, driving\_audio, first\_clip. first\_frame and
    last\_frame: JPEG/JPG/PNG/BMP/WEBP, 240-8000 pixels per side, aspect ratio between 1:8
    and 8:1, at most 20MB, a public URL or a data:\{MIME\_type};base64,... URL.
    driving\_audio (WAV/MP3, 2-30 seconds, at most 15MB) and first\_clip (MP4/MOV, 2-10
    seconds, 240-4096 pixels per side, at most 100MB): a public HTTP/HTTPS URL; an inline
    data: URL is not accepted.
  * wan2.7-r2v: first\_frame (optional, max 1), reference\_image, reference\_video. At least
    one reference\_image or reference\_video is required, and reference images plus
    reference videos total at most 5. first\_frame and reference\_image: JPEG/JPG/PNG/BMP/WEBP
    (no alpha channel), 240-8000 pixels per side, aspect ratio between 1:8 and 8:1, at most
    20MB, a public URL or a data:\{MIME\_type};base64,... URL. reference\_video: a public
    HTTP/HTTPS URL; an inline data: URL is not accepted.
  * wan2.7-videoedit: video (exactly 1, the clip being edited: MP4/MOV, 2-10 seconds,
    240-4096 pixels per side, at most 100MB, a public HTTP/HTTPS URL; an inline data: URL
    is not accepted) plus an optional 0 to 4 reference\_image (JPEG/JPG/PNG/BMP/WEBP,
    240-8000 pixels per side, aspect ratio between 1:8 and 8:1, at most 20MB, a public URL
    or a data:\{MIME\_type};base64,... URL).
  * wan3.0-video, wan3.0-video-prime: first\_frame (max 1), last\_frame (max 1),
    reference\_image (max 10), reference\_video (max 5 clips, total duration \<= 15s),
    reference\_audio (max 5 clips, total duration \<= 15s), file (max 1, cannot be used
    with link), link (max 1, cannot be used with file). The reference\_\*/file/link types
    and first\_frame/last\_frame types are mutually exclusive within the same request. The
    array order defines the reference order of assets in the prompt (Image 1, Video 1,
    Audio 1, ...). first\_frame, last\_frame and reference\_image: JPEG/JPG/PNG/BMP/WEBP,
    240-8000 pixels per side, aspect ratio at most 8:1, at most 20MB, a public URL or a
    data:\{MIME\_type};base64,... URL. reference\_video, reference\_audio, file and link: a
    public HTTP/HTTPS URL; an inline data: URL is not accepted.
  * happyhorse-1.0-i2v, happyhorse-1.1-i2v: first\_frame only, exactly 1. These spellings
    take their first frame HERE and not in img\_url. At least 300x300 pixels, aspect ratio
    between 1:2.5 and 2.5:1, JPEG/JPG/PNG/WEBP, at most 20MB, a public URL or a
    data:\{MIME\_type};base64,... URL.
  * happyhorse-1.0-r2v, happyhorse-1.1-r2v: reference\_image only, 1 to 9 of them. This is
    the model's only reference input. Shortest side at least 400 pixels, JPEG/JPG/PNG/WEBP,
    at most 20MB, a public URL or a data:\{MIME\_type};base64,... URL. reference\_video is
    not an input type for this operation.
  * happyhorse-1.0-video-edit: video (exactly 1, the clip being edited: MP4/MOV, 3-60
    seconds, longer side at most 4096 pixels, shorter side at least 360 pixels, aspect
    ratio between 1:2.5 and 2.5:1, at most 100MB, a public HTTP/HTTPS URL; an inline data:
    URL is not accepted) plus an optional 0 to 5 reference\_image (JPEG/JPG/PNG/WEBP, at
    least 300x300 pixels, aspect ratio between 1:2.5 and 2.5:1, at most 20MB, a public URL
    or a data:\{MIME\_type};base64,... URL).
  * happyhorse-1.0-t2v, happyhorse-1.1-t2v, wan2.7-t2v, wan2.6-t2v, wan2.5-t2v-preview:
    text-to-video operations. Their partner references document no media input, so leave
    this field unset.
  * wan2.5-i2v-preview, wan2.6-i2v, wan2.6-r2v: this component enumerates no media
    vocabulary for these spellings. wan2.5-i2v-preview and wan2.6-i2v take their first
    frame in img\_url; wan2.6-r2v takes its reference clips in reference\_video\_urls.
    The per-model counts above are the partner's constraints, not this schema's: no
    minItems/maxItems is declared on media, because the admissible types and their caps
    differ per model. Schema acceptance does not imply provider acceptance -- and, in the
    other direction, the per-asset "at most 20MB" figures above -- the ceiling on the image
    inputs, the only inputs that may be sent inline -- are the partner's ceiling on the
    asset it ends up with, and they apply as written when the asset is a public URL,
    because those bytes never travel through Comfy. An inline data:\{MIME\_type};base64,...
    URL does travel through Comfy and meets a transport ceiling as well: a Comfy Router
    POST body is capped at 100 MiB in total and answered 413 past it, and base64 inflates a
    payload by about 4/3, so a single inline asset above roughly 75 MB is refused before any
    of the partner rules here are reached. At that size a single asset at the partner's own
    20MB ceiling fits inline comfortably, so the partner rule is what binds for one asset --
    the transport ceiling binds across several of them, since the 100 MiB Router cap bounds
    the WHOLE request rather than each element. Send anything near these ceilings as a
    public URL.
</ParamField>

<ParamField body="input.media[].type" type="string" required>
  Media asset type

  Possible values: `first_frame`, `last_frame`, `driving_audio`, `first_clip`, `reference_image`, `reference_video`, `reference_audio`, `video`, `file`, `link`
</ParamField>

<ParamField body="input.media[].url" type="string" required>
  URL of the media file: a public HTTP/HTTPS URL, or -- for exactly the IMAGE inputs the `media` description above lists for each model: first\_frame and last\_frame on wan2.7-i2v; first\_frame and reference\_image on wan2.7-r2v; reference\_image on wan2.7-videoedit; first\_frame, last\_frame and reference\_image on wan3.0-video and wan3.0-video-prime; first\_frame on happyhorse-1.0-i2v and happyhorse-1.1-i2v; reference\_image on happyhorse-1.0-r2v and happyhorse-1.1-r2v; and reference\_image on happyhorse-1.0-video-edit -- an inline `data:{MIME_type};base64,...` URL. No video, audio, file or link input on any of these models takes an inline data: URL. An oss\://dashscope-instant temporary URL from the partner's own upload service, or (on wan2.7-videoedit) an Asset Center asset\_id, resolves only against the Alibaba Cloud account that uploaded it; Comfy makes the model call with its own key and exposes no upload route, so a caller's own oss\:// URL or asset\_id is not a supported input. This field does not validate the URL scheme, so such a value is forwarded to the partner as-is rather than rejected here. See the `media` description for the per-model size and pixel limits and for the 100 MiB Router request-body cap that bounds an inline payload in aggregate.
</ParamField>

<ParamField body="input.negative_prompt" type="string">
  Reverse prompt words are used to describe content that you do not want to see in the video screen
</ParamField>

<ParamField body="input.prompt" type="string">
  Text prompt words. Support Chinese and English, length not exceeding 800 characters
  (up to 20,000 characters for wan3.0-video; content exceeding the limit is truncated).
  For wan2.6-r2v with multiple reference videos, use 'character1', 'character2', etc. to refer to subjects
  in the order of reference videos. Example: "Character1 sings on the roadside, Character2 dances beside it"
  For wan3.0-video reference mode, use 'Image 1', 'Video 1', 'Audio 1', etc. to refer to media assets
  in the corresponding order within the media array.
</ParamField>

<ParamField body="input.reference_video_urls" type="string[]">
  Reference video URLs for wan2.6-r2v model only. Array of 1-3 video URLs.
  Input restrictions:

  * Format: mp4, mov
  * Quantity: 1-3 videos
  * Single video length: 2-30 seconds
  * Single file size: max 30MB
  * Cannot be used with audio\_url
    Reference duration: Single video max 5s, two videos max 2.5s each, three videos proportionally less.
    Billing: Based on actual reference duration used.
</ParamField>

<ParamField body="input.template" type="string">
  Video effect template name. Optional. Currently supported: squish, flying, carousel. When used, prompt parameter is ignored.
</ParamField>

<ParamField body="model" type="string">
  The ID of the model to call. NOT constrained on this component: Comfy Router fills it from the `{model}` path segment of `POST /v2/models/wan/{model}`, so a Router caller omits it. A direct v1 call to `POST /proxy/wan/api/v1/services/aigc/video-generation/video-synthesis` MUST supply it, and the enum of accepted spellings lives on that operation's own component, `WanVideoGenerationRequest`.
</ParamField>

<ParamField body="parameters" type="object">
  Video processing parameters
</ParamField>

<ParamField body="parameters.audio" type="boolean" default="true">
  Whether to add audio to the video. Supported for wan3.0-video and wan3.0-video-prime only; the provider documents no such switch for the other wan models.
</ParamField>

<ParamField body="parameters.audio_setting" type="string" default="&#x22;auto&#x22;">
  Video audio setting for wan2.7-videoedit model.

  * auto (default): Model intelligently judges based on prompt content
  * origin: Forcefully preserve the original audio from the input video

    Possible values: `auto`, `origin`
</ParamField>

<ParamField body="parameters.duration" type="integer" default="5">
  The duration of the video generated, in seconds:

  * wan2.5 models: 5 or 10 seconds
  * wan2.6-t2v, wan2.6-i2v: 5, 10, or 15 seconds
  * wan2.6-r2v: 5 or 10 seconds only (no 15s support)
  * wan2.7-i2v, wan2.7-t2v: integer in \[2, 15]
  * wan2.7-r2v, wan2.7-videoedit: integer in \[2, 10]
  * wan3.0-video: integer in \[2, 30] without video input; with video input the total
    input video duration + output video duration must not exceed 30 seconds; -1 enables
    smart duration mode where the model picks a suitable duration
    This proxy returns 400 for a duration outside \[-1, 30].

    Range: `-1` to `30`
</ParamField>

<ParamField body="parameters.prompt_extend" type="boolean" default="true">
  Is it enabled prompt intelligent rewriting. Default is true
</ParamField>

<ParamField body="parameters.ratio" type="string">
  Aspect ratio of the generated video. For wan2.7 and wan3.0 models only.
  For wan2.7 models, defaults based on the resolution tier if not provided.
  For wan3.0-video, adaptive (the default) automatically recommends a suitable
  aspect ratio based on the input media proportions and intent.

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

<ParamField body="parameters.resolution" type="string">
  Resolution level. Supported values vary by model:

  * wan2.5-i2v-preview: 480P, 720P, 1080P
  * wan2.6 models (t2v, i2v, r2v): 720P, 1080P only (no 480P support)
  * wan2.7 models (i2v, t2v, r2v, videoedit): 720P, 1080P (default 1080P)
  * wan3.0-video, wan3.0-video-prime: 480P, 720P, 1080P (upstream default 1080P)
  * happyhorse-1.0-\* (t2v, i2v, r2v, video-edit): 720P, 1080P
  * happyhorse-1.1-\* (t2v, i2v, r2v): 480P, 720P, 1080P
    This proxy rejects video generation requests that provide neither resolution
    nor size, because the resolution tier selects the billing rate. It upper-cases
    resolution before checking it and forwards the upper-cased value, returns 400
    for a value outside this enum, and returns 400 for 480P (whether sent as
    resolution or as a 480P size) on the wan2.6, wan2.7 and happyhorse-1.0 models
    listed above as having no 480P.

    Possible values: `480P`, `720P`, `1080P`
</ParamField>

<ParamField body="parameters.seed" type="integer">
  Random number seed, used to control the randomness of the model generated content

  Range: `0` to `2147483647`
</ParamField>

<ParamField body="parameters.shot_type" type="string" default="&#x22;single&#x22;">
  Intelligent multi-lens control. Only active when prompt\_extend is enabled.
  For wan2.6 and wan2.7-r2v models.

  * single: Single-shot video (default)
  * multi: Multi-shot video

    Possible values: `multi`, `single`
</ParamField>

<ParamField body="parameters.size" type="string">
  Video resolution in format width*height. Supported resolutions vary by model:
  For wan2.5 T2V: 480P (480*832, 832*480, 624*624), 720P, 1080P sizes
  For wan2.6 T2V/R2V (no 480P):
  720P: 1280*720, 720*1280, 960*960, 1088*832, 832*1088
  1080P: 1920*1080, 1080*1920, 1440*1440, 1632*1248, 1248*1632
  When both size and resolution are sent, size selects the billed tier, and
  resolution must still be a value this proxy accepts for the model. A 480P size
  returns 400 on every model the resolution description lists as having no 480P.
</ParamField>

<ParamField body="parameters.watermark" type="boolean" default="false">
  Whether to add a watermark logo, the watermark is located in the lower right corner
</ParamField>

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

### Output

<ResponseField name="output" type="object" required />

<ResponseField name="output.actual_prompt" type="string">
  Actual prompt after intelligent rewriting (for video tasks)
</ResponseField>

<ResponseField name="output.check_audio" type="string">
  Audio URL for I2V tasks with audio generation
</ResponseField>

<ResponseField name="output.code" type="string">
  The error code for the failed request (not returned if request is successful)
</ResponseField>

<ResponseField name="output.end_time" type="string">
  Task completion time
</ResponseField>

<ResponseField name="output.message" type="string">
  Detailed information about the failed request (not returned if request is successful)
</ResponseField>

<ResponseField name="output.orig_prompt" type="string">
  Original input prompt (for video tasks)
</ResponseField>

<ResponseField name="output.results" type="object[]">
  List of task results for image generation tasks
</ResponseField>

<ResponseField name="output.results[].actual_prompt" type="string">
  Actual prompt after intelligent rewriting (if enabled)
</ResponseField>

<ResponseField name="output.results[].code" type="string">
  Image error code (returned when some tasks fail)
</ResponseField>

<ResponseField name="output.results[].message" type="string">
  Image error information (returned when some tasks fail)
</ResponseField>

<ResponseField name="output.results[].orig_prompt" type="string">
  Original input prompt
</ResponseField>

<ResponseField name="output.results[].url" type="string">
  Generated image URL address
</ResponseField>

<ResponseField name="output.scheduled_time" type="string">
  Task execution time
</ResponseField>

<ResponseField name="output.submit_time" type="string">
  Task submission time
</ResponseField>

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

<ResponseField name="output.task_metrics" type="object">
  Task result statistics for image generation tasks
</ResponseField>

<ResponseField name="output.task_metrics.FAILED" type="integer">
  Number of failed tasks
</ResponseField>

<ResponseField name="output.task_metrics.SUCCEEDED" type="integer">
  Number of successful tasks
</ResponseField>

<ResponseField name="output.task_metrics.TOTAL" type="integer">
  Total number of tasks
</ResponseField>

<ResponseField name="output.task_status" type="string" required>
  Task status

  Possible values: `PENDING`, `RUNNING`, `SUCCEEDED`, `FAILED`, `CANCELED`, `UNKNOWN`
</ResponseField>

<ResponseField name="output.video_url" type="string">
  Video URL for completed video generation tasks. Link validity period 24 hours
</ResponseField>

<ResponseField name="request_id" type="string" required>
  Unique request identifier
</ResponseField>

<ResponseField name="usage" type="object">
  Output information statistics. Only successful results are counted
</ResponseField>

<ResponseField name="usage.SR" type="integer">
  Video resolution level (I2V and wan3.0-video tasks)
</ResponseField>

<ResponseField name="usage.duration" type="number">
  Duration of generated video in seconds (I2V and wan3.0-video tasks)
</ResponseField>

<ResponseField name="usage.fps" type="integer">
  Frame rate of the generated video (wan3.0-video tasks)
</ResponseField>

<ResponseField name="usage.image_count" type="integer">
  Number of generated images (T2I and I2I tasks)
</ResponseField>

<ResponseField name="usage.input_video_duration" type="number">
  Duration of the input video in seconds, 0.0 when no video input (wan3.0-video tasks)
</ResponseField>

<ResponseField name="usage.output_video_duration" type="number">
  Duration of the output video in seconds (wan3.0-video tasks)
</ResponseField>

<ResponseField name="usage.ratio" type="string">
  Aspect ratio of the generated video, e.g. 16:9 (wan3.0-video tasks)
</ResponseField>

<ResponseField name="usage.size" type="string">
  Image resolution (T2I and I2I tasks)
</ResponseField>

<ResponseField name="usage.video_count" type="integer">
  Number of generated videos (T2V tasks)
</ResponseField>

<ResponseField name="usage.video_duration" type="number">
  Duration of generated video in seconds (T2V tasks)
</ResponseField>

<ResponseField name="usage.video_ratio" type="string">
  Video resolution ratio (T2V tasks)
</ResponseField>

<ResponseField name="code" type="string">
  Error code for a failed request, reported at the ROOT of the envelope rather than under `output` (not returned if the request succeeded).
</ResponseField>

<ResponseField name="message" type="string">
  Detailed information about a failed request, reported at the ROOT of the envelope rather than under `output` (not returned if the request succeeded). Read this before falling back to `output.message`.
</ResponseField>

## Examples

### Input

```json theme={null}
{
  "input": {
    "prompt": "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady",
    "media": [
      {
        "type": "first_frame",
        "url": "https://raw.githubusercontent.com/Comfy-Org/workflow_templates/main/input/pink_robot_front.png"
      }
    ]
  },
  "parameters": {
    "resolution": "720P",
    "duration": 5
  }
}
```

### Output

```json theme={null}
{
  "output": {
    "task_id": "0385dc79-5ff8-4d82-bcb6-7c1a9f2e4d60",
    "task_status": "SUCCEEDED",
    "submit_time": "2027-01-01T00:00:00.000Z",
    "scheduled_time": "2027-01-01T00:00:01.000Z",
    "end_time": "2027-01-01T00:01:04.000Z",
    "orig_prompt": "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady",
    "actual_prompt": "the robot lowers its raised arm and steps toward the camera, the flat orange backdrop holds steady, smooth studio lighting, subtle camera push in",
    "video_url": "https://.../generated.mp4"
  },
  "request_id": "7574ee8f-38a3-4b1e-9280-11c33ab46e51",
  "usage": {
    "SR": 720,
    "duration": 5
  }
}
```

The video URL is valid for 24 hours. Download the video promptly if you need to keep it.

## 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>


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