Fal-compatible asynchronous REST API for MiniMax H3 image-to-video, using ComfyUI as the inference backend.
Install the server dependencies:
uv syncStart the existing H3 ComfyUI backend and this API in separate terminals:
cd ../MiniMax-H3-ComfyUI && ./run-minimax-h3.sh
cd ../minimax-h3-server && ./run-h3-api.shThe defaults can be overridden when the services are elsewhere:
COMFY_URL=http://127.0.0.1:8188 \
COMFY_OUTPUT_DIR=/path/to/ComfyUI/output \
H3_API_HOST=0.0.0.0 \
H3_API_PORT=8190 \
./run-h3-api.shFor multiple backends, set a comma-separated worker list. COMFY_URLS takes
precedence over COMFY_URL:
COMFY_URLS=http://127.0.0.1:8188,http://127.0.0.1:8189 \
COMFY_OUTPUT_DIR=/path/to/shared/ComfyUI/output \
./run-h3-api.shInteractive API documentation is available at http://127.0.0.1:8190/minimax-h3/docs. The schema is available at http://127.0.0.1:8190/minimax-h3/openapi.json.
Production measurements and methodology are recorded in LATENCY_REPORT.md. Infrastructure economics, utilization assumptions, and GPU break-even points are recorded in COST_REPORT.md.
Generation, status, cancellation, and metrics requests require a Fal-compatible authorization header:
Authorization: Key YOUR_H3_API_KEY
The API fails closed with HTTP 503 when H3_API_KEY is empty. Local development
may explicitly set H3_ALLOW_UNAUTHENTICATED=true; never use that setting on a
public host. Signed result URLs remain downloadable without the API key until
their short expiry.
curl -X POST https://api.longchen.me/minimax-h3/t2v \
-H "Authorization: Key $H3_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"prompt": "A cinematic sunrise over a futuristic city, slow aerial movement.",
"resolution": "720p",
"aspect_ratio": "16:9",
"duration": "5",
"seed": 123,
"generate_audio": true
}'The submission returns {"request_id":"JOB_ID","status":"IN_QUEUE"}. Poll,
retrieve, or cancel it using:
GET /minimax-h3/t2v/requests/{request_id}/status
GET /minimax-h3/t2v/requests/{request_id}
PUT /minimax-h3/t2v/requests/{request_id}/cancel
resolution accepts 480p or 720p; aspect_ratio accepts 16:9, 9:16,
or 1:1. Explicit model-safe width and height may override both.
curl -X POST https://api.longchen.me/minimax-h3/i2v \
-H "Authorization: Key $H3_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"image_url": "https://example.com/signed-first-frame.png",
"prompt": "The camera moves forward while the subject turns and smiles.",
"resolution": "720p",
"duration": "5",
"seed": 123,
"generate_audio": false
}'resolution accepts 480p or 720p and defaults to 720p. The API uses the
orientation of image_url to select the canvas:
| Preset | Portrait | Landscape | Square |
|---|---|---|---|
480p |
480x864 | 864x480 | 480x480 |
720p |
704x1248 | 1248x704 | 704x704 |
These model-safe sizes are multiples of 32. Advanced clients may override the
preset with width and height; they must be supplied together, be multiples
of 32, and fit H3's maximum 768x1344 canvas. The API then submits the job and returns:
{"request_id":"JOB_ID","status":"IN_QUEUE"}end_image_url is optionally accepted for first/last-frame generation.
Reference-to-video uses separate subject, style, and audio references rather
than fixing an image as frame zero. Supply up to nine ordered public HTTPS image
URLs and up to three public HTTPS audio URLs. At least one reference is required.
Use H3's <Picture N> and <Audio N> labels in the prompt:
curl -X POST https://api.longchen.me/minimax-h3/ref2video \
-H "Authorization: Key $H3_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"reference_image_urls": [
"https://example.com/person.png",
"https://example.com/location.png"
],
"reference_audio_urls": [
"https://example.com/performance.wav"
],
"prompt": "<Picture 1> walks through <Picture 2>, matching the rhythm and timbre of <Audio 1>.",
"resolution": "720p",
"aspect_ratio": "16:9",
"duration": "5",
"generate_audio": false,
"reference_image_size": "match"
}'The submission response and queue states match I2V. Poll and retrieve it at:
GET /minimax-h3/ref2video/requests/{request_id}/status
GET /minimax-h3/ref2video/requests/{request_id}
PUT /minimax-h3/ref2video/requests/{request_id}/cancel
resolution supports 480p and 720p; aspect_ratio supports 16:9,
9:16, and 1:1. Explicit model-safe width and height may override both.
The reference images may total at most 100 MB. Each audio reference may be at
most 50 MB and audio references may total at most 100 MB. WAV, MP3, FLAC, M4A,
AAC, OGG, Opus, MP4, and WebM inputs are accepted. Audio references condition
the generated sound and audiovisual motion; generate_audio: false omits audio
from the returned MP4 but still uses the reference for conditioning.
reference_image_size: "match"
is the throughput-oriented default. "max" retains references up to a 2048px
short edge for identity detail, but upstream warns that it can be several times
slower because reference tokens participate in every sampling step.
The endpoint accepts duration as a JSON number or numeric string from 1
through 15 seconds.
H3 generates at 24 FPS and snaps the request to its required 17k+5 frame grid,
so the returned frames value determines the exact output length.
| Requested | Frames | Approximate output |
|---|---|---|
| 1s | 39 | 1.63s |
| 2s | 56 | 2.33s |
| 5s | 124 | 5.17s |
2s is the shortest configuration verified locally. The accepted 1s setting
is less tested by the model.
The coordinator stores each runnable graph in one durable SQLite global queue. It dispatches only to an idle healthy worker, choosing the least queue depth and keeping overflow work global instead of pinning it to a busy ComfyUI process. If a submitted job vanishes before execution, another idle worker can claim it; jobs already observed running are never duplicated.
State changes use SQLite compare-and-set transitions. Cancellation is terminal
even when it races dispatch or completion. The API publishes COMPLETED only
after ComfyUI reports success, the nonempty MP4 and its parent directory are
fsynced, and the completed state is committed durably. Status remains exactly
IN_QUEUE, IN_PROGRESS, or COMPLETED for Fal compatibility.
Set H3_JOB_DB to place the database on durable storage. It defaults to
data/jobs.sqlite3 under this repository. If a worker restarts and loses an
accepted job, the coordinator records a terminal interruption instead of
returning 404. Completed videos remain accessible when their persisted file
still exists in the shared COMFY_OUTPUT_DIR.
All workers must use a shared ComfyUI input/output tree visible to the API. On a single multi-GPU host, launch them from one ComfyUI checkout as shown below. Run one API coordinator process per worker pool; its scheduler task and worker telemetry are process-local. Put a reverse proxy in front of that coordinator rather than starting multiple Uvicorn workers.
Authenticated worker and queue metrics are available at
GET /minimax-h3/metrics.
The files in deploy/vast support either one RTX 5090 or four RTX 5090s. The
launcher detects the topology and runs one isolated ComfyUI process per GPU plus
one API coordinator. They intentionally use the same production workflow:
minimax_h3_fl2va_pruned_int8_convrot.safetensorsdiffusion modelminimax_h3_ref2va_pruned_int8_convrot.safetensorsreference diffusion modelqwen3vl_32b_minimax_h3_nvfp4_awq.safetensorstext encoder- Official H3 video and audio VAEs
No third-party NVFP4 diffusion checkpoint is installed. On a fresh Vast CUDA
13 image, place this repository at /workspace/minimax-h3-server, then run:
cd /workspace/minimax-h3-server
./deploy/vast/provision.sh
cp .env.example .env
# Set H3_API_KEY, H3_SIGNING_SECRET, and H3_PUBLIC_ORIGIN in .env.
./deploy/vast/start-supervisor.shprovision.sh pins the same tested ComfyUI commit and PyTorch 2.11 cu130
stack, then downloads about 63.5 GB of official weights. A single-GPU host binds
one worker to localhost port 8188; a four-GPU host binds ports 8188-8191. The API
uses port 8000 in either topology. Its
independent cloudflared process expects an existing binary and credentials in
/workspace/cloudflared; it does not create the tunnel or commit credentials.
The repository skill at skills/vast-h3-deploy/SKILL.md covers parallel live
offer probes and the fastest path from a verified Vast offer to a detached H3
deployment. Its bundled scripts always destroy temporary probes and transfer
only the small runtime tree before starting model downloads.
Useful operations:
.venv/bin/supervisorctl -c deploy/vast/supervisord.conf status
.venv/bin/supervisorctl -c deploy/vast/supervisord.conf restart 'minimax-h3:*'
curl http://127.0.0.1:8000/minimax-h3/healthzcurl -H "Authorization: Key $H3_API_KEY" \
https://api.longchen.me/minimax-h3/i2v/requests/JOB_ID/status
curl -H "Authorization: Key $H3_API_KEY" \
https://api.longchen.me/minimax-h3/i2v/requests/JOB_ID
curl -X PUT -H "Authorization: Key $H3_API_KEY" \
https://api.longchen.me/minimax-h3/i2v/requests/JOB_ID/cancelThe completed response contains an absolute, short-lived HTTPS URL:
{"video":{"url":"https://api.longchen.me/minimax-h3/i2v/files/JOB_ID?expires=...&signature=..."}}The signed video URL is downloadable without the API key and expires after ten minutes by default.
Run a measured I2V request with:
uv run python benchmark/run_i2v.py first-frame.png \
--prompt 'The subject turns toward the camera and smiles naturally.' \
--width 480 --height 864 --duration 2 --seed 42The script records submission, queue, generation, download, and total latency in a JSON file next to the resulting MP4.