REST async · one key · updated 2026-10-02

Veo API

Google Veo 3.1, 3.1 Fast and 3.1 Lite through one REST endpoint — no Cloud project required — with the price on every host compared live.

API at a glance

EndpointPOST https://videorouter.sh/api/v1/videos
AuthenticationAuthorization: Bearer llmr_sk_live_...
LifecycleAsync job: queued → in_progress → completed | failed. Polling is free.
Model idsgoogle/veo-3.1, google/veo-3.1-fast, google/veo-3.1-lite
BillingPer requested second, charged once at job creation; failed-upstream jobs are not billed. Flat 2% platform fee.
Provider choiceUnpinned requests route to the cheapest healthy host and fail over; append /<host> to prefer one.

Models

Provider comparison — veo-3.1

Host720p1080p2160p
Pika$0.20$0.20$0.20
Replicate$0.20$0.20$0.20
SandBase$0.20$0.20$0.40
Google$0.40$0.40$0.40
DeepInfra$0.40$0.40$0.40
MachGen$0.40$0.40$0.60
WaveSpeedAI$0.40$0.40$0.40

USD per second, before the 2% platform fee. Bold = cheapest at that tier.

Examples

curl https://videorouter.sh/api/v1/videos \
  -H "Authorization: Bearer $VIDEOROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "google/veo-3.1", "prompt": "a paper airplane gliding over a city", "duration_secs": 5}'
# -> {"id": "video_...", "status": "queued"}
curl https://videorouter.sh/api/v1/videos/$ID -H "Authorization: Bearer $VIDEOROUTER_API_KEY"
import time, requests
H = {"Authorization": "Bearer llmr_sk_live_..."}
job = requests.post("https://videorouter.sh/api/v1/videos", headers=H, json={
    "model": "google/veo-3.1", "prompt": "a paper airplane gliding over a city", "duration_secs": 5}).json()
while job["status"] not in ("completed", "failed"):
    time.sleep(5)
    job = requests.get(f"https://videorouter.sh/api/v1/videos/{job['id']}", headers=H).json()
print(job["data"][0]["url"] if job["status"] == "completed" else job["error"])
const H = { Authorization: "Bearer llmr_sk_live_...", "Content-Type": "application/json" };
let job = await (await fetch("https://videorouter.sh/api/v1/videos", { method: "POST", headers: H,
  body: JSON.stringify({ model: "google/veo-3.1", prompt: "a paper airplane gliding over a city", duration_secs: 5 }) })).json();
while (!["completed", "failed"].includes(job.status)) {
  await new Promise(r => setTimeout(r, 5000));
  job = await (await fetch(`https://videorouter.sh/api/v1/videos/${job.id}`, { headers: H })).json();
}
console.log(job.data?.[0]?.url ?? job.error);

Model id used: google/veo-3.1. More in examples.

Notes

Three variants
Full, Fast and Lite are separate model ids so cost and latency are one string away.
No Vertex setup
Skip the Google Cloud project, quota requests and service accounts.
Multiple hosts
Veo is available directly from Google and from resellers at different prices; the table shows the spread.
Same job lifecycle
Create, poll, download — identical to Kling, Seedance and the rest.

FAQ

Which Veo versions are available?

Veo 3.1, Veo 3.1 Fast and Veo 3.1 Lite. The live table lists exactly what is currently in the catalog.

When should I use Fast or Lite?

Use Fast for iteration and Lite for high-volume or cost-sensitive output; reserve full Veo 3.1 for final renders.

Is it the same Veo as Google's?

Yes — requests are served by Google directly or by third-party hosts reselling the same model.

How is it billed?

Per second of output video. Check the pricing page for the cheapest host today.

Guides

Using Veo is one part of the job.

VideoRouter puts it next to dozens of other video and image models behind one API key, so you can compare providers, prices and fail over automatically. Compare providers on VideoRouter →