# wavespeed-ai/minimax-h3/controlnet-union

> MiniMax H3 Open Weights ControlNet Union generates a new video that follows the motion and composition of a source video. Pose, depth, edges, lines, scribble or grayscale structure is extracted from the source automatically and guides the output, optionally with reference images for the subject or style, with native stereo audio generated in the same pass. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.

## Overview

- **Endpoint**: `https://api.wavespeed.ai/api/v3/wavespeed-ai/minimax-h3/controlnet-union`
- **Polling/result URL**: `https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result`
- **Model ID**: `wavespeed-ai/minimax-h3/controlnet-union`
- **Category**: video-to-video

## API Information

This model can be used via our HTTP API or more conveniently via our client libraries.
The API is asynchronous: submit a prediction, then poll its result URL until it completes.

### Input Schema

The API accepts the following input parameters:

- **`prompt`** (`string`, _required_):
  Describe the output video. The source video's motion and composition are carried over through the selected control. Refer to reference inputs as <Picture 1>..<Picture 9> and <Audio 1>..<Audio 3>.

- **`video`** (`string`, _required_):
  URL of the source video (up to 15 seconds are used). The control signal is extracted from it automatically and drives motion and composition; the output keeps its duration and aspect ratio.

- **`control_type`** (`string`, _optional_):
  What to keep from the source video: pose (body, hand and face motion), depth (spatial layout), canny (precise edges), soft_edge (softer outlines), lines (straight lines, for architecture and interiors), scribble (loose sketch lines), gray (brightness structure, for recoloring).
  - Default: `"pose"`
  - Options: "pose", "depth", "canny", "soft_edge", "lines", "scribble", "gray"

- **`control_strength`** (`number`, _optional_):
  How strongly the control signal constrains the output. Lower values give the prompt more freedom.
  - Default: `1`
  - Range: `0` to `2`

- **`reference_images`** (`array of string`, _optional_):
  Optional reference image URLs, e.g. the character to animate or a target style. Refer to them in the prompt as <Picture 1>..<Picture 9>.

- **`reference_audios`** (`array of string`, _optional_):
  Optional reference audio URLs to guide audio generation. Refer to them in the prompt as <Audio 1>..<Audio 3>.

- **`resolution`** (`string`, _optional_):
  Output video resolution. 768p is the model's native canvas; 480p is a faster, lower-cost tier; 540p is a mid tier at 1.5x the 480p price. 1080p is the highest-quality full-HD tier at 2x the 768p price (generation takes longer).
  - Default: `"480p"`
  - Options: "480p", "540p", "768p", "1080p"

- **`generate_audio`** (`boolean`, _optional_):
  Whether to generate native audio. When set to false, the source video's audio track is preserved on the output instead.
  - Default: `true`

- **`seed`** (`integer`, _optional_):
  The random seed to use for the generation. A negative value means a random seed will be used.



**Required Parameters Example**:

```json
{
  "prompt": "A cinematic ocean wave at sunrise, highly detailed",
  "video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
}
```

**Full Example**:

```json
{
  "prompt": "A cinematic ocean wave at sunrise, highly detailed",
  "video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
  "control_type": "pose",
  "control_strength": 1,
  "reference_images": [],
  "reference_audios": [],
  "resolution": "480p",
  "generate_audio": true,
  "seed": 0
}
```

### Result Data Schema

The `data` object returned by the API has the following fields:

- **`created_at`** (`string (date-time)`, _optional_):
  ISO timestamp of when the request was created (e.g., "2023-04-01T12:34:56.789Z").

- **`id`** (`string`, _optional_):
  Unique identifier for the prediction, the ID of the prediction to get.

- **`model`** (`string`, _optional_):
  Model ID used for the prediction.

- **`outputs`** (`array of string | object`, _optional_):
  Array of generated outputs (empty when status is not completed). Items are usually URL strings, but may be text strings or structured result objects, depending on the model.

- **`status`** (`string`, _optional_):
  Status of the task: created, processing, completed, or failed.

- **`urls`** (`object`, _optional_):
  Object containing related API endpoints.



**Example `data` Object**:

```json
{
  "created_at": "example",
  "id": "example",
  "model": "example",
  "outputs": [],
  "status": "example",
  "urls": {}
}
```

## Usage Examples

The examples use `jq` to read JSON. Set your API key first:

```bash
set -euo pipefail
export WAVESPEED_API_KEY="your-api-key"
```

### 1. Submit a prediction

```bash
REQUEST_BODY=$(cat <<'JSON'
{
  "prompt": "A cinematic ocean wave at sunrise, highly detailed",
  "video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
}
JSON
)

SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
  --request POST \
  --url https://api.wavespeed.ai/api/v3/wavespeed-ai/minimax-h3/controlnet-union \
  --header "Authorization: Bearer ${WAVESPEED_API_KEY}" \
  --header "Content-Type: application/json" \
  --data "${REQUEST_BODY}")

printf '%s\n' "${SUBMIT_RESPONSE}" | jq .
```

The response contains the prediction ID in `data.id`.

### 2. Poll until complete and read `outputs`

```bash
PREDICTION_ID=$(printf '%s' "${SUBMIT_RESPONSE}" | jq -r '.data.id')
if [ -z "${PREDICTION_ID}" ] || [ "${PREDICTION_ID}" = "null" ]; then
  printf 'Submission response did not contain data.id\n' >&2
  exit 1
fi
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"

while true; do
  RESPONSE=$(curl --silent --show-error --fail-with-body \
    --request GET \
    --url "${RESULT_URL}" \
    --header "Authorization: Bearer ${WAVESPEED_API_KEY}")

  RESULT=$(printf '%s' "${RESPONSE}" | jq -e '.data')
  STATUS=$(printf '%s' "${RESULT}" | jq -er '.status')
  case "${STATUS}" in
    completed)
      # Generated files are returned in the outputs array.
      printf '%s\n' "${RESULT}" | jq '.outputs'
      break
      ;;
    failed|cancelled|timeout|deleted)
      printf '%s\n' "${RESULT}" | jq '{status, error, code}'
      exit 1
      ;;
    *)
      sleep 2
      ;;
  esac
done
```

## Additional Resources

### Documentation

- [Model Playground](https://wavespeed.ai/models/wavespeed-ai/minimax-h3/controlnet-union)
- [API Documentation](https://wavespeed.ai/docs/docs-api/wavespeed-ai/minimax-h3-controlnet-union)
