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

# Submit Asset Generation

> Start generating one or more images or videos with any supported model

## Overview

Submits an asset (image or video) generation job and returns immediately with the IDs of the temporary assets being generated. Generations run in the background — poll [`/asset/status/{assetId}`](/api-reference/assets/status) to track progress.

Credits are debited up front based on the model and the parameters you send. Failed generations are automatically refunded.

## Authentication

<Info>
  This endpoint requires API key authentication. Include your API key in the `Authorization` header.
</Info>

## Request Body

<ParamField body="type" type="string" required>
  `image` or `video`. Must match the type of the model you select.
</ParamField>

<ParamField body="model" type="string" required>
  The model identifier. See [List Models](/api-reference/assets/models) for available identifiers and capabilities.
</ParamField>

<ParamField body="prompt" type="string" required>
  Text prompt describing the asset to generate. Some models cap the prompt length — check the model page.
</ParamField>

<ParamField body="references" type="array">
  Reference media for the model. Required for image-to-video, motion control, edit, and reference-based models.

  **Not used for models with named input slots** (e.g. `kling-motion-control`, `veo-3.1-flf`). See [Named input slots](#named-input-slots) below.

  Each item must have **exactly one** of:

  <Expandable title="item properties">
    <ParamField body="url" type="string">
      Direct publicly accessible URL of the reference media file. Supported formats:

      * Images: `.jpg` / `.jpeg` / `.png` / `.webp`
      * Videos: `.mp4` / `.mov` / `.webm` / `.m4v`
    </ParamField>

    <ParamField body="asset_id" type="string">
      ID of an existing asset in your Hoox space media library (as returned by `/asset/start` or `/asset/status`).
      The server resolves the URL automatically — no need to re-upload.
    </ParamField>

    <ParamField body="avatar_id" type="string">
      ID of an avatar defined in your Hoox space. The avatar's thumbnail image is used as the reference.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="generation_count" type="number" default="1">
  Number of variations to generate from the same prompt. Must be between 1 and 4. Credits are debited per generation.
</ParamField>

<ParamField body="aspect_ratio" type="string">
  One of the model's supported aspect ratios. Defaults to the model's default if omitted.
</ParamField>

<ParamField body="resolution" type="string">
  One of the model's supported resolutions. Defaults to the model's default if omitted.
</ParamField>

<ParamField body="duration" type="integer">
  Video duration **in seconds** (e.g. `8`). Use one of the model's supported durations — see the `duration` enum in the model's `input_schema` from [Get Model](/api-reference/assets/model). The server converts it to the model's expected format automatically.
</ParamField>

<ParamField body="model_settings" type="object">
  Per-model toggles such as `generateAudio`, `camera_fixed`, `quality`. See the model page for available keys.
</ParamField>

<ParamField body="parent_media_id" type="string">
  ID of the **source asset this generation is derived from** — an edit, animation (image-to-video), upscale, restyle, or variation. Set it whenever the output comes from an existing asset: it links the new asset to its source in the dashboard's **history tree** so the full edit chain stays visible.

  This is separate from the model input: keep passing the source as a reference (`asset_id` / named slot like `source_video`) so the model receives it, **and** set `parent_media_id` to the same source id to record the lineage.

  When set, the generated assets also inherit the parent's folder, and `folder_id` is ignored.
</ParamField>

<ParamField body="folder_id" type="string">
  ID of an existing **asset folder** to place the generated asset(s) into. Create one with [Create Folder](/api-reference/folders/create) (`type: "assets"`) or list existing ones with [List Folders](/api-reference/folders/list). When working on a project or generating a batch, group its outputs in a dedicated folder so they stay organized and easy to find in the dashboard.
</ParamField>

<ParamField body="avatar_description" type="string">
  For Seedance 2.0 UGC only — appearance and actions of the subject (separate from the script).
</ParamField>

<ParamField body="webhook_url" type="string">
  URL that will receive a notification when generation completes (success or failure).
</ParamField>

<ParamField body="file_name" type="string">
  Predefined base file name for the produced asset, without extension (e.g. `summer-campaign-hero`). It is slugified server-side (lowercased, non-alphanumeric characters replaced by hyphens) and the correct extension is appended automatically. When omitted, a descriptive name is generated from the prompt.
</ParamField>

## Named input slots

Some models require specific media types in a fixed order — for example, a subject image **and** a motion reference video. For these models, instead of a generic `references[]` array, you pass named top-level properties that make the intent explicit.

The named properties for a given model are listed on its model page and in the `input_schema` field returned by [`GET /models/{name}`](/api-reference/assets/model).

Each named slot accepts the same object shape as a `references[]` item: exactly one of `url`, `asset_id`, or `avatar_id`. Slots are ordered — when a slot is optional, you may omit it, but you cannot provide a later slot while leaving an earlier one empty (e.g. `end_image` requires `start_image`).

**Models with named slots:**

| Model                                                                                                 | Named slots                                       |
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `kling-pro`                                                                                           | `start_image` (optional) + `end_image` (optional) |
| `kling-motion-control`, `kling-motion-control-pro`, `kling-v3-motion-pro`, `kling-v3-motion-standard` | `start_image` + `motion_video`                    |
| `kling-o3-edit-pro`, `kling-o3-edit-standard`                                                         | `source_video`                                    |
| `veo-3.1-flf`                                                                                         | `first_frame` + `last_frame`                      |
| `veo-3.1-extend`, `grok-imagine-video-edit`, `bytedance-upscaler`                                     | `source_video`                                    |

## Response

<ResponseField name="asset_ids" type="array">
  IDs of the created temporary assets. One ID per generation. Use these with [`/asset/status/{assetId}`](/api-reference/assets/status).
</ResponseField>

<ResponseField name="status" type="string">
  Always `generating` on success.
</ResponseField>

<ResponseField name="count" type="number">
  Number of generations launched.
</ResponseField>

<ResponseField name="cost_per_generation" type="number">
  Credits charged for one generation.
</ResponseField>

<ResponseField name="total_cost" type="number">
  Total credits debited (`cost_per_generation × count`).
</ResponseField>

## Examples

<RequestExample>
  ```bash Text-to-video (no references) theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "video",
      "model": "veo-3.1",
      "prompt": "A cinematic shot of a fox running through autumn leaves at sunrise.",
      "aspect_ratio": "9:16",
      "duration": 8,
      "resolution": "720p"
    }'
  ```

  ```bash Text-to-image into a folder theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "image",
      "model": "flux-2-pro",
      "prompt": "Product shot of a ceramic mug on a marble counter.",
      "aspect_ratio": "1:1",
      "folder_id": "662f8c1d3a4b5e6f70123456"
    }'
  ```

  ```bash Image-to-video (URL reference) theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "video",
      "model": "grok-imagine-video",
      "prompt": "The subject walks forward confidently.",
      "references": [
        { "url": "https://example.com/subject.jpg" }
      ],
      "duration": 6,
      "resolution": "720p"
    }'
  ```

  ```bash Image-to-video (existing Hoox asset) theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "video",
      "model": "grok-imagine-video",
      "prompt": "The subject walks forward confidently.",
      "references": [
        { "asset_id": "662f8c1d3a4b5e6f70123456" }
      ],
      "duration": 6
    }'
  ```

  ```bash Animate an existing asset (keeps history) theme={null}
  # Derive a video from an existing image asset. The asset is passed BOTH as the
  # model reference AND as parent_media_id, so the dashboard links them in the
  # history tree (and the video inherits the image's folder).
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "video",
      "model": "grok-imagine-video",
      "prompt": "The subject turns slowly toward the camera.",
      "references": [
        { "asset_id": "662f8c1d3a4b5e6f70123456" }
      ],
      "parent_media_id": "662f8c1d3a4b5e6f70123456"
    }'
  ```

  ```bash Image-to-video (Hoox avatar) theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "video",
      "model": "kling-v3-pro",
      "prompt": "The character smiles and waves at the camera.",
      "references": [
        { "avatar_id": "6630000000000000deadbeef" }
      ]
    }'
  ```

  ```bash Motion control (named slots) theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "video",
      "model": "kling-v3-motion-pro",
      "prompt": "Apply the motion to the subject naturally.",
      "start_image": { "url": "https://example.com/subject.jpg" },
      "motion_video": { "asset_id": "662f8c1d3a4b5e6f70123456" }
    }'
  ```

  ```bash First / last frame (named slots) theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "video",
      "model": "veo-3.1-flf",
      "prompt": "A smooth transition between the two frames.",
      "first_frame": { "url": "https://example.com/frame-start.jpg" },
      "last_frame": { "url": "https://example.com/frame-end.jpg" },
      "aspect_ratio": "16:9",
      "duration": 8
    }'
  ```

  ```bash Video edit (named slot) theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/asset/start" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "video",
      "model": "kling-o3-edit-pro",
      "prompt": "Change the background to a tropical beach.",
      "source_video": { "asset_id": "662f8c1d3a4b5e6f70123456" }
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "asset_ids": ["662f8c1d3a4b5e6f70123456"],
    "status": "generating",
    "count": 1,
    "cost_per_generation": 60,
    "total_cost": 60
  }
  ```

  ```json 400 Validation Failed theme={null}
  {
    "error": "Validation failed",
    "details": [
      { "code": "missing_field", "message": "prompt is required", "field": "prompt" }
    ]
  }
  ```

  ```json 402 Insufficient Credits theme={null}
  {
    "error": "Insufficient credits. Required: 60, Available: 12",
    "details": [
      { "code": "not_eligible", "message": "Insufficient credits. Required: 60, Available: 12" }
    ]
  }
  ```

  ```json 403 Plan Required theme={null}
  {
    "error": "This model requires one of the following plans: PRO, ENTREPRISE.",
    "details": [
      { "code": "not_eligible", "message": "This model requires one of the following plans: PRO, ENTREPRISE." }
    ]
  }
  ```
</ResponseExample>

## Notes

* The endpoint returns as soon as the temp assets are created — the actual generation runs in the background and typically completes in 10–120 seconds depending on the model.
* If you provide a `webhook_url`, it will be called when generation completes (success or failure).
* Use [List Models](/api-reference/assets/models) and [Get Model](/api-reference/assets/model) to discover the parameters each model accepts, including named input slots.
* Use [Get Pricing](/api-reference/assets/pricing) for a dry-run cost estimate before submitting.
* When a generation is derived from an existing asset (edit, animation, upscale, restyle, variation), set `parent_media_id` to the source asset's id so the dashboard keeps the full history chain. Pass the source as a reference for the model **and** as `parent_media_id` for the lineage.
