Back to blog

How to Generate AI Videos with an API

An AI video generation API tutorial: submit async jobs to Veo, Seedance, and KLING through one OpenAI-compatible endpoint, poll or receive signed webhooks, download the MP4, and keep per-second costs visible.

A glowing film clapperboard rendering frames on a circuit board, representing an AI video generation API

Video models don't respond in milliseconds — a single clip can take minutes to render, and every provider handles the waiting differently. Google Vertex uses long-running operations, ByteDance uses task polling, AtlasCloud uses prediction endpoints. Building against three job systems to compare three models is a bad afternoon.

LLM Gateway wraps all of them in one asynchronous, OpenAI-compatible AI video generation API: POST /v1/videos submits the job, GET /v1/videos/{id} reports progress, and GET /v1/videos/{id}/content streams the finished MP4 — for every video model in the catalog. Browse the current list on the models page with the video filter.

Submit a job

1curl -X POST "https://api.llmgateway.io/v1/videos" \2  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \3  -H "Content-Type: application/json" \4  -d '{5    "model": "veo-3.1-generate-preview",6    "prompt": "A cinematic aerial shot flying above a rainforest waterfall at sunrise",7    "seconds": 8,8    "size": "1920x1080"9  }'

The response comes back immediately with a job id:

1{2  "id": "v_123",3  "object": "video",4  "model": "veo-3.1-generate-preview",5  "status": "queued",6  "progress": 0,7  "created_at": 1753500000,8  "completed_at": null,9  "error": null10}

Three fields are required: model, prompt, and seconds. Optional fields include size (widthxheight), audio (default true), first/last frame images for image-to-video, and reference images, videos, or audio on models that support them. Video generation requires at least $1.00 of available organization credits before the job is submitted.

Pick a model, duration, and resolution

Each model supports specific sizes and durations — requests outside them return a 400 instead of silently rendering something else:

Model family Sizes Durations Price (720p/1080p, with audio)
Veo 3.1 720p, 1080p, 4K (portrait too) 4, 6, 8, 10 $0.40/s (1080p)
Veo 3.1 Fast 720p, 1080p, 4K 4, 6, 8, 10 $0.15/s (1080p)
Seedance 2.0 720p, 1080p 4–15 $0.15/s / $0.34/s
Seedance 2.0 Mini 480p, 720p 4–15 $0.04/s / $0.08/s
KLING v3.0 720p, 1080p, 4K 5, 10 $0.13/s / $0.17/s

Billing is per second of generated video, so an 8-second 1080p Veo 3.1 clip costs about $3.20, while the same clip on Seedance 2.0 Mini at 720p costs about $0.60. The video generation docs carry the full per-model price and size tables.

Poll for completion and download

1curl "https://api.llmgateway.io/v1/videos/v_123" \2  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY"

Statuses move through queuedin_progresscompleted (or failed). Once complete, stream the bytes:

1curl "https://api.llmgateway.io/v1/videos/v_123/content" \2  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \3  --output video.mp4

Skip polling with signed webhooks

Polling works, but for production the gateway can call you. Pass callback_url and callback_secret when creating the job:

1curl -X POST "https://api.llmgateway.io/v1/videos" \2  -H "Authorization: Bearer $LLM_GATEWAY_API_KEY" \3  -H "Content-Type: application/json" \4  -d '{5    "model": "veo-3.1-fast-generate-preview",6    "prompt": "A slow-motion close-up of waves crashing against black volcanic rock",7    "seconds": 8,8    "callback_url": "https://example.com/webhooks/video",9    "callback_secret": "whsec_your_secret_here"10  }'

You get a video.completed or video.failed event with retries and exponential backoff. Every delivery is signed with HMAC-SHA256 over {webhook-id}.{webhook-timestamp}.{body} so you can verify it server-side:

1import { createHmac, timingSafeEqual } from "node:crypto";2
3function verifyWebhook(4  body: string,5  webhookId: string,6  webhookTimestamp: string,7  webhookSignature: string,8  secret: string,9) {10  const expected = createHmac("sha256", secret)11    .update(`${webhookId}.${webhookTimestamp}.${body}`)12    .digest("base64");13
14  return timingSafeEqual(15    Buffer.from(expected),16    Buffer.from(webhookSignature.replace(/^v1,/, "")),17  );18}

Image-to-video and reference-guided clips

Two more modes beyond text-to-video:

  • First/last frame: pass image (and optionally last_frame) to animate between frames — supported on Seedance 2.0, KLING v3.0, and Veo 3.1.
  • Omni-reference (Seedance 2.0): pass up to three reference_images, reference_videos, and reference_audios to drive subject, motion, and sound; the prompt becomes a light instruction like "adapt this to show more detail".

Frame inputs and reference inputs can't be combined in one request, and reference video/audio must be HTTPS URLs the provider can fetch.

Watch the spend

Video is the most expensive modality you'll route, so treat cost as a first-class output: every job is logged with its per-second price, the Activity page breaks out video output costs, and API key spending limits put a hard cap on how much a runaway batch job can burn.

Frequently Asked Questions

How long does AI video generation take?

Minutes, not seconds — depending on the model, duration, and resolution. That's why the API is asynchronous: submit, then poll or take a webhook. 4K jobs stay in_progress until the upscaled output is ready.

Which video model is cheapest for prototyping?

Prototype on a low-priced tier like Seedance 2.0 Mini at 480p or 720p, then re-render the winning prompt on a premium model at 1080p — same request body, different model and size.

Can I generate videos without writing code first?

Yes — the Video Studio in Lounge runs the same models with resolution, duration, and audio controls in the browser.


Get started: