MiniMax H3 API Guide: Create, Poll, and Download Video

MiniMax H3
|
Published on Aug 2, 2026

Quick answer

The official MiniMax H3 API uses an asynchronous V2 workflow. Send a POST request to https://api.minimax.io/v2/video_generation with the model ID MiniMax-H3, a required content[] array, resolution: "2K", an integer duration from 4 to 15 seconds, and a valid ratio for the selected mode. The response gives you a task_id. Poll GET https://api.minimax.io/v2/query/video_generation/{task_id} about every 10 seconds until the status becomes succeeded or reaches a terminal failure state. A successful task returns the video URL directly in task.content.url; H3 V2 does not require the older file_id retrieval step.

Keep the API key on your server and send it as Authorization: Bearer <API_KEY>. The current pay-as-you-go list price for H3 at 2K is $0.13 per output second. The examples below follow the official schema checked on August 2, 2026. They were not sent as paid generation requests. minimaxh3.tv is an independent website, not MiniMax's official API service.

MiniMax H3 V2 API create, poll, and result workflow

The V2 API returns a task_id after creation. Poll until the task succeeds or reaches a terminal failure state; only a successful task exposes content.url. Diagram based on the official V2 guide, checked August 2, 2026.

Prerequisites and API key

Create a pay-as-you-go key in the MiniMax API Platform under Account Management > API Keys, then keep it in a server-side environment variable. MiniMax separates standard pay-as-you-go keys from Token Plan or Credits keys, so confirm which balance the key uses before sending a paid video request.

export MINIMAX_API_KEY="replace-with-your-server-side-key"

Every create and query request uses the same header:

Authorization: Bearer <API_KEY>

Do not place the key in browser JavaScript, a mobile bundle, a public repository, screenshots, or client-visible logs. Route browser requests through your own authenticated backend and enforce per-user quotas there.

H3 model ID and modes

The official V2 model ID is MiniMax-H3. The API uses one endpoint and changes the generation mode according to the objects and roles inside content[].

Mode Required content[] items Ratio behavior
Text to video One non-empty text item Required; choose 21:9, 16:9, 4:3, 1:1, 3:4, or 9:16
First or last frame text plus one or two image_url items using first_frame and/or last_frame Input image determines the ratio; the API treats it as adaptive
Reference generation text plus reference_image, reference_video, or reference_audio items Optional; defaults to adaptive

Every request needs a non-empty text item. Reference audio cannot be the only reference; include at least one reference image or video. Frame roles and reference roles are mutually exclusive in one request.

MiniMax H3 content array modes for text, frame, and reference generation

Valid content[] families for H3 V2. Text is always required. Frame roles cannot be mixed with reference roles, and reference audio needs an image or video beside it. Checked against the official create-task schema on August 2, 2026.

Create a video task

This minimal cURL request creates a five-second, 2K, 16:9 text-to-video task:

curl --request POST \
  --url https://api.minimax.io/v2/video_generation \
  --header "Authorization: Bearer ${MINIMAX_API_KEY}" \
  --header "Content-Type: application/json" \
  --data '{
    "model": "MiniMax-H3",
    "content": [
      {
        "type": "text",
        "text": "A paper boat crosses a rain-filled street while the camera tracks beside it."
      }
    ],
    "resolution": "2K",
    "duration": 5,
    "ratio": "16:9"
  }'

A successful create response contains the task identifier:

{
  "task_id": "424010985738629"
}

Store that ID before returning control to your client. Your database record should also keep the user, request fingerprint, submission time, and current state so an application restart does not lose the job.

Poll task status

Query the V2 task endpoint with the returned ID:

curl --request GET \
  --url "https://api.minimax.io/v2/query/video_generation/${TASK_ID}" \
  --header "Authorization: Bearer ${MINIMAX_API_KEY}"

MiniMax's guide recommends a 10-second polling interval. Handle these states explicitly:

Status Application action
queued Wait and poll again
running Wait and poll again
succeeded Read task.content.url and save the result
failed Stop and record task.error
cancelled Stop; do not keep polling
expired Stop; the task no longer has a usable result

Use a maximum wait time in your application rather than polling forever. A local timeout does not prove the upstream task failed, so keep the task_id and allow later reconciliation.

Download the result

H3 V2 returns the result URL inside the successful query response:

{
  "task": {
    "id": "424010985738629",
    "model": "MiniMax-H3",
    "status": "succeeded",
    "content": {
      "url": "https://example-cdn.invalid/generated-video.mp4"
    },
    "resolution": "2K",
    "duration": 5,
    "ratio": "16:9"
  }
}

Fetch that time-limited URL from your backend and save the bytes promptly to storage you control. Do not build the H3 V2 flow around the older V1 /v1/files/retrieve endpoint; the current V2 query response already contains content.url.

