OpenAI-compatible HTTP contract
FastVideo exposes one model-agnostic REST engine for image and video models. Launch it from a typed serve config:
fastvideo serve --config examples/serving/openai_fasth3.yaml
All generation routes share one serialized engine. FastVideo pipelines mutate per-request sampling state, and some adapters merge weights at load time, so a single loaded pipeline is never entered concurrently by image and video requests. HTTP handling and job polling remain asynchronous.
Endpoints
| Method | Path | Description |
|---|---|---|
GET |
/v1/models |
List the served model and optional startup adapter |
GET |
/v1/models/{model} |
Retrieve one served model card |
POST |
/v1/videos |
Submit an asynchronous video job |
POST |
/v1/videos/sync |
Generate and return an MP4 response directly |
GET |
/v1/videos |
List in-memory jobs with after, limit, and order |
GET |
/v1/videos/{id} |
Retrieve job status and metadata |
GET |
/v1/videos/{id}/content |
Download a completed MP4 |
DELETE |
/v1/videos/{id} |
Delete a job and its completed artifact |
POST |
/v1/images |
Generate an image |
POST |
/v1/images/generations |
OpenAI-compatible alias for image generation |
POST |
/v1/images/edits |
Generate an image from image references |
GET |
/v1/images/{id}/content |
Download a generated image |
GET |
/health |
Liveness probe |
POST /v1/videos/generations remains an alias for older FastVideo clients, and
POST /v1/images/generations is the OpenAI Python client’s image generation path.
The OpenAI Python and JavaScript clients can create, retrieve, list, download,
and delete video jobs. Use the H3 server cookbook
for pinned client versions and executable examples. Download variants other
than video return HTTP 400. Remix, extensions, and characters are not implemented.
An H3 text-to-video/audio server also serves /playground/. This same-origin
browser client uses the video routes above and shares their loaded pipeline.
GET /playground/config reports the model alias and operator-explicit sampling
defaults. The playground does not add authentication or a second model process.
For native FastH3 MLX, launch
python -m fastvideo.entrypoints.openai.mlx_server --config examples/serving/mlx_fasth3.yaml.
This adapter shares the video-job API and executes pipeline calls on one MLX
thread. It rejects unsupported options before media fetching or job creation.
Image routes are not mounted. MLX keeps its existing phase-memory policy, so a
persistent server does not imply persistent residency of all model weights.
Video requests
The canonical shape follows vLLM-Omni and accepts SGLang’s common flat extensions. Fields that FastVideo cannot represent for the loaded model fail at admission with HTTP 400 instead of creating a job that later fails.
{
"model": "fasth3",
"prompt": "A fox runs through fresh snow.",
"seconds": "5",
"size": "1344x768",
"video_params": {
"fps": 24,
"num_frames": 124
},
"seed": 42,
"num_inference_steps": 5,
"guidance_scale": 1.0,
"image_reference": [
{"image_url": "https://example.com/first-frame.png"}
],
"extra_params": {
"vsa_mode": "exempt"
}
}
Resolution precedence matches vLLM-Omni:
size- top-level
widthandheight video_params.widthandvideo_params.height
Top-level fps and num_frames similarly take precedence over the nested
block. If num_frames is absent, seconds * fps is used. FastVideo also keeps
the legacy input_reference, reference_url, video_path, and video_url
spellings.
Reference objects support URL or local-path strings through image_url,
video_url, and audio_url. file_id references are schema-compatible but
return HTTP 400 because FastVideo does not provide an OpenAI Files store.
Image URLs, data URLs, local paths, and multipart input_reference uploads are
materialized and decoded under the configured output directory during
admission. Invalid media returns HTTP 400 before a job is created.
Jobs and synchronous responses
An asynchronous submission returns a video object in queued state. Its
status advances through in_progress to completed or failed. Completed
jobs expose file_name, the FastVideo compatibility extension file_path,
timings, and peak-memory metadata when the pipeline reports them.
POST /v1/videos/sync returns video/mp4 bytes. It includes
X-Request-Id, X-Model, X-Inference-Time-S, X-Stage-Durations, and
X-Peak-Memory-MB headers. Its temporary MP4 is removed after the response is
streamed. Asynchronous artifacts remain available until their job is deleted.
Output paths are controlled by the server. Clients cannot choose filesystem
destinations; every video is written beneath server.output_dir with a unique
request id.
FastVideo’s synchronous CUDA execution cannot be interrupted after launch. Deleting an in-progress resource removes it from the API immediately; the engine remains serialized until the call exits and then removes any artifact.
Model and LoRA selection
server.served_model_name controls the public model id. If omitted, the
checkpoint path is used. Requests that name another model fail with HTTP 400.
LoRAs are configured under
generator.pipeline.components.{lora_path,lora_nickname,lora_strength}. The
startup adapter is the only model advertised by a LoRA server, and requests can
select it by its model nickname or with a selector:
{
"prompt": "A fox runs through fresh snow.",
"model": "fasth3-dense-datafree",
"lora": {
"name": "fasth3-dense-datafree",
"path": "/models/adapter_model.safetensors",
"scale": 1.0
}
}
The selector must match the adapter already loaded at startup. FastH3 adapter files can contain dense replacement tensors and VSA gates in addition to low-rank factors, so swapping them inside concurrent requests would corrupt shared pipeline state. A mismatch is rejected with HTTP 400.
MiniMax-H3 and FastH3
FastH3 uses the same general routes and adapter. task is accepted for
SGLang-compatible H3 clients:
t2vauses text only.fl2vatakes one or two image references.ref2vatakes ordered image, video, and audio references and requires a server started withMiniMaxH3Ref2VAModularPipeline.
The released FastH3 pipeline generates one packed video/audio result per request, uses 24 fps, requires guidance scale 1, and accepts frame counts on its causal-VAE grid. The serving examples pin its five-point distilled sigma schedule (four DiT forwards).
Defaults and errors
Incoming explicit fields override operator-explicit default_request fields,
which override model preset defaults. Pydantic defaults do not masquerade as
client intent; the transport uses model_fields_set, while typed config parsing
tracks the exact paths written by the operator.
Errors use the OpenAI envelope:
{
"error": {
"message": "...",
"type": "invalid_request_error",
"param": null,
"code": 400
}
}
Parse, model-selection, startup-LoRA, and unsupported-parameter failures are
HTTP 400; missing resources are HTTP 404. Generation failures are stored on
asynchronous jobs. Retrieving a failed job returns HTTP 200 with status: "failed"
and a string error code, so OpenAI SDK polling returns the terminal resource
instead of retrying it as a transport error. Synchronous generation failures
still return HTTP 500.
Unknown top-level fields are rejected. extra_params accepts only the explicit
request-batch passthrough fields supported by the typed request adapter.
GET /health also verifies that the generation engine is open and all local
multiprocess workers are alive. It returns HTTP 503 when the worker pool is no
longer usable.