Published: 2026-10-20

Docs · Video generation

Three states, and only one of them means give up

auto/video is asynchronous. You submit a prompt, get an id back, and poll until the job resolves. A clip takes roughly two minutes. The detail that matters: a job whose upstream state is unknown is still running. Treating that as failure makes your client throw away work that was about to succeed.

Submit

curl https://freemodel.online/v1/videos/generations \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{"model":"auto/video","prompt":"clouds rolling over a ridge, timelapse"}'
{
  "object": "video",
  "id":     "a1b2c3d4-…",
  "status": "processing"
}

Poll

curl https://freemodel.online/v1/videos/generations/a1b2c3d4-… \
  -H "Authorization: Bearer sk-your-key"

Three states, and nothing else:

statusMeaningWhat to do
processingStill workingPoll again
succeededDone: url is setTake the URL
failedTerminal — error says whyStop and report

Both PENDING and RUNNING from upstream arrive as processing, which is unsurprising. The one worth documenting is UNKNOWN. Upstream reports it before a job has fully registered, and it is transient: in our own probe run, jobs read UNKNOWN first and SUCCEEDED later. All eleven of them finished.

So UNKNOWN maps to processing, not failed. If it mapped to failure, a client would abandon a job the moment it asked too early, and every one of those jobs would have been fine.

import time, requests

H = {"Authorization": "Bearer sk-your-key"}
base = "https://freemodel.online/v1/videos/generations"

job = requests.post(base, headers=H,
                    json={"model": "auto/video", "prompt": "clouds over a ridge"}).json()

while True:
    st = requests.get(base + "/" + job["id"], headers=H).json()
    if st["status"] == "succeeded": break
    if st["status"] == "failed": raise SystemExit(st.get("error"))
    time.sleep(10)

print(st["url"])

Poll on a ten-to-fifteen second interval. A clip takes about two minutes, so a one-second loop mostly produces load.

What is deliberately not here

Text-to-video only. Image-to-video, reference-to-video and video editing take an input frame or clip, and they are a different operation with a different request shape — not a flag on this one.

The alias moves between candidates only when the current model has been retired upstream (404 or 410). A generation is not a request you can quietly retry on a different model: a different model produces a different clip, and you would notice only after watching it.

Related capabilities

Same naming scheme, one alias per capability — all listed in /v1/models:

image

auto/image

Text to image. Synchronous, seconds not minutes.

embedding

auto/embed

1024-dimension vectors, one candidate.

rerank

auto/rerank

Reordering retrieved documents by relevance.

tts

auto/tts

Text to speech.

asr

auto/asr

Speech to text.

Sources

Every third-party figure quoted on this site was read from the vendor documentation linked below, on the date stated. None of these links are affiliate links and none of these vendors paid to be listed. If a number here disagrees with the page it came from, the page is right — tell us and it gets corrected.

What this is

auto/video turns a prompt into a short clip through an asynchronous job: submit, poll, then fetch the URL.

auto/video is an asynchronous job API: you submit a prompt, then poll until the clip is ready.

FreeModel 的 auto/video 是免费的文本转视频 API:提交 prompt 后,一个视频片段约 2 分钟生成完毕。接口是异步的:POST /v1/videos/generations 拿到任务 id 后,每 10–15 秒轮询一次,直到状态为 succeeded 再取视频 URL。任务只有 3 种状态走向:processing(含上游的 UNKNOWN)、succeeded、failed。实测 11 个任务全部完成,包括一开始报 UNKNOWN 的任务——UNKNOWN 只是上游尚未完全注册,映射为 processing 继续等,不是失败。结论:不要把 UNKNOWN 当失败丢掉,也不要每秒轮询;按 10–15 秒轮询、等到 succeeded 再取 URL,是这页最稳的用法;只有模型退役(404/410)时别名才会切换候选,超时、限流、上游 5xx 应直接返回带模型名的错误,不静默换模型。

Key numbers

How to use it, step by step

  1. Step 1. Submit: POST {"model":"auto/video","prompt":"…"}, keep the returned id.
  2. Step 2. Poll: GET /v1/videos/generations/<id> every 10–15 seconds.
  3. Step 3. Finish: succeeded means take url; failed means read error; processing — including upstream UNKNOWN — means keep waiting.

Polling vs a callback: this endpoint has no callback, so polling is the contract.

FAQ

What does UNKNOWN mean?

The upstream has not registered the job yet. It is mapped to processing, not to failure — treating it as failure throws away work that was about to succeed.

Is there a callback instead of polling?

Not on this endpoint. Polling is the contract.

When to use it — and when not to

Use it for short clips: 5–15 second social cuts, animated backgrounds, storyboard previews. The job is asynchronous, so it fits batch production, not interactive requests.

Do not use it for long-form video, precise on-screen text, or anything that must match a real person or product exactly. Generation time and fidelity both scale badly there.

Limits worth designing around

Cost and latency

Video is priced per second of output, so a 60-second clip can cost twelve times a 5-second clip. Budget by seconds, not by job count. Latency is minutes, not seconds; a job queue with status pages is the right shape.

Generate at the lowest resolution that passes review, then re-render only the approved shots at final quality.

Two more questions

What do the three states mean? Submitted means queued; processing means the model is rendering; a terminal state means success or failure. Only a terminal success has a file to fetch.

Why did a job fail with no useful message? Most often the prompt tripped a content filter or the requested duration exceeded the model's limit. Shorten the clip and simplify the prompt before retrying.