Python example

import os
import time
from pathlib import Path

import requests

BASE_URL = "https://api.minimax.io"
API_KEY = os.environ["MINIMAX_API_KEY"]
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}


def create_task() -> str:
    payload = {
        "model": "MiniMax-H3",
        "content": [
            {
                "type": "text",
                "text": "A paper boat crosses a rain-filled street while the camera tracks beside it.",
            }
        ],
        "resolution": "2K",
        "duration": 5,
        "ratio": "16:9",
    }
    response = requests.post(
        f"{BASE_URL}/v2/video_generation",
        headers=HEADERS,
        json=payload,
        timeout=30,
    )
    response.raise_for_status()
    return response.json()["task_id"]


def wait_for_result(task_id: str, timeout_seconds: int = 1800) -> str:
    deadline = time.monotonic() + timeout_seconds
    while time.monotonic() < deadline:
        time.sleep(10)
        response = requests.get(
            f"{BASE_URL}/v2/query/video_generation/{task_id}",
            headers={"Authorization": f"Bearer {API_KEY}"},
            timeout=30,
        )
        response.raise_for_status()
        task = response.json()["task"]
        if task["status"] == "succeeded":
            return task["content"]["url"]
        if task["status"] in {"failed", "cancelled", "expired"}:
            raise RuntimeError(f"Task ended with {task['status']}: {task.get('error')}")
    raise TimeoutError(f"Task {task_id} did not finish before the local timeout")


def save_video(url: str, destination: str = "output.mp4") -> None:
    with requests.get(url, stream=True, timeout=120) as response:
        response.raise_for_status()
        with Path(destination).open("wb") as output:
            for chunk in response.iter_content(chunk_size=1024 * 1024):
                output.write(chunk)


task_id = create_task()
save_video(wait_for_result(task_id))

JavaScript example

This version uses the built-in fetch available in current Node.js releases:

import { writeFile } from "node:fs/promises";

const baseUrl = "https://api.minimax.io";
const apiKey = process.env.MINIMAX_API_KEY;

if (!apiKey) throw new Error("MINIMAX_API_KEY is missing");

async function requestJson(url, options = {}) {
  const response = await fetch(url, options);
  if (!response.ok) {
    throw new Error(`${response.status}: ${await response.text()}`);
  }
  return response.json();
}

async function createTask() {
  const data = await requestJson(`${baseUrl}/v2/video_generation`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "MiniMax-H3",
      content: [
        {
          type: "text",
          text: "A paper boat crosses a rain-filled street while the camera tracks beside it.",
        },
      ],
      resolution: "2K",
      duration: 5,
      ratio: "16:9",
    }),
  });
  return data.task_id;
}

async function waitForResult(taskId) {
  for (let attempt = 0; attempt < 180; attempt += 1) {
    await new Promise((resolve) => setTimeout(resolve, 10_000));
    const data = await requestJson(
      `${baseUrl}/v2/query/video_generation/${taskId}`,
      { headers: { Authorization: `Bearer ${apiKey}` } },
    );
    const { status, content, error } = data.task;
    if (status === "succeeded") return content.url;
    if (["failed", "cancelled", "expired"].includes(status)) {
      throw new Error(`Task ended with ${status}: ${JSON.stringify(error)}`);
    }
  }
  throw new Error(`Task ${taskId} exceeded the local wait limit`);
}

const taskId = await createTask();
const videoUrl = await waitForResult(taskId);
const videoResponse = await fetch(videoUrl);
if (!videoResponse.ok) throw new Error(`Download failed: ${videoResponse.status}`);
await writeFile("output.mp4", Buffer.from(await videoResponse.arrayBuffer()));

Text, frame, and reference payload differences

The content[] array replaces separate H3 model IDs for each mode. Use the same MiniMax-H3 model value and change the roles.

First and last frame

{
  "model": "MiniMax-H3",
  "content": [
    { "type": "text", "text": "The paper sketch becomes a finished product render." },
    {
      "type": "image_url",
      "image_url": { "url": "https://example.com/start.png" },
      "role": "first_frame"
    },
    {
      "type": "image_url",
      "image_url": { "url": "https://example.com/end.png" },
      "role": "last_frame"
    }
  ],
  "resolution": "2K",
  "duration": 5
}

Multimodal references

{
  "model": "MiniMax-H3",
  "content": [
    { "type": "text", "text": "Keep the subject's clothing and follow the reference motion." },
    {
      "type": "image_url",
      "image_url": { "url": "https://example.com/subject.png" },
      "role": "reference_image"
    },
    {
      "type": "video_url",
      "video_url": { "url": "https://example.com/motion.mp4" },
      "role": "reference_video"
    }
  ],
  "resolution": "2K",
  "duration": 8,
  "ratio": "16:9"
}

