Skip to content
Docs version r8
OpenAPIJSONYAML
Guides / Models

MiniMax H3 API

Every input field of MiniMax H3, the rules between them, the price and a complete request with its responses.

POST/v1/generations"model": "minimax-h3"

Generates a video from one prompt text plus optional image frames, or reference images, videos and audio.

What it does

MiniMax H3 makes a 768P video of 4 to 15 seconds from a prompt and optional media. Everything goes in one list, input.content: exactly one text item carries the prompt, and each image_url, video_url and audio_url item names its role. resolution (always 768P) and duration are required. The items you send choose the mode:

Modecontent itemsOther fields to set
[Text to video](#text-to-video)textratio other than adaptive
[First frame](#first-frame)text, one image_url with role first_frame—
[First and last frame](#first-and-last-frame)text, first_frame and last_frame images—
[Reference images](#reference-images)text, 1 to 5 image_url with role reference_image—
[Reference video and audio](#reference-video-and-audio)text, any mix of reference images, up to 3 video_url with role reference_video, up to 3 audio_url with role reference_audio—

Every example below is a complete body for POST /v1/generations. Send the same body to POST /v1/estimates first: it is free, creates no task, holds no Credits, and refuses an invalid body with the same 422 as a create. The https://media.vizoapi.com/... files are public samples, so the examples run as they are; replace https://example.com/... with your own file or an uploaded ast_... asset ID.

Modes

Text to video

Only the text item. Set ratio to 21:9, 16:9, 4:3, 1:1, 3:4 or 9:16: without media, adaptive or no ratio is refused (rule ratio_required).

Text to video
{
  "model": "minimax-h3",
  "input": {
    "content": [
      { "type": "text", "text": "A paper boat drifts across a still pond at dawn, mist on the water, slow push-in, soft natural light" }
    ],
    "resolution": "768P",
    "duration": 6,
    "ratio": "16:9"
  }
}

First frame

The video starts on your image. Send one image_url with role first_frame. The output always takes the image's shape: with frames, any ratio you send is replaced by adaptive. The prompt describes what happens next.

First frame
{
  "model": "minimax-h3",
  "input": {
    "content": [
      { "type": "text", "text": "The hominids step back as the sun rises behind the monolith, slow push-in" },
      { "type": "image_url", "role": "first_frame", "image_url": { "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/monolith.jpg" } }
    ],
    "resolution": "768P",
    "duration": 6
  }
}

First and last frame

The video moves from the first image to the last. Send at most one first_frame and one last_frame (rule frame_repeated). Frames cannot be combined with any reference image, video or audio (rule frames_with_references).

First and last frame
{
  "model": "minimax-h3",
  "input": {
    "content": [
      { "type": "text", "text": "The ring-shaped station slowly turns to face the camera as an amber planet rises behind it" },
      { "type": "image_url", "role": "first_frame", "image_url": { "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/station.jpg" } },
      { "type": "image_url", "role": "last_frame", "image_url": { "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/ending.jpg" } }
    ],
    "resolution": "768P",
    "duration": 6
  }
}

Reference images

Up to 5 images with role reference_image give the model characters, objects, places or a style to reuse; they do not fix any frame (rule too_many_images, which counts every image). ratio is optional: adaptive (the default) follows the input, or pick a fixed one.

Reference images
{
  "model": "minimax-h3",
  "input": {
    "content": [
      { "type": "text", "text": "Shot 1: the black monolith from image 1 stands on a savanna at dawn. Shot 2: match cut to the ring-shaped space station from image 2, tumbling slowly in black space." },
      { "type": "image_url", "role": "reference_image", "image_url": { "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/monolith.jpg" } },
      { "type": "image_url", "role": "reference_image", "image_url": { "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/station.jpg" } }
    ],
    "resolution": "768P",
    "duration": 8,
    "ratio": "16:9"
  }
}

Reference video and audio

Reference videos give motion, camera movement or a subject; reference audio gives a voice, rhythm or sound. Send up to 3 videos (rule too_many_videos), each 2 to 15 seconds and 15 seconds together, and up to 3 audio items (rule too_many_audios), 15 seconds together. They mix freely with reference images. Any video_url moves the task to the 768p-video tier, which bills the input video's seconds too (see [How it is billed](#how-it-is-billed)); audio never changes the tier.

Reference video

{
  "model": "minimax-h3",
  "input": {
    "content": [
      { "type": "text", "text": "Follow the camera movement and pacing of video 1, set on the space station from image 1" },
      { "type": "image_url", "role": "reference_image", "image_url": { "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/keyframes/station.jpg" } },
      { "type": "video_url", "role": "reference_video", "video_url": { "url": "https://media.vizoapi.com/samples/seedance-2-5/odyssey-v1/1.mp4" } }
    ],
    "resolution": "768P",
    "duration": 5,
    "ratio": "16:9"
  }
}

Reference audio

{
  "model": "minimax-h3",
  "input": {
    "content": [
      { "type": "text", "text": "The astronaut from image 1 speaks to the camera inside the station, in the voice of audio 1" },
      { "type": "image_url", "role": "reference_image", "image_url": { "url": "https://example.com/astronaut.png" } },
      { "type": "audio_url", "role": "reference_audio", "audio_url": { "url": "https://example.com/voice.mp3" } }
    ],
    "resolution": "768P",
    "duration": 8,
    "ratio": "16:9"
  }
}

Input limits

LimitValueChecked
content items1 to 16. Exactly one text item; up to 5 images, 3 videos and 3 audio itemsAt create, 422 invalid_input (too_many_items, too_few_items, text_count, too_many_images, too_many_videos, too_many_audios)
PromptUp to 7,000 charactersAt create (out_of_range)
RolesEvery image, video and audio item needs role: first_frame, last_frame or reference_image for images, reference_video for video, reference_audio for audio. Frames (one of each at most) never mix with referencesAt create (role_required, role_not_allowed, frame_repeated, frames_with_references)
Each video2 to 15 secondsAt create when the file's length can be read, 422 input_duration_out_of_range (video_length); otherwise when the task runs
All videos togetherAt most 15 secondsSame, rule video_total_too_long
All audio togetherAt most 15 secondsSame, rule audio_total_too_long
Image filePNG, JPEG, WebP, HEIC; up to 30 MBAt create when readable: 422 input_media_invalid (format) or input_media_too_large (size)
Video fileMP4, MOV; up to 50 MBSame
Audio fileMP3, WAV; up to 15 MBSame
Uploaded assetimage/png, image/jpeg, image/webp, video/mp4, audio/mpeg, audio/wav; up to 20,000,000 bytesWhen you request the upload, 422
Image 256 to 5,760 pixels per side and aspect ratio 0.4 to 2.5; each audio item 2 to 15 secondsChecked by the model onlyWhen the task runs: the task fails with generation_failed and is not charged

A media value is a public https URL (up to 4,000 characters) or an ast_... asset ID from your project. Plain http, private or local addresses, URLs with a user name or #fragment, and Base64 data are refused with 422 (rule bad_format). The model fetches a linked file itself, possibly some time after acceptance, so keep it reachable until the task closes. See Model inputs and media.

Output

SettingValues
resolutionRequired, only 768P (case-sensitive)
durationRequired, 4 to 15 seconds. There is no automatic length
ratioadaptive (default), 21:9, 16:9, 4:3, 1:1, 3:4 or 9:16. Text alone needs a fixed ratio; with frames it is always adaptive
aigc_watermarkfalse (default) or true for a visible AI-generated mark. The price is the same

A succeeded task lists one MP4 in result.outputs: take its asset_id and get a download URL with download an asset. Outputs are kept for 7 days. See Get results.

How it is billed

The input selects the tier: 768p, or 768p-video when content has any video_url. Both have the same rate per second, but the video tier also bills the input video's seconds. Images and audio never change the tier or the price, and neither do ratio or aigc_watermark.

TierCredits per secondSeconds billed
768p18Output seconds
768p-video18Output + input seconds

Input seconds are the length of all videos together, rounded up, at most 15. When a video's length cannot be read at create, the hold counts 15 input seconds. The sample video in the examples runs 12.06 seconds, so it holds 13 input seconds.

RequestOutputInputBilledHeld (Credits)
Text, frames or reference images, duration: 66—6108.000
The same, duration: 1515—15270.000
Reference video of 12.06 s, duration: 551318324.000
The same, video length not readable51520360.000

The hold is only the estimate. A succeeded task is charged for the output seconds the model reports, plus its reported input seconds on the video tier, to the millisecond, at the tier's rate. So price.charged can be below the hold (the rest is released) or above it, with no cap. When the model reports no output length, or on the video tier the input length is known neither from the model nor from the create, the charge is the hold. Usage above the hold comes from your available balance; what it cannot cover is owed, and new creates get 402 balance_negative until a top-up. A failed or unresolved task is not charged. Send the body to POST /v1/estimates to see the exact hold and its basis (output_seconds, input_seconds, billed_seconds). See Billing.

Errors and behaviors

WhenResponseWhat to do
A field the schema does not list, a wrong value or type, no resolution or duration422 invalid_input, errors[].rule such as field_not_allowed, value_not_allowed, out_of_range, requiredSend only the fields in the reference below
More than 16 content items, or an empty list422 invalid_input, rule too_many_items or too_few_itemsSend 1 to 16 items
A content rule is broken422 invalid_input with the rule: text_count, role_required, role_not_allowed, frame_repeated, frames_with_references, too_many_images, too_many_videos, too_many_audiosFix the item at errors[].path
Text alone with ratio adaptive or none422 invalid_input, rule ratio_requiredSet a fixed ratio
A measured video is too short or too long, or measured videos or audio are too long in total422 input_duration_out_of_range; errors[] names the item (/content/N/video_url/url, rule video_length) or the total (/content, rule video_total_too_long or audio_total_too_long)Trim the media
A linked file has the wrong format or is too large422 input_media_invalid or input_media_too_largeConvert or shrink it
Content safety refuses the prompt or mediaTask fails with input_moderated when the model reports a safety refusal; otherwise generation_failedChange the prompt or media; nothing is charged
Content safety refuses the resultTask fails with output_moderated when the model reports a safety refusal; otherwise generation_failed; no resultChange the prompt; nothing is charged
The model refuses the request when it is sentTask fails with generation_failedCheck the body against the limits above; nothing is charged
The model refuses a file or setting when the task runs, or cannot fetch a URLTask fails with generation_failed; input_media_invalid or input_media_unreachable when the model names that causeCheck the media against the limits above and keep URLs public; nothing is charged
The model fails for another reasonTask fails with generation_failedRetry, or change the prompt; nothing is charged

Moderation is always on; no field turns it off. Each task has a deadline of 24 hours from acceptance. A task still unfinished then closes as unresolved, releases its hold and is not charged; if its result arrives later, it is added at no charge and late_result_available becomes true. See Errors and Get results.

Prompting tips

  • Name reference media by kind and order in content: "image 1", "image 2", "video 1", "audio 1". Say what to take from each: "the character from image 1", "the camera movement of video 1", "the voice of audio 1".
  • Write the shot, not just the subject: subject, action, setting, camera movement, light and style, in that order.
  • With first and last frames, describe the motion between them; the frames already fix the start and end, and the shape follows the first image.
  • Always set ratio for a prompt alone: without media, adaptive is refused.
  • Videos are at most 15 seconds: for a longer piece, generate several shots and join them, with a still from the end of one shot as the next shot's first_frame.

Pricing

Your input selects the tier. Video is billed per second of output; a tier with input video also counts the input seconds.

TierSelected byPriceLength
768presolution = 768p18 Credits/s4–15 s
768p-videoresolution = 768p, input video18 Credits/s4–15 s

Rules

  • content holds exactly one text item.
  • Every image, video and audio item in content names its role.
  • Frames (first_frame, last_frame, at most one each) cannot be combined with reference images, videos or audio.
  • Input without images, videos or audio needs a ratio other than adaptive; input with frames always uses adaptive.
  • resolution is case-sensitive: send 768P.

Input fields

Send these fields in input. A field the table does not list is refused with HTTP 422 invalid_input.

Input fields
FieldDescription
contentarray of objectsRequired

Exactly one text item. Frames (first_frame, last_frame, at most 1 each) cannot be combined with references. Up to 5 images, 3 videos (2 to 15 seconds each, 15 in total) and 3 audios (15 seconds in total).

At least 1 items · At most 16 items

content[].typestringRequired

Item kind.

Allowed valuestextimage_urlvideo_urlaudio_url
Items where type is text
content[].textstringRequired

Prompt text, up to 7000 characters.

At most 7000 characters

Items where type is image_url
content[].rolestringOptional

Image roles: first_frame, last_frame, reference_image. Video: reference_video. Audio: reference_audio.

content[].image_urlobjectRequired
content[].image_url.urlstringRequired

An https URL or an uploaded asset id (ast_...).

At most 4000 characters · Pattern^(https://|ast_)

Items where type is video_url
content[].rolestringOptional

Image roles: first_frame, last_frame, reference_image. Video: reference_video. Audio: reference_audio.

content[].video_urlobjectRequired
content[].video_url.urlstringRequired

An https URL or an uploaded asset id (ast_...).

At most 4000 characters · Pattern^(https://|ast_)

Items where type is audio_url
content[].rolestringOptional

Image roles: first_frame, last_frame, reference_image. Video: reference_video. Audio: reference_audio.

content[].audio_urlobjectRequired
content[].audio_url.urlstringRequired

An https URL or an uploaded asset id (ast_...).

At most 4000 characters · Pattern^(https://|ast_)

resolutionstringRequired

Output resolution. Only 768P.

Only 768P

durationintegerRequired

Output length in seconds, 4 to 15.

Minimum 4 · Maximum 15

ratiostringOptional

Output aspect ratio. Text-only input needs a value other than adaptive; input with frames always uses adaptive.

Allowed valuesadaptive21:916:94:31:13:49:16

Default adaptive

aigc_watermarkbooleanOptional

Add a visible watermark. Defaults to false; the tier price is unchanged.

Default false

Example

A complete create request, the 202 answer and the task once it has succeeded.

Request

cURL

curl https://api.vizoapi.com/v1/generations \
  -H "Authorization: Bearer $VIZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "minimax-h3",
  "input": {
    "content": [
      {
        "type": "text",
        "text": "A paper boat drifting on a pond at dawn, slow dolly in"
      }
    ],
    "resolution": "768P",
    "ratio": "16:9",
    "duration": 6
  },
  "metadata": {
    "client_reference": "my-unique-reference-1"
  }
}'

Python

import os, requests

# Send once: do not retry this request automatically.
task = requests.post(
    "https://api.vizoapi.com/v1/generations",
    headers={"Authorization": f"Bearer {os.environ['VIZO_API_KEY']}"},
    json={
      "model": "minimax-h3",
      "input": {
        "content": [
          {
            "type": "text",
            "text": "A paper boat drifting on a pond at dawn, slow dolly in"
          }
        ],
        "resolution": "768P",
        "ratio": "16:9",
        "duration": 6
      },
      "metadata": {
        "client_reference": "my-unique-reference-1"
      }
    },
    timeout=60,
).json()
print(task["id"], task["status"])

Node.js

// Send once: do not retry this request automatically.
const res = await fetch("https://api.vizoapi.com/v1/generations", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.VIZO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "minimax-h3",
    "input": {
      "content": [
        {
          "type": "text",
          "text": "A paper boat drifting on a pond at dawn, slow dolly in"
        }
      ],
      "resolution": "768P",
      "ratio": "16:9",
      "duration": 6
    },
    "metadata": {
      "client_reference": "my-unique-reference-1"
    }
  }),
});
const task = await res.json();
console.log(task.id, task.status);

This input selects the 768p tier at 18 Credits per second. For 6 seconds the API holds 108.000 Credits.

Response

202 Accepted

{
  "id": "gen_01JD8Z5QW3XR",
  "model": "minimax-h3",
  "source": "api",
  "created_at": "2026-11-08T09:00:00Z",
  "customer_resolution_deadline": "2026-11-09T09:00:00Z",
  "late_result_available": false,
  "metadata": {
    "client_reference": "my-unique-reference-1"
  },
  "status": "processing",
  "execution_status": "processing",
  "delivery_status": "pending",
  "billing_status": "pending",
  "version": 1,
  "price": {
    "unit": "credit",
    "estimated": "108.000",
    "reserved": "0.000",
    "charged": "0.000",
    "refunded": "0.000"
  },
  "allowed_actions": [],
  "closed_at": null,
  "error": null,
  "result": null
}

200 Succeeded

{
  "id": "gen_01JD8Z5QW3XR",
  "model": "minimax-h3",
  "source": "api",
  "created_at": "2026-11-08T09:00:00Z",
  "customer_resolution_deadline": "2026-11-09T09:00:00Z",
  "late_result_available": false,
  "metadata": {
    "client_reference": "my-unique-reference-1"
  },
  "status": "succeeded",
  "execution_status": "succeeded",
  "delivery_status": "ready",
  "billing_status": "settled",
  "version": 4,
  "price": {
    "unit": "credit",
    "estimated": "108.000",
    "reserved": "0.000",
    "charged": "108.000",
    "refunded": "0.000"
  },
  "allowed_actions": [],
  "closed_at": "2026-11-08T09:01:31Z",
  "error": null,
  "result": {
    "asset_id": "ast_01JD8Z9M2C4V",
    "outputs": [
      {
        "index": 0,
        "asset_id": "ast_01JD8Z9M2C4V",
        "content_type": "video/mp4"
      }
    ]
  }
}