MiniMax Hailuo: video generation API
Generate video with MiniMax Hailuo H3 / H3 Max / H3 Self-hosted: parameters, results, and caveats.
| Item | Value |
|---|---|
| Base URL | https://api.hop-base.com/v1 |
| Submit a task | POST /v1/video/generate |
| Query a task | GET /v1/video/tasks/{task_id} |
| List tasks | GET /v1/video/tasks |
| Key group | H3 "MiniMax H3 Official", H3-Max "MiniMax H3 Max Official", H3-SelfHosted "MiniMax H3 Self-hosted", H3-Max also "MiniMax H3 Max Cloud" |
Available models
| Model ID | Resolution | Duration | Reference input | Official price |
|---|---|---|---|---|
MiniMax-H3 | 768P / 2K | integer 4-15 s | up to 9 images, 3 video clips, 3 audio tracks | $0.08from/ second |
MiniMax-H3-Max | 480P / 768P | integer 5-15 s | not supported — text and first/last-frame only | $0.05from/ second |
MiniMax-H3-SelfHosted | 480P / 768P / 1080P / 2K / 4K | integer 4-15 s | up to 9 images, 3 video clips, 3 audio tracks | $0.0437from/ second |
Use the exact IDs MiniMax-H3 / MiniMax-H3-Max / MiniMax-H3-SelfHosted: no aliases are registered and unknown model names are rejected. H3-Max is the fast variant — a 5-second clip typically renders in a few seconds. Tiered prices and full specs are on the model cards MiniMax-H3 and MiniMax-H3-Max.
MiniMax-H3-SelfHosted is a self-hosted deployment of Hailuo H3 that matches H3's output quality at a lower price. It takes the same request contract as MiniMax-H3, with these differences: it adds 480P, 1080P, and 4K (the full list is in the table above); reference videos and audio must be public http(s) URLs, and data: embeds are rejected (images may still be embedded); a typical clip takes 3-6 minutes. It is served by the MiniMax H3 Self-hosted group and is listed under the Self-hosted category in the console. Specs and tiered prices are on the MiniMax-H3-SelfHosted model card.
MiniMax-H3 and MiniMax-H3-Max are served by two separate groups — MiniMax H3 Official and MiniMax H3 Max Official — and speech-2.8-hd / speech-2.8-turbo by a third, MiniMax Speech Official; see the Text-to-speech API. MiniMax-H3-SelfHosted is served by MiniMax H3 Self-hosted, and MiniMax-H3-Max is also available in MiniMax H3 Max Cloud (the same official model at a different price).
A key reaches only the models of the groups it includes; add both groups to one key if you need H3 and H3-Max. Before sending paid work, confirm which models your key reaches with GET /v1/models.
Request parameters
HopBase exposes MiniMax Hailuo H3 through the official MiniMax v2 contract. The body mirrors MiniMax's official POST /v2/video_generation request and is decoded strictly: unknown fields and a second JSON value are rejected before the request goes out.
Only the top-level fields below are accepted; anything else, including OpenAI's prompt / size / n / seconds / image, returns 400.
| Parameter | Required | Type & limits | Default | Description |
|---|---|---|---|---|
model | Required | MiniMax-H3 / MiniMax-H3-Max / MiniMax-H3-SelfHosted | — | Exact ID |
content | Required | array: exactly 1 text element plus optional media elements (next table) | — | Prompt and media |
resolution | Required | H3: 768P / 2K; H3-Max: 480P / 768P; H3-SelfHosted: 480P / 768P / 1080P / 2K / 4K | — | Also selects the billing tier |
duration | Required | integer seconds; H3: 4-15; H3-Max: 5-15; H3-SelfHosted: 4-15 | — | There is no automatic length |
ratio | Text-to-video only | 21:9 / 16:9 / 4:3 / 1:1 / 3:4 / 9:16 / adaptive | reference mode: adaptive | Text-to-video rejects adaptive |
aigc_watermark | Optional | boolean | off | Adds an AI-content watermark |
callback_url | — | not supported | — | Returns 400; poll the task instead |
First/last-frame mode accepts any valid ratio and always outputs adaptive (follows the image); crop the frame first for a specific ratio. All requests use Authorization: Bearer sk-your-key and Content-Type: application/json.
content elements
| Element | Required | Type & limits | Default | Description |
|---|---|---|---|---|
text | Required | exactly 1; 1-7,000 characters | — | The prompt |
image_url | Optional | role first_frame / last_frame (≤1 each) or reference_image (H3 / H3-SelfHosted only, ≤9) | role: first_frame | In reference mode, set "role": "reference_image" on every image |
video_url | Optional | H3 / H3-SelfHosted only; explicit role: "reference_video"; ≤3 clips | — | Billed on its input duration |
audio_url | Only with an image or video reference | H3 / H3-SelfHosted only; explicit role: "reference_audio"; ≤3 tracks | — | Cannot be the only reference input |
Counts, roles, and combinations are checked at submission; file size, dimensions, codec, and duration are checked by MiniMax during execution. First/last-frame elements and reference_* elements are mutually exclusive, and one request carries at most 12 media files in total.
Media url values accept an absolute public http(s) URL or a data: URI (base64). mm_file:// is rejected — the file belongs to your own MiniMax account, which the gateway cannot access. For MiniMax-H3-SelfHosted, video_url and audio_url must be public http(s) URLs; data: is accepted for images only.
Media specifications
| Media | Formats | Size each | Dimensions / duration |
|---|---|---|---|
| Image | JPG / JPEG / PNG / WEBP / HEIC / HEIF | ≤30 MB | 256-5760 px per side, aspect 5:2 to 2:5 |
| Video | H.264 / H.265 | ≤50 MB | 2-15 s each, ≤15 s combined |
| Audio | WAV / MP3 | ≤15 MB | 2-15 s each, ≤15 s combined |
Output and request size
- Output is 24 FPS, and every clip ships with native stereo audio.
- Dialogue and voice-over are generated in-model, with TTS covering 11 languages (Chinese, English, Japanese, Korean, French, German, Spanish and more).
2Kmeans a 1440-pixel short side for ratios between 16:9 and 9:16; wider ratios keep ≈3.7M total pixels, e.g. 21:9 → 2976×1248.768Pfollows the same rule at 768 px / ≈1M pixels.- The whole JSON body is capped at 64 MiB, with
413above it. - base64 inflates data by about 4/3 and
data:embeds do not relax the count or duration limits, so use URLs for large media.
Response
MiniMax task fields sit at the top level of the response, with no task wrapper.
Submit response
The submission responds with 202 and a HopBase task ID:
{
"id": "mmt60x430684635582774",
"object": "video.generation.task",
"model": "MiniMax-H3",
"status": "queued",
"billing_bucket": "2k"
}Task query fields
| Field | Description |
|---|---|
id | HopBase task ID, mmt… |
status | queued → processing → completed | failed |
outputs | Output URLs; valid for 24 hours after completion |
error.message | Failure reason in English; no error code |
usage.bucket | Billing tier |
usage.billed_seconds | Billed seconds |
usage.input_seconds | Reference video input seconds |
usage.extra_input_images | Reference images past the free allowance |
usage.cost / usage.cost_usd / usage.currency | The charge for this task: cost_usd is the USD amount actually deducted from your balance, cost is the same charge in CNY, and currency is always CNY |
Only completed and failed are terminal, so treat any other value as still running. A typical clip completes in 1.5-3 minutes.
In progress
{
"id": "mmt60x430684635582774",
"status": "processing"
}Succeeded
{
"id": "mmt60x430684635582774",
"status": "completed",
"outputs": ["https://api.hop-base.com/..."],
"usage": { "bucket": "2k", "billed_seconds": 4, "input_seconds": 0, "extra_input_images": 0, "cost": 3.4, "cost_usd": 0.5, "currency": "CNY" }
}Failed
A failed task has no error code, so read error.message (async task failures):
{ "id": "mmt60x...", "status": "failed", "error": { "message": "..." } }Minimal example
# 1. Submit; text-to-video requires ratio
curl https://api.hop-base.com/v1/video/generate \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{
"model": "MiniMax-H3",
"content": [{
"type": "text",
"text": "Aerial shot of snow mountains above clouds at sunrise"
}],
"resolution": "2K",
"duration": 4,
"ratio": "16:9"
}'
# 2. Poll with the returned id
curl https://api.hop-base.com/v1/video/tasks/mmt-your-task-id \
-H "Authorization: Bearer sk-your-key"For image-to-video, put the first frame in content:
{
"model": "MiniMax-H3",
"content": [
{ "type": "text", "text": "The camera slowly pushes in, light drifting across the scene" },
{ "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,..." }, "role": "first_frame" }
],
"resolution": "768P",
"duration": 4
}Notes
Reference media is downloaded on MiniMax's side, not by HopBase. Image hosts that block datacenter IPs (many free image CDNs do) cause the task to fail minutes after submission, so prefer data: embeds or your own object storage / CDN.
- An
image_urlwithoutrolecounts as a first frame, so in reference mode set"role": "reference_image"on every image. - A task still unfinished 2 hours after creation is failed automatically, and MiniMax tasks cannot be cancelled.
outputsis a signed URL onapi.hop-base.com, valid for 24 hours from the moment the task completes. Querying again returns the same URL without extending it, and an expired URL returns 410, so download results within that window.
Common errors and fixes
The gateway's own checks return {"error":{"message":…,"type":"invalid_request_error"}} without code; rely on message.
| Status | Cause / what to do |
|---|---|
| 400 | Invalid field or value; fix the field named in message |
| 400 / 404 / 422 | Rejected at submission (422 = sensitive content); fix the input or rewrite the prompt |
| 413 | Request body too large; use URLs, not data: |
| 404 | Malformed task ID or task not found |
| 429 | Rate limited; retry after Retry-After |
Common 400 texts and the 413 / 404 texts:
400 first/last-frame image-to-video and multimodal reference generation are mutually exclusive: ...
400 {"error":{"message":"request body does not match the JSON contract: json: unknown field \"prompt\"","type":"invalid_request_error"}}
400 callback_url is not supported yet; poll /v1/video/tasks/{id} for task progress
request body exceeds the 64 MiB limit (got N bytes)
invalid task ID format
task not found # also returned for another user's keyThe first usually means a reference-mode image is missing its role; the second means a top-level prompt was sent — put the prompt in content.
For failed tasks, act on error.message:
| message | What to do |
|---|---|
Names a parameter, media, or content problem (invalid request parameters: ...) | Fix it and resubmit |
... declined by content moderation ...... blocked by content moderation ... | Rewrite the prompt or replace the media |
video generation failed ...... stopped before completion ...... finished without a usable video ... | Resubmit; contact support if it repeats |
... did not finish within 2 hours ... | Resubmit; contact support with the task ID if it repeats |
Billing
MiniMax bills both models per second of video at a rate that follows the output resolution, not by token:
charge = usage.billed_seconds × the rate for the usage.bucket tier- A reference video is billed on its input duration at that same rate — MiniMax's own
input_seconds. - Reference images are free up to an allowance, with
usage.extra_input_imagescounting the ones past it. - For H3-Max, MiniMax bills output video only and does not charge for input material.
- For H3-SelfHosted, a reference video's input duration is rounded up to whole seconds and billed at the output tier's rate; reference images past 5 are billed per image.
A MiniMax submit checks available balance minus the estimates for in-flight tasks minus this request's own estimate; if that falls short you get a 402 with code insufficient_balance, and the estimate is released automatically once the task ends. A failed task is never billed. Once the task finishes, the query's top-level usage also carries cost_usd (the USD amount actually deducted from your balance for this task, 0 for an uncharged failure), cost (the same charge in CNY), and currency (always CNY).
Official list prices are on the pricing page. Your own rate is the one shown in the signed-in model catalog, and each request's actual charge is in your usage record. See the Video overview for the rules shared by every video family.
Next steps
- Video overview — how the video families compare, plus the balance holds, timeouts, and result URLs they share
- Text-to-speech API — MiniMax Speech 2.8 and voice cloning
- Error codes and retries — including async task failures
- Concurrency, timeouts, and billing