Video Generation
Endpoints
Section titled “Endpoints”POST /v1/videos/generations # submit jobGET /v1/videos/generations/{id} # poll statusVideo generation is asynchronous. The submit call returns immediately with a job id and a poll_url; the client polls until status is completed (or failed).
Submit Request
Section titled “Submit Request”| Field | Type | Default | Description |
|---|---|---|---|
model | string | "auto" | Video model (see Providers). Use "auto" for health-aware routing. |
prompt | string | required | Text description. 1–8000 chars. |
duration_seconds | number | provider default | 1–60 seconds. Most models cap at 4–10s on free tier. |
aspect_ratio | string | "16:9" | One of "16:9", "9:16", "1:1". |
image_url | string | — | Public HTTPS image URL for image-to-video models (Wan 2.6, Wan 2.2 I2V). |
project_id | string | — | Body-level project tag. Alternative to x-gateway-project-id header. |
Required Header
Section titled “Required Header”| Header | Required | Description |
|---|---|---|
Authorization: Bearer <GATEWAY_API_KEY> | yes | Gateway API key. |
x-gateway-project-id | yes (or body project_id) | 1–64 chars [a-zA-Z0-9._:-]. |
Providers
Section titled “Providers”All video models currently route through Together AI (TOGETHER_API_KEY required).
| Model ID | Upstream Model | Capabilities |
|---|---|---|
sora-2 | openai/sora-2 | Text-to-video |
veo-3-audio | google/veo-3.0-audio | Text-to-video with audio |
veo-3-fast-audio | google/veo-3.0-fast-audio | Faster Veo 3 variant with audio |
veo-2 | google/veo-2.0 | Text-to-video |
kling-2.1-master | kwaivgI/kling-2.1-master | High-quality Kling |
kling-2.1-pro | kwaivgI/kling-2.1-pro | Kling pro tier |
kling-2.0-master | kwaivgI/kling-2.0-master | Previous-gen Kling |
kling-1.6-pro | kwaivgI/kling-1.6-pro | Kling 1.6 |
wan-2.6-image | Wan-AI/Wan2.6-image | Image-to-video |
wan-2.2-i2v | Wan-AI/Wan2.2-I2V-A14B | Image-to-video |
vidu-q1 | vidu/vidu-q1 | Text-to-video |
seedream-3 | ByteDance-Seed/Seedream-3.0 | ByteDance Seedream |
seedream-4 | ByteDance-Seed/Seedream-4.0 | ByteDance Seedream v4 |
Daily free-tier limits are tight (typically 10–30 requests per model per day). See GET /v1/models for the live enabled list.
Submit Response
Section titled “Submit Response”Status 202 Accepted when the job is queued, or 200 OK if the provider happens to return a finished job synchronously.
{ "id": "job_abc123", "status": "processing", "poll_url": "/v1/videos/generations/job_abc123", "x_gateway": { "provider": "together", "model": "openai/sora-2", "attempts": 1, "request_id": "req_xyz", "project_id": "my_project" }}Poll Response
Section titled “Poll Response”{ "id": "job_abc123", "status": "completed", "video_url": "https://cdn.example/video.mp4", "x_gateway": { "provider": "together", "model": "openai/sora-2", "attempts": 1, "request_id": "req_poll1", "project_id": "my_project" }}status is one of "processing", "completed", "failed". When failed, error contains the upstream message.
Examples
Section titled “Examples”Submit
Section titled “Submit”curl https://free-ai-gateway.sarthakagrawal927.workers.dev/v1/videos/generations \ -H "Authorization: Bearer <GATEWAY_API_KEY>" \ -H "x-gateway-project-id: my_project" \ -H "Content-Type: application/json" \ -d '{ "model": "sora-2", "prompt": "A slow aerial drone shot over a misty mountain lake at dawn", "duration_seconds": 5, "aspect_ratio": "16:9" }'const res = await fetch('https://free-ai-gateway.sarthakagrawal927.workers.dev/v1/videos/generations', { method: 'POST', headers: { 'Authorization': 'Bearer <GATEWAY_API_KEY>', 'x-gateway-project-id': 'my_project', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'sora-2', prompt: 'A slow aerial drone shot over a misty mountain lake at dawn', duration_seconds: 5, aspect_ratio: '16:9', }),});
const job = await res.json();console.log('Job ID:', job.id, 'Status:', job.status);Poll until complete
Section titled “Poll until complete”const BASE = 'https://free-ai-gateway.sarthakagrawal927.workers.dev';
async function pollUntilDone(jobId, { interval = 5000, timeout = 300_000 } = {}) { const deadline = Date.now() + timeout; while (Date.now() < deadline) { const res = await fetch(`${BASE}/v1/videos/generations/${jobId}`, { headers: { 'Authorization': 'Bearer <GATEWAY_API_KEY>' }, }); const body = await res.json(); if (body.status === 'completed') return body.video_url; if (body.status === 'failed') throw new Error(body.error ?? 'job failed'); await new Promise((r) => setTimeout(r, interval)); } throw new Error('poll timeout');}
const videoUrl = await pollUntilDone('job_abc123');console.log(videoUrl);Image-to-video (Wan)
Section titled “Image-to-video (Wan)”curl https://free-ai-gateway.sarthakagrawal927.workers.dev/v1/videos/generations \ -H "Authorization: Bearer <GATEWAY_API_KEY>" \ -H "x-gateway-project-id: my_project" \ -H "Content-Type: application/json" \ -d '{ "model": "wan-2.2-i2v", "prompt": "Camera pans right as clouds roll in", "image_url": "https://example.com/source-frame.jpg", "duration_seconds": 4 }'Error Codes
Section titled “Error Codes”| Status | code | Meaning |
|---|---|---|
| 400 | invalid_project_id | Missing/invalid project_id. |
| 404 | — | Job ID unknown, or upstream poll endpoint returned 404 (see beta caveat above). |
| 502 | provider_error | Submit or poll failed at upstream. |
| 503 | no_video_provider | TOGETHER_API_KEY not configured. |