MiniMax H3 API in Python: submit, poll and download a video job

A runnable Python example for MiniMax H3 on Sume: POST /v1/videos, poll the job until completed, then download the clip from unsigned_urls. Uses httpx.

4 min readSume
All posts

To call MiniMax H3 from Python, POST to https://api.sume.com/v1/videos with model: "minimax-h3", poll the returned polling_url until status is completed, then download unsigned_urls[0]. Generation is asynchronous, so the script below submits once and polls every 15 seconds.

The flow and fields are from the Sume Video generation docs, read 2026-09-29. It needs pip install httpx and SUME_API_KEY in the environment.

What does the script look like?

It reuses one Idempotency-Key so that a retried submit does not create a second job, and stops on failed or cancelled.

import asyncio
import os
import httpx

API = "https://api.sume.com/v1/videos"
HEADERS = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}

async def main():
    body = {
        "model": "minimax-h3",
        "prompt": "A paper boat drifts down a rainy gutter, close-up, soft rain sound",
        "resolution": "768p",
        "aspect_ratio": "16:9",
        "duration": 5,
    }
    async with httpx.AsyncClient(timeout=60, follow_redirects=True) as client:
        r = await client.post(API, json=body, headers={**HEADERS, "Idempotency-Key": "h3-py-001"})
        r.raise_for_status()
        url = r.json()["polling_url"]
        while True:
            await asyncio.sleep(15)
            job = (await client.get(url, headers=HEADERS)).json()
            if job["status"] == "completed":
                clip = await client.get(job["unsigned_urls"][0], headers=HEADERS)
                open("h3.mp4", "wb").write(clip.content)
                return
            if job["status"] in ("failed", "cancelled"):
                raise RuntimeError(job.get("error", job["status"]))

asyncio.run(main())

What can go wrong?

Refusals from Sume's H3 request validation, read in code 2026-09-29.
RequestResult
resolution: "720p"Refused; use 768p
generate_audio: falseRefused; sound is always on, omit the field
bitrate_mode setRefused for both H3 ids
duration under 5 or over 15Refused; the range is 5–15 seconds
resolution: "1080p" on minimax-h3Refused; use minimax-h3-max

How long should I poll?

Sume's own docs example polls every 30 seconds. No generation time is published for H3, so pick a poll interval and an overall timeout from your own test runs.

Can I get a webhook instead of polling?

Yes: the request takes callback_url, which must be HTTPS, and Sume notifies it when the job completes. If you verify the webhook, refuse to run with an empty secret. Keep the polling loop as a fallback.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume