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.