MiniMax H3 (Hailuo 03) API
MiniMax H3 (Hailuo 03) video with sound, up to 15 seconds: from a prompt, from the first and last frames or from references. References can be pictures, videos and audio. Quality 768P or 2K, the model makes the sound itself.
For AI assistants:Download .mdAll documentation .mdOpen as text
Connect in three steps
- Get a keyCreate a key in the dashboard after you confirm your email. One key opens every model.
- Check the pricePOST /v1/price shows the cost of a run in advance, without charging you.
- Run a task and collect the resultPOST /v1/tasks starts a task, GET /v1/tasks/{id} shows its status and files.
Ready-to-use code
Replace YOUR_API_KEY with your key. The code starts a task and waits for the result. In cURL, repeat the second request with the id from the first response instead of TASK_ID until status becomes succeeded.
curl -X POST "https://api.cyhub.ai/v1/tasks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"model": "minimax_h3",
"settings": {
"mode": "text_to_video",
"prompt": "Кот медленно идёт по пляжу на закате, волны тихо набегают на берег",
"resolution": "768P",
"aspect_ratio": "16:9",
"duration": 6
}
}'
curl "https://api.cyhub.ai/v1/tasks/TASK_ID" \
-H "Authorization: Bearer YOUR_API_KEY"import time
import requests
API = "https://api.cyhub.ai/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
body = {
"model": "minimax_h3",
"settings": {
"mode": "text_to_video",
"prompt": "Кот медленно идёт по пляжу на закате, волны тихо набегают на берег",
"resolution": "768P",
"aspect_ratio": "16:9",
"duration": 6,
},
}
response = requests.post(f"{API}/tasks", json=body, headers=HEADERS, timeout=60)
response.raise_for_status()
task = response.json()
while task["status"] in ("queued", "running"):
time.sleep(5)
task = requests.get(f"{API}/tasks/{task['id']}", headers=HEADERS, timeout=30).json()
print(task["status"], task["result"])const API = "https://api.cyhub.ai/v1";
const HEADERS = { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json" };
const body = {
"model": "minimax_h3",
"settings": {
"mode": "text_to_video",
"prompt": "Кот медленно идёт по пляжу на закате, волны тихо набегают на берег",
"resolution": "768P",
"aspect_ratio": "16:9",
"duration": 6
}
};
async function main() {
let response = await fetch(`${API}/tasks`, { method: "POST", headers: HEADERS, body: JSON.stringify(body) });
if (!response.ok) throw new Error(await response.text());
let task = await response.json();
while (task.status === "queued" || task.status === "running") {
await new Promise((resolve) => setTimeout(resolve, 5000));
response = await fetch(`${API}/tasks/${task.id}`, { headers: HEADERS });
task = await response.json();
}
console.log(task.status, task.result);
}
main();Price before the run
Prices as of 15.10.2026: from 26 ₽. POST /v1/price shows the exact price of your settings.
| Mode | Price |
|---|---|
| From a prompt | from 26 ₽ |
| From frames | from 26 ₽ |
| From references | from 26 ₽ |
Send the same settings to POST /v1/price: the response shows the price of the run without charging you.
curl -X POST "https://api.cyhub.ai/v1/price" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"model": "minimax_h3",
"settings": {
"mode": "text_to_video",
"prompt": "Кот медленно идёт по пляжу на закате, волны тихо набегают на берег",
"resolution": "768P",
"aspect_ratio": "16:9",
"duration": 6
}
}'amount_minor: the price of the run in minor units (kopecks for rubles)currency: the wallet currencyavailable_minor: how much your balance has for new tasks right now
Modes
Each mode has its own parameters and examples. The mode is set by the mode field.
- From a prompt
mode = text_to_video - From frames
mode = image_to_video - From references
mode = reference_to_video
From a prompt
Video from text alone, no files are sent.
Value of the mode field: text_to_video
Price in this mode from 26 ₽.
Parameters
Model parameters go inside settings. Omitted optional fields take their default values.
promptRequiredWhat happens in the video, how the camera moves, what it sounds like. A timed script works too: what happens from 0 to 3 seconds, from 3 to 7, and so on.
Type: StringMinimum characters: 1Maximum characters: 7000resolutionOptionalVideo quality. 2K is more detailed, a second costs more.
Type: StringAllowed values:768P2KDefault:"768P"durationOptionalVideo length in seconds, 4 to 15. The price is per second.
Type: IntegerMinimum: 4Maximum: 15Default:6aspect_ratioOptionalFrame shape: from cinematic 21:9 to portrait 9:16.
Type: StringAllowed values:21:916:94:31:13:49:16Default:"16:9"
Parameters not listed here are not accepted: the response is 422 unknown_setting.
The API sets these settings itself, do not send them: files_as_is = true
Input
Request example
Send this JSON to POST /v1/tasks with your API key. To check the price first, send the same JSON to POST /v1/price.
Video from a prompt
{
"model": "minimax_h3",
"settings": {
"mode": "text_to_video",
"prompt": "Кот медленно идёт по пляжу на закате, волны тихо набегают на берег",
"resolution": "768P",
"aspect_ratio": "16:9",
"duration": 6
}
}The price is calculated when the task is accepted, currency RUB.
Output
- One MP4 video with sound: the model makes the sound itself.
- Generation usually takes 1 to 10 minutes.
| Kind | Formats | How many | Note |
|---|---|---|---|
video | mp4 | 1 |
A finished task as GET /v1/tasks/{id} returns it (some fields left out). The caption may sit on the task or on a single file and may be empty; the model picks the file name.
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"status": "succeeded",
"finished_at": "2026-10-01T12:03:41+00:00",
"result": {
"caption": "Caption of the result: the model and its settings",
"texts": [],
"files_expire_at": "2026-10-08T12:03:41+00:00",
"files_expired": false,
"artifacts": [
{
"index": 0,
"kind": "video",
"filename": "video.mp4",
"size": 12582912,
"caption": "",
"download_path": "/v1/tasks/7c9e6679-7425-40de-944b-e07fc1f90ae7/artifacts/0"
}
]
}
}From frames
The video starts with the first frame. If the last frame is given too, the video ends with it. The video takes the shape of the frames.
Value of the mode field: image_to_video
Price in this mode from 26 ₽.
Parameters
Model parameters go inside settings. Omitted optional fields take their default values.
promptRequiredWhat happens in the video, how the camera moves, what it sounds like. A timed script works too: what happens from 0 to 3 seconds, from 3 to 7, and so on.
Type: StringMinimum characters: 1Maximum characters: 7000resolutionOptionalVideo quality. 2K is more detailed, a second costs more.
Type: StringAllowed values:768P2KDefault:"768P"durationOptionalVideo length in seconds, 4 to 15. The price is per second.
Type: IntegerMinimum: 4Maximum: 15Default:6image_urlsRequiredOne URL: the first frame. Two URLs: the first and the last frames.
Type: List (String, uri)Maximum items: 2
Parameters not listed here are not accepted: the response is 422 unknown_setting.
The API sets these settings itself, do not send them: files_as_is = true
Input
- Pictures are URLs of JPEG, PNG or WebP files up to 30 MB each, sides from 256 to 5,760 pixels, shape from 2:5 to 5:2.
| Field | Accepts | Formats | Files | File size up to |
|---|---|---|---|---|
image_urls | Images | jpeg, jpg, png, webp | 2 | 30 MB |
Request example
Send this JSON to POST /v1/tasks with your API key. To check the price first, send the same JSON to POST /v1/price.
Animate a frame
{
"model": "minimax_h3",
"settings": {
"mode": "image_to_video",
"prompt": "Героиня поворачивается и улыбается, камера медленно наезжает",
"image_urls": [
"https://example.com/first-frame.jpg"
],
"duration": 6
}
}From the first frame to the last
{
"model": "minimax_h3",
"settings": {
"mode": "image_to_video",
"prompt": "Бутон медленно раскрывается в цветок",
"image_urls": [
"https://example.com/bud.jpg",
"https://example.com/flower.jpg"
],
"resolution": "2K",
"duration": 5
}
}The price is calculated when the task is accepted, currency RUB.
Output
- One MP4 video with sound: the model makes the sound itself.
- Generation usually takes 1 to 10 minutes.
| Kind | Formats | How many | Note |
|---|---|---|---|
video | mp4 | 1 |
A finished task as GET /v1/tasks/{id} returns it (some fields left out). The caption may sit on the task or on a single file and may be empty; the model picks the file name.
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"status": "succeeded",
"finished_at": "2026-10-01T12:03:41+00:00",
"result": {
"caption": "Caption of the result: the model and its settings",
"texts": [],
"files_expire_at": "2026-10-08T12:03:41+00:00",
"files_expired": false,
"artifacts": [
{
"index": 0,
"kind": "video",
"filename": "video.mp4",
"size": 12582912,
"caption": "",
"download_path": "/v1/tasks/7c9e6679-7425-40de-944b-e07fc1f90ae7/artifacts/0"
}
]
}
}From references
The model carries characters and objects from the pictures, motion and editing from the videos, voice and rhythm from the audio into a new video. At least one picture or one video is needed.
Value of the mode field: reference_to_video
Price in this mode from 26 ₽.
Parameters
Model parameters go inside settings. Omitted optional fields take their default values.
promptRequiredWhat happens in the video, how the camera moves, what it sounds like. A timed script works too: what happens from 0 to 3 seconds, from 3 to 7, and so on.
Type: StringMinimum characters: 1Maximum characters: 7000resolutionOptionalVideo quality. 2K is more detailed, a second costs more.
Type: StringAllowed values:768P2KDefault:"768P"durationOptionalVideo length in seconds, 4 to 15. The price is per second.
Type: IntegerMinimum: 4Maximum: 15Default:6aspect_ratioOptionalFrame shape. adaptive: the model picks it from the attached files.
Type: StringAllowed values:adaptive21:916:94:31:13:49:16Default:"16:9"image_urlsOptionalUp to 9 URLs of pictures with the characters, objects or style. The first 5 are free, each next one adds to the price.
Type: List (String, uri)Maximum items: 9video_urlsOptionalUp to 3 URLs of videos the model takes motion and editing from. Their seconds are billed like seconds of the result.
Type: List (String, uri)Maximum items: 3audio_urlsOptionalUp to 3 URLs of audio: a voice or music the model matches speech and rhythm to. Free, only together with a picture or a video.
Type: List (String, uri)Maximum items: 3
Parameters not listed here are not accepted: the response is 422 unknown_setting.
The API sets these settings itself, do not send them: files_as_is = true
Input
- Pictures are URLs of JPEG, PNG or WebP files up to 30 MB each, sides from 256 to 5,760 pixels, shape from 2:5 to 5:2.
- Videos are URLs of MP4 or MOV files (H.264 or H.265) up to 50 MB each: each 2 to 15 seconds long, no more than 15 seconds all together, sides from 256 to 5,760 pixels, shape from 2:5 to 5:2, 23.976 to 60 frames per second.
- Audio files are URLs of MP3 or WAV files up to 15 MB each: each 2 to 15 seconds long, no more than 15 seconds all together.
- Videos and audio go to the model whole. The video price follows the length of the files themselves: their seconds are added to the seconds of the result.
- Video and audio lengths are checked before anything goes to the model: if they do not fit, the task ends with a refusal that names the reason and costs nothing.
| Field | Accepts | Formats | Files | File size up to |
|---|---|---|---|---|
image_urls | Images | jpeg, jpg, png, webp | 9 | 30 MB |
video_urls | Video | mp4, mov | 3 | 50 MB |
audio_urls | Audio | mp3, wav | 3 | 15 MB |
Request example
Send this JSON to POST /v1/tasks with your API key. To check the price first, send the same JSON to POST /v1/price.
A character from a picture
{
"model": "minimax_h3",
"settings": {
"mode": "reference_to_video",
"prompt": "Девушка с картинки идёт по ночному городу под дождём",
"image_urls": [
"https://example.com/girl.png"
],
"aspect_ratio": "9:16",
"duration": 6
}
}Motion from a video, music from audio
{
"model": "minimax_h3",
"settings": {
"mode": "reference_to_video",
"prompt": "Девушка с картинки танцует как в видео под музыку из аудио",
"image_urls": [
"https://example.com/girl.png"
],
"video_urls": [
"https://example.com/dance.mp4"
],
"audio_urls": [
"https://example.com/music.mp3"
],
"aspect_ratio": "adaptive",
"duration": 8
}
}The price is calculated when the task is accepted, currency RUB.
Output
- One MP4 video with sound: the model makes the sound itself.
- Generation usually takes 1 to 10 minutes.
| Kind | Formats | How many | Note |
|---|---|---|---|
video | mp4 | 1 |
A finished task as GET /v1/tasks/{id} returns it (some fields left out). The caption may sit on the task or on a single file and may be empty; the model picks the file name.
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"status": "succeeded",
"finished_at": "2026-10-01T12:03:41+00:00",
"result": {
"caption": "Caption of the result: the model and its settings",
"texts": [],
"files_expire_at": "2026-10-08T12:03:41+00:00",
"files_expired": false,
"artifacts": [
{
"index": 0,
"kind": "video",
"filename": "video.mp4",
"size": 12582912,
"caption": "",
"download_path": "/v1/tasks/7c9e6679-7425-40de-944b-e07fc1f90ae7/artifacts/0"
}
]
}
}See also
Try MiniMax H3 (Hailuo 03) through the API
One key opens every CyHUB model. Payment in rubles, and you see the price before the run.
Get an API key