Most AI video generator reviews score the output: how the faces hold up, whether the physics look right, which one nails a dolly zoom. That is useful for picking a tool to open in a browser. It is close to useless if you are going to call one from code, because output quality changes with every checkpoint, while the parameter contract is what your integration has to live with for the next year.
So here is the other review. Six video models, judged on what their APIs refuse to accept, where the refusal is silent, and how much of your client survives swapping one model for another. Everything below comes from a request surface I maintain.
One framing note. I am not affiliated with any of these labs. I reach these models through third-party channels, so channel-level caps can differ from whatever a first-party API exposes, and none of this is official documentation.
MiniMax H3 takes an aspect_ratio
. What that field means depends entirely on which mode you are in.
| Mode | aspect_ratio |
|---|---|
| Text to video | Required, and adaptive is rejected |
| Image to video | Forbidden. Orientation comes from the source image |
| Reference to video | Optional, defaults to adaptive |
The middle row is the interesting one. The field is not ignored there, and it is not optional. Sending a valid enum value, one this same model accepts in another mode, fails the request. A generic client that always sets aspect_ratio
from user config works in two modes out of three, and the failure surfaces as a validation error about a field the docs told you to send.
Seedance 2.5 has the same shape with different edges. It accepts seven ratios plus adaptive
, but first-plus-last-frame requests have to leave the size at adaptive
, because upstream rejects any other value at submit time. Same model, same field, and whether it is settable depends on which image mode you chose two fields earlier.
Mode is not a filter over one schema. It is several schemas that happen to share field names.
Seedance 2.5 requires a prompt on every request, minimum three characters, image-to-video included. The documentation for the channel describes the prompt as optional when reference material is supplied. The endpoint disagrees and returns an error.
The version history makes this worse for anyone upgrading. The 2.0 family let you submit an image with no prompt and take whatever motion the model inferred. Point the same client at 2.5 and every bare image-to-video call starts failing. Nothing in the model name signals that the required fields changed.
"Optional" in a vendor doc is a hypothesis, not a fact. The cheap test is to fire one deliberately minimal request per mode during integration and record what comes back. It takes ten minutes, and the result is the only version of the schema you can trust.
Veo 3.1 is one model. Reached through three different resale channels, it is three different APIs.
| Channel A | Channel B | Channel C | |
|---|---|---|---|
| Duration | Fixed 8s | Fixed 8s | Selectable |
| Resolution control | No | Yes | Yes |
| Negative prompt | No | No | Yes |
| Seed | Yes | No | Yes |
Nothing here is a quality difference. It is the same weights. But an integration written against the third column, using seed for near-reproducible re-rolls and a negative prompt to suppress a recurring artifact, loses both the moment someone flips a routing env var to the second column. The requests still succeed. The outputs just stop respecting parameters you are still sending.
The adapter layer you write to paper over those differences tends to widen the silence rather than close it. Mine did. Normalizing per-channel enums looks harmless:
aspect_ratio = request.get("aspect_ratio", "16:9")
if aspect_ratio not in VALID_ASPECT_RATIOS:
aspect_ratio = "16:9"
That clamp stops the channel erroring, and it means a user who asks for 21:9 where only two ratios exist gets a successful 16:9 render, billed normally, with nothing anywhere saying they were overruled. Parameters a channel never implemented are not read at all, so they vanish a layer earlier. Decide deliberately whether an unsupported value should clamp or fail, and tell the caller which one happened.
The same config carried a fourth channel that was mapped, wired, and non-functional: the routing layer rejects it for this model with an invalid-tier error on every call. A provider being present in your config is not evidence that it is reachable.
So model_name
is not a sufficient key for capability. (model_name, channel)
is.
HappyHorse 1.0 exposes a single model id and infers the mode from which media fields you populated, in priority order: a video URL wins, then a first-frame image, then a list of reference images, then prompt-only.
This is elegant until you leave a field set. A client that keeps video_url
from the previous request while the user is now trying a text-to-video generation does not get an error. It gets a video edit. The request is well formed, the mode is just not the one anyone intended, and the bill lands in the edit tier.
Anywhere the API derives intent from field presence rather than an explicit mode enum, clear your media fields on mode switch. Explicitly, not by trusting your form state.
Three real ones, all of which have to live in application code because a flat parameter list cannot hold them:
Each of these is a place where a schema-driven form or a generated client rejects valid requests, or accepts invalid ones.
No numbers here, since rates move and differ per channel. The shapes are the part a per-second price will not tell you:
The review criteria, in the order that has saved me the most time:
None of that tells you which model makes the prettiest video. That is deliberate. I have no benchmark worth publishing, and a quality verdict written today expires at the next checkpoint, while a contract quirk tends to outlive several.
If you want to poke at these surfaces before writing any client code, clipdance.ai puts the reference-to-video parameters of several of these models behind form controls, which surfaces the per-mode field sets and the upload ceilings faster than reading error strings does. The models belong to their respective labs; this is third-party access.
This space is still shipping capability faster than it ships stable contracts, and a review scored on output quality cannot see that at all. If you have hit a rejection I did not list, especially a silent one, I would like to read it in the comments.