The API accepts up to 9 reference images, 3 reference videos, and 3 reference audio files, with no more than 12 mixed-input files in one request. Each video or audio clip may be 2 to 15 seconds, with a 15-second total for each media type. A request body is limited to 64 MB, so public URLs are the practical choice for large inputs. See the MiniMax H3 model page for the workflows exposed on this independent website.

Errors, retries, and idempotency

The create endpoint documents these common responses:

HTTP Documented condition Retry guidance
400 Invalid parameters, including an empty prompt (2013) Fix the payload; do not retry unchanged
401 Missing or invalid bearer key (1004) Fix server-side authentication
402 Insufficient balance (1008) Add balance or use the correct key
422 Sensitive content (1026) Revise the request; do not bypass safety checks
429 Rate limited (1002) Back off with jitter and respect concurrency limits
500 Internal server error (1000) Retry carefully after a delay

The current rate-limit page lists a maximum of 2 concurrent H3 V2 tasks on the free tier and 15 on the paid tier. Treat those figures as account defaults, not a throughput guarantee.

The V2 create reference does not document an idempotency-key header. Add idempotency in your own backend: create a job row before the upstream call, attach a stable request fingerprint, and reuse the stored task_id when the same client request arrives again. If a create call times out after the server may have accepted it, do not blindly submit another paid task. Reconcile against your stored job and the official seven-day task list first.

API pricing and limits

MiniMax's pay-as-you-go pricing page listed these H3 rates on August 2, 2026:

Item Current list price or limit
2K output $0.13 per output second
768P output $0.09 per output second; closed beta, contact sales
Reference audio Free input material
Reference images First 5 free, then $0.04 per additional image
Reference video Billed by input seconds at the selected output-resolution rate
Output duration Integer values from 4 to 15 seconds
Current public create schema 2K is the available resolution

A five-second 2K output has a $0.65 list cost before any billable reference material. Recheck the official pricing page before showing a quote or sending a job. The pricing page on minimaxh3.tv describes this site's own credit packages, not MiniMax API billing.

Security checklist

  • Keep the MiniMax key in a server-only secret store.
  • Authenticate your own users before allowing them to create a paid task.
  • Validate media URLs, file types, dimensions, duration, and size before submission.
  • Limit concurrent jobs per account and enforce a spending ceiling.
  • Redact authorization headers and input URLs from logs when they may contain private data.
  • Persist the task_id and terminal status without storing more user media than the product needs.
  • Download successful results to controlled storage and apply your retention policy.
  • Rotate a key immediately if it appears in a client bundle, repository, screenshot, or log.

FAQ

What is the MiniMax H3 API model ID?

Use MiniMax-H3 with the V2 video-generation endpoint.

What endpoint creates an H3 video?

Send POST https://api.minimax.io/v2/video_generation with a valid bearer key and JSON body.

How often should I poll an H3 task?

The official guide recommends 10 seconds between queries. Poll GET /v2/query/video_generation/{task_id} and stop on succeeded, failed, cancelled, or expired.

Do I need a file ID to download H3 V2 output?

No. A successful V2 query returns the video URL in task.content.url. The older V1 file-retrieval flow is not part of this H3 V2 workflow.

Does H3 support text, frame, video, and audio inputs through one API?

Yes. All modes use MiniMax-H3 and a content[] array. Text is required. Frame roles cannot be mixed with reference roles, and reference audio needs at least one image or video.

How much does the MiniMax H3 API cost?

The 2K pay-as-you-go list price was $0.13 per output second on August 2, 2026. Reference video seconds and images beyond the included allowance can add cost. Check the official pricing page before each production pricing update.

Is minimaxh3.tv the official MiniMax API console?

No. minimaxh3.tv is an independent service and is not affiliated with, endorsed by, or operated by MiniMax. Use the official MiniMax API Platform for API keys and direct API billing, or open the independent MiniMax H3 model page to use this site's web generator.

Sources and methodology

The schema, endpoints, modes, states, examples, prices, and limits in this guide were checked against MiniMax's official documentation on August 2, 2026. The code samples mirror the documented request and response shapes; no paid generation was used as evidence.

Last verified: August 2, 2026.

#MiniMax H3#API#video generation#developer guide
Related Posts
View all articles
MiniMax H3 Open Source Status: Hugging Face, GitHub, Weights, and License

MiniMax H3 Open Source Status: Hugging Face, GitHub, Weights, and License

Check MiniMax H3 Hugging Face, GitHub, ModelScope, open weights, download, and license status, verified August 1, 2026.

MiniMax H3 Release Date: What Launched and Where to Use It

MiniMax H3 Release Date: What Launched and Where to Use It

MiniMax H3 release date, confirmed launch capabilities, official API limits, and where to use Hailuo H3 online.