Using the local video generation API
This HTTP/JSON API submits MiniMax H3 text-to-video or first-frame image-to-video jobs, lets you poll their status, lists saved results, and serves video files. No API key is required on the local network.
Base URL: the same origin as this page, e.g. http://YOUR-H3-LAB-HOST:7862.
Machine-readable specification: OpenAPI 3.1 JSON. All timestamps in generation metadata are Unix seconds (UTC); generation duration is seconds.
Quick start: generate, poll, download
Submit a prompt; use the returned job_id to poll until the response says complete. Then GET the returned video path. Poll every 2–5 seconds rather than continuously.
BASE=http://YOUR-H3-LAB-HOST:7862
JOB=$(curl -fsS "$BASE/api/generate" \
-H 'Content-Type: application/json' \
-d '{"prompt":"A paper boat drifting through a sunlit stream","aspect":"16:9","quality":"preview","duration":5,"turbo":true,"steps":6,"seed":-1}' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["job_id"])')
# Poll; continue while status is "running".
curl -fsS "$BASE/api/jobs/$JOB" | python3 -m json.tool
# When status is "complete", download the returned video path.
curl -f "$BASE$(curl -fsS "$BASE/api/jobs/$JOB" | python3 -c 'import json,sys; print(json.load(sys.stdin)["video"])')" \
-o result.mp4Endpoints
GET /api/config — capabilities and health
Returns the active model, backend health, available aspect ratios, qualities, durations, Turbo LoRA and optional additional LoRAs. Read this first instead of hard-coding model availability.
{
"model": "minimax_h3_fl2va_pruned_int8_convrot.safetensors",
"backend_ready": true,
"turbo_available": true,
"turbo_lora": "minimax_h3_turbo_v4_step600_ema_pruned_comfyui.safetensors",
"loras": [{"id":"mystic-xxx-v4", "name":"Mystic XXX v4 (FL2VA)",
"air":"urn:air:minimaxh3:lora:civitai:2856467@3266628+3150341",
"default_strength":1.0}],
"aspects": ["16:9","9:16","1:1","4:3","3:4","21:9"],
"qualities": ["draft","preview","native"],
"durations": [4,5,6,8,10,12,15]
}backend_ready is a point-in-time check; retry if false.
POST /api/generate — enqueue a generation
Send a JSON object with Content-Type: application/json. Maximum request body is 30 MiB. Returns HTTP 202 with a job ID and normalized settings. The service supports one active ComfyUI generation at a time; jobs may wait in ComfyUI's queue.
| Field | Type | Allowed values / behavior |
|---|---|---|
prompt | string, required | 1–12,000 characters (whitespace trimmed); include desired scene, motion and audio description. |
aspect | string | 16:9, 9:16, 1:1, 4:3, 3:4, 21:9; default 16:9. |
quality | string | draft, preview, native; default preview. |
duration | number | 4–15 seconds; default 5. Values supported in the UI are advertised by config; the API accepts any number in range. |
turbo | boolean | Default false. Turbo sampler uses the installed Turbo LoRA at strength 1.0. |
steps | integer | Turbo: 4–8 (default 6). Standard: 4–30 (default 20). |
seed | integer or numeric string | -1 or omitted chooses a random seed. Valid range: -1 through 263-1. Response returns the actual seed; reuse it for deterministic reruns. |
start_image | string or null | Optional data URI: data:image/png;base64,…, data:image/jpeg;base64,…, or data:image/webp;base64,…. Maximum decoded size 20 MiB. Crop/resize it to the selected aspect ratio before sending to avoid distortion. |
lora | string | Optional additional LoRA ID from /api/config, or empty/omitted. Current ID: mystic-xxx-v4. |
lora_strength | number | 0–2, default 1.0; used when an additional LoRA is selected. |
Example response:
{"job_id":"e8909c41-be4d-4405-816b-8b97fc430e59","settings":{"prompt":"A paper boat drifting through a sunlit stream","aspect":"16:9","quality":"preview","width":864,"height":480,"duration":5,"frames":124,"steps":6,"turbo":true,"seed":123456,"start_image":false,"lora":null,"lora_name":null,"lora_strength":null,"model":"minimax_h3_fl2va_pruned_int8_convrot.safetensors","created":1790093031.123}}
GET /api/jobs/{job_id} — poll job status
Poll with the job_id returned from generation. HTTP 200; state is in status:
{"status":"running"}
{"status":"complete","video":"/api/video?filename=…&subfolder=H3Lab"}
{"status":"error","error":"…"}A completed result is returned only once ComfyUI has completed execution and saved its output. Make a GET to the returned video URL (relative to the same base URL). A non-existent/expired job is reported as status: error. Invalid job ID returns HTTP 400; unavailable ComfyUI returns 502.
GET /api/gallery — recent saved generations
Returns up to 24 newest videos and their metadata. Seeds are strings in gallery metadata to preserve full 64-bit precision.
{"items":[{"video":"/api/video?filename=…&subfolder=H3Lab","settings":{
"prompt":"…","aspect":"9:16","quality":"preview","width":480,"height":864,
"duration":5,"frames":124,"steps":6,"turbo":true,"seed":"123456",
"start_image":false,"lora":"mystic-xxx-v4","lora_name":"Mystic XXX v4 (FL2VA)",
"lora_strength":1.0,"model":"…","created":1790093031.123,"completed":1790093065.366,
"generation_time_seconds":34.24
}}]}Fields completed and generation_time_seconds may be estimated for older generations created before exact timing was recorded; such entries set generation_time_estimated: true.
GET /api/video?filename=…&subfolder=H3Lab — stream/download output
Use the relative video URL returned by a job or gallery item; do not construct a filesystem path. Supports standard HTTP byte ranges for browser playback and resume. Returns 200 for full file or 206 for a valid Range: bytes=start-end request. Missing files return 404.
POST /api/interrupt — interrupt current generation
Send Content-Type: application/json and body {}. Returns {"ok":true}. This signals ComfyUI's global interrupt endpoint and is not scoped to a job ID, so only call it to stop the active generation.
Errors and client guidance
- Generation input validation errors: HTTP
400, JSON{"error":"…"}. - ComfyUI rejects a workflow or is unavailable: HTTP
502, JSON{"error":"…","detail":"…"}when available. - POST requests must be same-origin when an
Originheader is supplied; no token/authentication is currently configured. - Use
seed: -1for a random seed; save the returned actual seed and settings if you may rerun. - For image-to-video, send a pre-cropped data URI with the same aspect ratio as
aspect. The website's interactive cropper exports JPEG; API callers may crop images in their own image library. - Poll job status every 2–5 seconds. The API does not currently provide WebSocket progress events.