Video generation behind a relay: three API shapes, four billing traps, one acceptance checklist

Tutorials Published 2026-10-19 46 views API Compass
Video generation has no shared protocol; every vendor ships its own asynchronous task flow. The shape decides how you integrate it, and four billing traps decide whether you overpay. A six-step acceptance checklist follows.

Why video is the least tidy category

Text has a de facto standard in POST /v1/chat/completions. Images have POST /v1/images/generations. Video has nothing.

To date there is no unified protocol: every vendor ships its own submission method, its own task state machine and its own way of collecting the result. A relay sits in the middle and can only pass each vendor through individually, so on the same site two video models may be called in completely different ways.

That single fact determines three things: you cannot write one generic wrapper, you cannot bill against a single multiplier, and you cannot apply one retry policy.

Three API shapes

Shape one: OpenAI-style asynchronous task

Submission returns a task object, then you poll by id:

# submit
curl -s https://<base_url>/v1/videos \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"model":"<video-model>","prompt":"a cat walking on a beach","seconds":"8","size":"1280x720"}'

# poll
curl -s https://<base_url>/v1/videos/<video_id> -H "Authorization: Bearer $KEY"

Test: the submission response must contain id and status, and only when status becomes completed does the response expose a downloadable location.

Shape two: submit, poll, fetch

More common with Chinese vendors: the task id is task_id, status lives at a separate path, and the result URL has a limited lifetime.

curl -s https://<base_url>/v1/video/generations \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"model":"<model>","prompt":"...","duration":5}'
# => {"task_id":"..."}

curl -s https://<base_url>/v1/video/generations/<task_id> -H "Authorization: Bearer $KEY"
# => {"status":"succeed","data":{"url":"https://.../xxx.mp4"}}

Shape three: synchronous return (rare)

The URL comes back immediately, sometimes as base64. Only suitable for very short, very low resolution clips, because the HTTP connection has to stay open for tens of seconds and any proxy timeout along the way will cut it.

DimensionShape oneShape twoShape three
Submit path/v1/videos/v1/video/generationssame as submit
Key fieldsid / statustask_id / statusurl
Typical duration30-180 s20-300 s5-20 s
Timeout risklow (polling uses short connections)lowhigh
Result lifetimeoften 24 hoften 1-24 hmay expire instantly

If your client or gateway is bad at long-lived connections, use shape one or two and never shape three.

Four billing traps

Trap one: per second, per call and per token coexist on one site

On a single site, model A bills per generated second, model B bills a flat price per call, and model C bills input tokens plus output video tokens. The consumption figure in your dashboard is a blend, so you cannot reverse-engineer a unit price from it.

Do this: run one minimum request per video model — same prompt, shortest duration, lowest resolution — and record the charge. That is your baseline unit price, and every later anomaly is measured against it.

Trap two: resolution and duration change the price, but the multiplier table only covers text

A relay's "multiplier" is usually defined against text tokens. For video, 720p versus 1080p and five seconds versus ten can differ two to three times in price, while the table shows a single number.

Test: run the same prompt at 720p/5 s and at 1080p/10 s and compare the charge. If the ratio does not match the vendor's public price list, the relay has added its own tier coefficient — and it owes you an explanation.

Trap three: failures are billed

Whether the charge is refunded after a failure (content moderation rejection, upstream timeout, a task stuck in processing) varies by provider, and this is almost never written in the price list.

Do this: deliberately submit a prompt that must be rejected, then look at the billing record. That is worth more than ten pages of terms.

Trap four: result URLs expire

The returned url is usually a presigned object storage address with a lifetime between a few minutes and 24 hours. Once it expires you cannot retrieve the video again, and relays generally do not offer a re-issue endpoint.

The only correct move is to download immediately rather than storing the URL as a permanent link.

A six-step acceptance checklist

StepActionPass criteria
1Submit a minimum requestGot id or task_id, HTTP 200
2Poll to a terminal stateStatus moves from processing to completed, and a terminal state exists (it must not sit in processing forever)
3Download at onceAfter curl -o out.mp4, [ -s out.mp4 ] is true and the size exceeds 100 KB
4Verify media propertiesDuration and resolution read by ffprobe match the request
5Reconcile the chargeDashboard consumption equals the baseline from step 1
6Retry onceSubmit the same request again and confirm it does not charge twice for one success

Step 4 is the one most often skipped and the one that exposes the most. Asking for ten seconds and receiving five has actually happened on relays, because the upstream rounds to a tier and the gateway never validates it.

ffprobe -v error -select_streams v:0 \
  -show_entries stream=width,height,duration \
  -of csv=s=x:p=0 out.mp4
# expected output such as 1280x720x8.000000

When a relay is worth it for video

Only two situations justify going through a relay:

  1. You need several video models side by side and do not want a separate account and deposit for each;
  2. You operate in mainland China while the vendor only accepts overseas payment, making a relay the only practical settlement path.

Conversely, if your volume is steady and you use one model, going direct is cheaper and easier to debug — a middle layer for this kind of API delivers no protocol unification, only one more place to fail.

Summary

  1. Video has no shared protocol; the shape decides how your code is written.
  2. Measure unit prices yourself; per second, per call and per token cannot be mixed.
  3. Resolution and duration change the price, and multiplier tables usually ignore them.
  4. Test refund behaviour with a request that is guaranteed to fail.
  5. Result URLs expire, so download as soon as you get one.
  6. One successful generation is not acceptance: let the numbers ffprobe reports decide.

Was this useful? If you have run into something the article does not cover, tell us and we will verify it and update the text.

Related articles

MCP through a relay: what works, what never will, and how to test it in ten minutes

2026-10-19

A relay selection decision tree: working back from your scenario to a site

2026-10-07

Logging and reconciliation: attributing token spend to the project level

2026-10-06

Migrating suppliers gradually: replacing an API site without interrupting service

2026-10-06

Build your own probe: twenty lines of script to monitor your API suppliers

2026-10-06

IP allowlists, sub-accounts and permission tiers: a survey of relay governance

2026-10-06

Read on: a few of the services we list

This article does not point at a specific model family, so here are a few of the highest-scoring services we list, in case you want to read on. They are ordered by score and uptime and are not a recommendation.

See the full list in the directory, or browse by model family.