🚀 One API for every frontier model on FastInfra

Browse models

Transparent per-token pricing → compare providers on FastInfra

View pricing

OpenAI-compatible chat completions → start in minutes

Read the docs

⚡ Server Auction → Enterprise bare metal from $78.15/mo (173 in stock)

Browse deals

Text-to-video API: the async job pattern, polling, and keeping generation cost under control

A text-to-video API turns a prompt into a short MP4, but unlike a chat completion it takes minutes, so the pattern is asynchronous: submit a job, receive HTTP 202 with a job id in about a second, poll until the status is completed, then decode the result. On FastInfra every text-to-video model — the self-hosted LTX model and wholesale models such as Wan and Veo when enabled — shares this workflow behind the same API key as the 785 chat models. This guide covers the contract, polling, cost and latency.

Why video is a job, not a request

Chat completions finish in seconds and stream; video generation runs a diffusion pipeline for tens of seconds to several minutes depending on the model, duration and resolution. HTTP connections through load balancers and CDNs are commonly cut at around 100 seconds, so a synchronous design would fail for exactly the requests that matter. The FastInfra video generations endpoint therefore returns HTTP 202 Accepted with a job id immediately, and you fetch the result when it is ready. The same contract applies to the self-hosted LTX model and to wholesale models (for example alibaba/wan-2.6 and Google Veo SKUs) when they are enabled on the deployment.

The three calls

Text-to-video job lifecycle
StepCallResponseBilled?
DiscoverGET /v1/videos/modelsVideo model ids with constraints and pricesNo
SubmitPOST /v1/videos with model, prompt, duration and size202 with id and status: queuedNo
PollGET /v1/videos/{id}status of queued, processing, completed or failedOn first completed
Decode—data[0].b64_json → MP4 bytes—

Submitting is free; a failed job is free; a completed job is deducted from prepaid credits the first time you observe completed. That makes the client's responsibility clear: poll every job you submit to completion or cancellation, and store the id durably so a restarted worker can resume polling.

Polling that behaves

import time, base64

job = client.post("/v1/videos", json={
    "model": "ltx-2.5",
    "prompt": "A slow dolly shot across a rain-soaked street at dusk",
    "seconds": 5,
    "size": "1280x720",
}).json()

delay = 5
while True:
    status = client.get(f"/v1/videos/{job['id']}").json()
    if status["status"] == "completed":
        mp4 = base64.b64decode(status["data"][0]["b64_json"])
        break
    if status["status"] == "failed":
        raise RuntimeError(status.get("error"))
    time.sleep(delay)
    delay = min(delay * 1.5, 20)

Start at five seconds and back off to twenty: anything faster wastes requests against your rate limit without finishing sooner; anything slower adds latency the user notices. If you run many jobs, poll from a single worker loop rather than one thread per job, and persist job ids with the user who requested them.

What drives cost

Video pricing is set per model and scales with the amount of video generated — duration in seconds and output resolution — rather than with prompt length. Three product decisions bound the bill:

  • Fix duration and size server-side. Do not let a client pick 30 seconds at the highest resolution; offer two or three presets.
  • Preview first. Generate a short, low-resolution clip for iteration, then the final render once the prompt is approved.
  • Deduplicate. Hash prompt + parameters and return the stored MP4 for repeats instead of resubmitting.

Prices per model are listed by GET /v1/videos/models and on the pricing page; all media models are read from the same catalog as the chat models, with 12 free-tier chat ids available if you want a $0 model to write or refine prompts before generation.

Latency and queueing

Job time is generation time plus queue time. Generation is roughly proportional to frames × resolution for a given model; queue time depends on load. A five-second 720p clip on the self-hosted model typically completes in a few minutes; higher resolutions and longer clips take proportionally longer. Expose queued and processing to the user as distinct states and show elapsed time; silence is what makes a two-minute wait feel broken. For batch use, submit many jobs at once and let the queue drain; the per-job latency matters less than aggregate throughput.

Failure handling

A failed status includes an error message; common causes are prompts rejected by safety filters, unsupported size for the model, and transient upstream errors for wholesale models. Retry transient failures with a new submission (the failed job is not billed); do not retry filter rejections automatically. If a poll returns 404 for an id you know you submitted, treat it as expired and resubmit. Keep the request id from the submit response in your logs so a report can be matched to the status page timeline.

Production checklist

  1. Enumerate models at start-up from GET /v1/videos/models; never hard-code constraints.
  2. Store job ids durably before returning to the user.
  3. Poll with backoff from a worker; resume on restart.
  4. Cap duration and size per plan tier; add a preview preset.
  5. Deduplicate identical requests.
  6. Alert on failed-job rate and on p95 job time.
  7. Budget: completed jobs are deducted from the same prepaid credits as chat usage; set a balance alert.

Speech-to-text and text-to-speech share the key and base URL but are synchronous endpoints; the video and speech API guides cluster covers them separately.

Combining video with chat and speech

Most video features are pipelines, not single calls. A typical flow uses a free-tier chat model to turn a user's rough idea into a well-formed prompt with camera direction and shot length, submits the video job, and in parallel generates a voice-over with the text-to-speech endpoint so audio is ready when the clip completes. All three run through the same API key and base URL, and all three show up as separate line items in per-key usage, which makes the cost of the whole feature visible per user.

Design the pipeline so each stage is idempotent and resumable: store the prompt, the job id and the audio file against the user's request, and let a single worker advance the request through its states. Then a crash mid-pipeline resumes from the last completed stage rather than paying for the video again. The list of available video and speech model ids comes from the model catalog, which you should read at start-up rather than hard-coding.

Frequently asked questions

Why does the text-to-video API return 202 instead of the video?

Generation takes minutes, longer than most HTTP intermediaries allow a connection to stay open. The endpoint returns 202 with a job id in about a second so your client can poll for the result without hitting timeouts.

When am I charged for a video job?

On the first poll that returns status completed. Submitting a job is not billed and failed jobs are not billed, so always poll every job you submit to completion.

Can I use a chat model id to generate video?

No. Video model ids only work on POST /v1/videos and return an error on chat/completions. List valid video ids with GET /v1/videos/models; chat model ids are listed by GET /v1/models.

How often should I poll?

Start at about five seconds and back off to roughly twenty seconds between polls. Faster polling does not finish the job sooner and counts against your rate limit; slower polling adds visible latency.

What formats and resolutions are supported?

The result is an MP4 returned as base64 in data[0].b64_json. Supported sizes and durations differ per model and are returned by GET /v1/videos/models, so read constraints from that call rather than assuming.

Last reviewed October 16, 2026 by FastInfra. Prices and counts on this page are refreshed from the live catalog on every load.