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.
Idle
$0.15per run·~66 / $10
The man from <Picture 1> - same face, curly blond hair, glasses, grey-green jacket and baggy trousers, white sneakers - dances on a neon-lit city street at night, full-body shot. Audio: upbeat hip-hop beat.
MiniMax H3 ControlNet Union Open Weights generates a new video while following the motion, structure, and composition of a source video. The model automatically extracts the selected control signal — such as pose, depth, edges, lines, scribble, or grayscale structure — so you can guide generation with a normal source video instead of preparing control maps manually.
Use pose for motion and character-performance transfer, depth for preserving spatial layout and camera movement, edge-based controls for structural restyling, or gray for recoloring and relighting. Optional reference images and audio can provide additional subject, style, or sound guidance.
Seven control types in one model
Choose pose, depth, canny, soft_edge, lines, scribble, or gray depending on what should be preserved from the source.
Automatic control extraction
Upload a normal source video and let the model derive the selected control signal automatically.
Character motion transfer
Combine pose with reference images to generate a different character performing the source video's motion.
Structure-preserving restyling
Use depth or edge controls to change the visual style, environment, or subject while retaining source composition and movement.
Recoloring and relighting
Use gray to preserve luminance structure while changing color, lighting, or overall grading.
Multimodal reference guidance
Add up to 9 reference images and 3 reference audio inputs for additional subject, style, or sound control.
Generated or preserved audio
Generate native audio with the new video, or disable audio generation to preserve the source soundtrack.
Four resolution tiers
Generate at 480p, 540p, 768p, or 1080p.
| Parameter | Required | Description |
|---|---|---|
| prompt | Yes | Text description of the desired output. Reference optional inputs as <Picture 1>–<Picture 9> and <Audio 1>–<Audio 3>. |
| video | Yes | Source video URL. Up to the first 15 seconds are used. The control signal is extracted automatically, and the output follows the processed source duration and aspect ratio. |
| control_type | No | Control signal to extract: pose, depth, canny, soft_edge, lines, scribble, or gray. Default: pose. |
| control_strength | No | Strength of the extracted control signal. Range: 0–2. Default: 1. |
| reference_images | No | Optional reference images for subject, appearance, or style guidance. Supports up to 9 images. |
| reference_audios | No | Optional reference audio inputs for audio guidance. Supports up to 3 inputs. |
| resolution | No | Output resolution: 480p, 540p, 768p, or 1080p. Default: 480p. |
| generate_audio | No | Generate audio together with the output video. Default: true. Set to false to preserve the source video's audio track. |
| seed | No | Random seed for generation. A negative value selects a random seed. |
| Control Type | Preserves from Source | Best For |
|---|---|---|
pose | Body, hand, and face motion | Character animation, dance, performance transfer |
depth | Spatial layout and camera movement | Scene replacement, structural restyling, composition preservation |
canny | Precise edges | Detailed and faithful structural restyling |
soft_edge | Softer object boundaries | Stylized re-rendering with more visual freedom |
lines | Straight-line structure | Architecture, interiors, products, geometric scenes |
scribble | Loose structural lines | Creative reinterpretation with approximate composition |
gray | Brightness and luminance structure | Recoloring, relighting, grading, appearance changes |
480p, 540p, 768p, or 1080p.generate_audio=true for newly generated audio, or disable it to preserve the source soundtrack.Pricing is based on the processed source-video duration and selected resolution, plus any reference-image or reference-audio charges.
Source duration is rounded up to the next whole second, with a minimum billed duration of 3 seconds and a maximum of 15 seconds.
| Resolution | Per Second | 3s | 5s | 10s | 15s |
|---|---|---|---|---|---|
| 480p | $0.10 | $0.30 | $0.50 | $1.00 | $1.50 |
| 540p | $0.15 | $0.45 | $0.75 | $1.50 | $2.25 |
| 768p | $0.20 | $0.60 | $1.00 | $2.00 | $3.00 |
| 1080p | $0.40 | $1.20 | $2.00 | $4.00 | $6.00 |
| Reference Type | Price |
|---|---|
| Reference image | $0.02 each |
| Reference audio | $0.02 each |
control_type, control_strength, generate_audio, prompt, and seed do not add separate charges.
| Configuration | Calculation | Cost |
|---|---|---|
| 5s source, 480p | 5 × $0.10 | $0.50 |
| 8s source, 768p + 1 reference image | 8 × $0.20 + $0.02 | $1.62 |
| 20s source, 1080p | 15 × $0.40 | $6.00 |
For source videos longer than 15 seconds, only the first 15 seconds are processed and billed.
pose.depth to keep spatial layout and camera movement while rebuilding the scene.lines or edge controls to preserve geometric structure.gray to retain brightness structure while changing color and lighting.pose with a clear full-body reference image when transferring human motion to another character.depth when camera movement and spatial layout matter more than exact surface details.canny for stronger structural adherence and soft_edge when you want more creative freedom.control_strength when the prompt should have more influence.control_strength when the result drifts too far from the source structure.generate_audio=false when the original soundtrack should remain unchanged.480p for lower-cost testing before moving to higher resolutions.prompt and video are required.15 seconds of the source video are processed.control_type defaults to pose.control_strength defaults to 1.reference_images supports up to 9 images.reference_audios supports up to 3 inputs.resolution defaults to 480p.generate_audio defaults to true.generate_audio=false, the source video soundtrack is preserved.Grab a WaveSpeedAI API key, then call POST https://api.wavespeed.ai/api/v3/wavespeed-ai/minimax-h3/controlnet-union with your input as JSON. The endpoint returns a prediction id. Start polling the result endpoint around every 2 seconds, increase the interval for long-running tasks, and stop on any terminal status. On completed, read output values from data.outputs. Examples for Minimax H3 Controlnet Union below.
set -euo pipefail
: "${WAVESPEED_API_KEY:?Set WAVESPEED_API_KEY}"
REQUEST_BODY=$(cat <<'JSON'
{
"prompt": "A cinematic shot of a city at sunset, soft golden light",
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"control_type": "pose",
"control_strength": 1,
"resolution": "480p",
"generate_audio": true
}
JSON
)
# 1. Submit the prediction.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
-X POST "https://api.wavespeed.ai/api/v3/wavespeed-ai/minimax-h3/controlnet-union" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $WAVESPEED_API_KEY" \
-d "$REQUEST_BODY")
TASK=$(printf '%s' "$SUBMIT_RESPONSE" | jq 'if has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "$TASK" | jq -r '.id')
if [ -z "$PREDICTION_ID" ] || [ "$PREDICTION_ID" = "null" ]; then
printf 'Submission response did not contain a prediction id
' >&2
exit 1
fi
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/$PREDICTION_ID/result"
# 2. Poll until the prediction finishes.
while true; do
RESPONSE=$(curl --silent --show-error --fail-with-body "$RESULT_URL" \
-H "Authorization: Bearer $WAVESPEED_API_KEY")
RESULT=$(printf '%s' "$RESPONSE" | jq 'if has("data") then .data else . end')
STATUS=$(printf '%s' "$RESULT" | jq -r '.status')
case "$STATUS" in
completed) printf '%s\n' "$RESULT" | jq '.outputs'; break ;;
failed|cancelled|timeout|deleted) printf '%s\n' "$RESULT" | jq . >&2; exit 1 ;;
*) sleep 2 ;;
esac
doneconst submitUrl = "https://api.wavespeed.ai/api/v3/wavespeed-ai/minimax-h3/controlnet-union";
const apiKey = process.env.WAVESPEED_API_KEY;
if (!apiKey) throw new Error('Set WAVESPEED_API_KEY');
async function requestJson(url, options = {}) {
const response = await fetch(url, options);
if (!response.ok) throw new Error(await response.text());
return response.json();
}
// 1. Submit the prediction.
const body = await requestJson(submitUrl, {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"prompt": "A cinematic shot of a city at sunset, soft golden light",
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"control_type": "pose",
"control_strength": 1,
"resolution": "480p",
"generate_audio": true
}),
});
const task = body.data ?? body;
if (!task.id) throw new Error("Submission response did not contain a prediction id");
const resultUrl = `https://api.wavespeed.ai/api/v3/predictions/${task.id}/result`;
// 2. Poll until the prediction finishes.
while (true) {
const resultBody = await requestJson(resultUrl, {
headers: { "Authorization": `Bearer ${apiKey}` },
});
const result = resultBody.data ?? resultBody;
if (result.status === "completed") {
console.log(result.outputs);
break;
}
if (["failed", "cancelled", "timeout", "deleted"].includes(result.status)) throw new Error(JSON.stringify(result));
await new Promise(resolve => setTimeout(resolve, 2000));
}import json
import os
import time
from urllib.request import Request, urlopen
api_key = os.environ["WAVESPEED_API_KEY"]
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
payload = {
"prompt": "A cinematic shot of a city at sunset, soft golden light",
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"control_type": "pose",
"control_strength": 1,
"resolution": "480p",
"generate_audio": True
}
def request_json(url, data=None):
request = Request(url, data=data, headers=headers, method="POST" if data else "GET")
with urlopen(request) as response:
return json.load(response)
# 1. Submit the prediction.
body = request_json("https://api.wavespeed.ai/api/v3/wavespeed-ai/minimax-h3/controlnet-union", json.dumps(payload).encode())
task = body.get("data", body)
if not task.get("id"):
raise RuntimeError("Submission response did not contain a prediction id")
result_url = f"https://api.wavespeed.ai/api/v3/predictions/{task['id']}/result"
# 2. Poll until the prediction finishes.
while True:
result_body = request_json(result_url)
result = result_body.get("data", result_body)
status = result.get("status")
if status == "completed":
print(result.get("outputs", []))
break
if status in {"failed", "cancelled", "timeout", "deleted"}:
raise RuntimeError(result)
time.sleep(2)Minimax H3 Controlnet Union is a WaveSpeedAI model for pose / motion driven video, exposed as a REST API on WaveSpeedAI. 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. You can call it programmatically or try it from the playground above.
POST your input parameters to the model's REST endpoint (shown in the API tab of this playground) with your WaveSpeedAI API key in the Authorization header. Submission returns a prediction ID. Poll the result endpoint starting around every 2 seconds, increase the interval for long-running tasks, and stop on any terminal status. The playground generates Python, JavaScript, and cURL examples for submitting requests and polling results. Full request/response shape is documented at https://wavespeed.ai/docs/docs-api/wavespeed-ai/minimax-h3-controlnet-union.
Minimax H3 Controlnet Union starts at $0.15 per run. That figure is the base price — the final charge scales with the parameters you set in the form (output size, length, count, references, or whatever knobs this model exposes), so a higher-quality or larger output costs more than a minimal one. The exact cost for your current input is shown live next to the Generate button before you submit, and the actual per-call charge is recorded on the prediction afterwards.
Key inputs: `prompt`, `video`, `resolution`, `seed`, `reference_images`, `control_strength`. The full JSON schema (types, defaults, allowed values) is rendered above the Generate button and mirrored in the API reference at https://wavespeed.ai/docs/docs-api/wavespeed-ai/minimax-h3-controlnet-union.
Sign up for a free WaveSpeedAI account to claim starter credits, copy your API key from /accesskey, then call the endpoint shown in the API tab of the playground. The playground also auto-generates a code sample in Python, JavaScript, or cURL for the parameters you've set.
Commercial usage rights depend on the model's license, set by its provider (WaveSpeedAI). Check the provider's applicable terms and WaveSpeedAI's Terms of Service before commercial use.