🐎 Coming soonHappy Horse 1.0 by Alibaba · #1 on Artificial Analysis · open-source · API landing late April
VideoGenAI
API reference

Build on VideoGenAI.

REST API, idempotent job submission, streaming webhook events, first-class SDKs in JS/Py/Go. Available from Studio tier upwards.

Base URL
https://api.videogenai.io
TLS 1.3 only. IPv4 + IPv6.
Auth
Authorization: Bearer sk_...
Rotate keys from the dashboard.
Rate limits
100 req/min · 16 concurrent renders
Studio tier. Enterprise raises both.

Your first render in 60 seconds

copy · paste · run
# 1. Export your key (get it from the dashboard).
export VGAI_API_KEY=sk_live_...

# 2. Submit a render.
curl -s https://api.videogenai.io/v1/renders \
  -H "Authorization: Bearer $VGAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "prompt": "a golden retriever running on a beach at dusk", "duration_sec": 8 }' \
  | tee render.json

# 3. Wait, then fetch.
ID=$(jq -r .id render.json)
while [ "$(curl -s https://api.videogenai.io/v1/renders/$ID \
  -H "Authorization: Bearer $VGAI_API_KEY" | jq -r .status)" != "completed" ]; do sleep 2; done

curl -s https://api.videogenai.io/v1/renders/$ID \
  -H "Authorization: Bearer $VGAI_API_KEY" | jq -r .url

Authentication

API keys

Create keys from Settings → API keys. Each key is sk_live_ or sk_test_. Test keys only hit the preview model pool and are free.

  • Rotate keys without downtime; old key is valid for 30 minutes after revocation.
  • Scope keys to a single project, or grant workspace-wide access.
  • Optional IP allowlist per key (CIDR).

SSO & SCIM (Infinite)

Workspaces on Infinite get SAML 2.0 or OIDC sign-in, plus SCIM 2.0 for user provisioning. Org-level API keys can require hardware-backed auth before creation.

OktaEntra IDGoogle WorkspaceAuth0Ping

Endpoints

POST/v1/renders
Submit a new render job. Returns 202 with a job id. Pass Idempotency-Key to make retries safe.
Request
curl https://api.videogenai.io/v1/renders \
  -H "Authorization: Bearer $VGAI_API_KEY" \
  -H "Idempotency-Key: 0a8f…" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "cinematic drone shot over a neon tokyo skyline at dusk",
    "resolution": "1080p",
    "duration_sec": 30,
    "aspect_ratio": "16:9",
    "seed": 42,
    "format": "mp4",
    "model_hint": "auto",
    "webhook_url": "https://yourapp.com/hooks/vgai"
  }'
Response
{
  "id": "rnd_01HZ...",
  "status": "queued",
  "created_at": "2026-04-18T16:12:09Z",
  "model_chosen": "kling-3",
  "estimated_tokens": 60,
  "estimated_usd": 1.89,
  "estimated_ready_at": "2026-04-18T16:12:51Z"
}
GET/v1/renders/:id
Get the current status of a render. Poll this or subscribe via webhook.
Request
curl https://api.videogenai.io/v1/renders/rnd_01HZ... \
  -H "Authorization: Bearer $VGAI_API_KEY"
Response
{
  "id": "rnd_01HZ...",
  "status": "completed",
  "progress": 1.0,
  "url": "https://cdn.videogenai.io/renders/rnd_01HZ.../out.mp4",
  "thumbnail_url": "https://cdn.videogenai.io/renders/rnd_01HZ.../poster.jpg",
  "duration_sec": 30,
  "resolution": "1080p",
  "tokens_consumed": 60,
  "billed_usd": 1.89,
  "model_used": "kling-3",
  "completed_at": "2026-04-18T16:12:49Z"
}
GET/v1/renders
List your renders. Cursor pagination, filter by status / created_at / tag.
Request
curl "https://api.videogenai.io/v1/renders?status=completed&limit=20" \
  -H "Authorization: Bearer $VGAI_API_KEY"
Response
{
  "data": [
    { "id": "rnd_01HZ...", "status": "completed", "created_at": "..." },
    { "id": "rnd_01HY...", "status": "completed", "created_at": "..." }
  ],
  "has_more": true,
  "next_cursor": "rnd_01HX..."
}
POST/v1/renders/:id/retry
Retry a failed render with the same spec. Counts as a fresh job; old job is refunded.
Request
curl -X POST https://api.videogenai.io/v1/renders/rnd_01HZ.../retry \
  -H "Authorization: Bearer $VGAI_API_KEY"
Response
{
  "id": "rnd_01J0...",
  "retry_of": "rnd_01HZ...",
  "status": "queued"
}
DELETE/v1/renders/:id
Cancel a queued render and refund its token hold.
Request
curl -X DELETE https://api.videogenai.io/v1/renders/rnd_01HZ... \
  -H "Authorization: Bearer $VGAI_API_KEY"
Response
{
  "id": "rnd_01HZ...",
  "status": "canceled",
  "refunded_tokens": 60
}
GET/v1/models
List models currently available in the routing pool and their per-category suitability scores.
Request
curl https://api.videogenai.io/v1/models \
  -H "Authorization: Bearer $VGAI_API_KEY"
Response
{
  "data": [
    { "id": "kling-3", "version": "3.0.4", "best_for": ["social", "action"] },
    { "id": "veo-3-1", "version": "3.1.0", "best_for": ["physics", "fluids"] },
    { "id": "runway-4-5", "version": "4.5.2", "best_for": ["narrative"] }
  ]
}
POST/v1/assets
Upload a reference image or video for image-to-video / style remix. Returns a signed asset id.
Request
curl -X POST https://api.videogenai.io/v1/assets \
  -H "Authorization: Bearer $VGAI_API_KEY" \
  -F "file=@reference.jpg" \
  -F "kind=image"
Response
{
  "id": "ast_01HZ...",
  "kind": "image",
  "expires_at": "2026-04-19T16:12:09Z",
  "url": "https://cdn.videogenai.io/assets/ast_01HZ..."
}
GET/v1/usage
Query token usage for a billing period, grouped by day / project / user.
Request
curl "https://api.videogenai.io/v1/usage?period=2026-04&group_by=project" \
  -H "Authorization: Bearer $VGAI_API_KEY"
Response
{
  "period": "2026-04",
  "total_tokens": 18420,
  "total_usd": 581.23,
  "by_project": [
    { "project_id": "prj_ads",   "tokens": 11200, "usd": 352.12 },
    { "project_id": "prj_shorts","tokens":  7220, "usd": 229.11 }
  ]
}
GET/v1/webhooks
List webhook endpoints configured on your workspace.
Request
curl https://api.videogenai.io/v1/webhooks \
  -H "Authorization: Bearer $VGAI_API_KEY"
Response
{
  "data": [
    { "id": "whk_01HZ...", "url": "https://yourapp.com/hooks/vgai",
      "events": ["render.completed", "render.failed"], "active": true }
  ]
}

Models & routing

By default every prompt goes through our router and lands on whichever model scores highest for that category on our weekly eval. You can pin a specific model with model_hint, but the cost is fixed to that model's rate.

idbest formax resRoute weight
seedance-2-0cinematic, stylised1080p
58%
seedance-1-5-profast lane, throwaways1080p
21%
happy-horse-1-0rolling out soon1080p
12%
internal-litepreviews720p
9%

Webhooks

Skip polling. Provide a webhook_url on render create and we'll POST the final payload to your endpoint when the job completes. Every event is signed with HMAC-SHA256 — verify with the shared secret from your dashboard.

POST / HTTP/1.1
Content-Type: application/json
VGAI-Signature: t=1713456789,v1=9d3f...
VGAI-Event: render.completed
VGAI-Delivery: dlv_01HZ...

{
  "type": "render.completed",
  "data": {
    "id": "rnd_01HZ...",
    "url": "https://cdn.videogenai.io/renders/rnd_01HZ.../out.mp4",
    "tokens_consumed": 60,
    "billed_usd": 1.89
  }
}
Events catalogue
eventwhenpayload
render.startedJob has been picked up by a worker.id, model_chosen, started_at
render.progressEvery 10% of progress (10%, 20%, …).id, progress (0–1), eta_seconds
render.completedRender succeeded and the file is on CDN.id, url, thumbnail_url, tokens_consumed, billed_usd
render.failedRender failed and tokens were refunded.id, reason, refunded_tokens
render.canceledRender was canceled via DELETE before completion.id, canceled_at, refunded_tokens
webhook.testFired when you press Test in the dashboard.id, nonce, created_at

Verifying a signature (Node)

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody: string, header: string, secret: string) {
  const [ts, v1] = header.split(",").map((p) => p.split("=")[1]);
  const mac = createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex");
  return timingSafeEqual(Buffer.from(mac, "hex"), Buffer.from(v1, "hex"));
}

Rate limits per tier

tierapi accessreq / minconcurrent rendersbatch size
Sparkno
Boostno
Prono
Studioyes100 / min1632
Infiniteyes600 / min64128

Every rate-limited response includes Retry-After and X-RateLimit-Reset. Our SDKs honour both automatically.

Errors

codenamemeaning
400bad_requestMalformed body or unsupported parameter combo.
401unauthorizedMissing or invalid API key.
402payment_requiredInsufficient tokens; top up or upgrade tier.
403forbiddenKey lacks access to this endpoint (needs Studio+).
404not_foundRender, asset or webhook id doesn't exist in this workspace.
409conflictIdempotency-Key reused with a different body.
422unprocessable_entityPrompt blocked by moderation filter.
429rate_limitedExceeded per-minute or per-second limit. Retry after header.
500internalTransient failure on our side. Safe to retry.
503unavailableMaintenance window. Respect Retry-After.
Error envelope
{
  "error": {
    "code": "rate_limited",
    "message": "Too many renders this minute.",
    "docs": "https://videogenai.io/developers#errors",
    "request_id": "req_01HZ..."
  }
}

Every error carries a request_id. Include it when you reach out — we can tail logs in one step.

Idempotency & retries

Idempotency-Key

POST endpoints accept an Idempotency-Key header. Send it on every retry and we'll guarantee exactly one render is queued even if your retry storm triples.

# Safe to retry — same key, same body, same result.
curl https://api.videogenai.io/v1/renders \
  -H "Authorization: Bearer $VGAI_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "prompt": "...", "duration_sec": 8 }'

Retry policy

  • Safe to retry: 408, 429, 5xx
  • Do not retry: 4xx other than the ones above.
  • Back-off: exponential, 250ms base, cap 30s, 5 attempts max. Our SDKs default to this.

Pagination

All list endpoints use cursor pagination. Pass limit (default 20, max 100) and cursor (opaque string from the previous response's next_cursor). Order is always newest-first.

curl "https://api.videogenai.io/v1/renders?limit=50&cursor=rnd_01HX..." \
  -H "Authorization: Bearer $VGAI_API_KEY"

Versioning & stability

Versioning

Path prefix (/v1/…). Breaking changes go to /v2 with 12 months overlap.

Beta endpoints

Marked in responses with VGAI-Beta: 1. Shape may change; we'll email you 30 days before any breaking update.

Status

99.98% rolling uptime. Reach out if you see elevated latency and we'll reply with the root cause within one business day.

Client libraries

JavaScript / TypeScript

npm install @videogenai/sdk

Works in Node 18+, Bun, Deno, and Edge runtimes.

import { VideoGenAI } from "@videogenai/sdk";

const client = new VideoGenAI({ apiKey: process.env.VGAI_API_KEY });

const render = await client.renders.create({
  prompt: "slow-motion waves crashing on a pebble beach",
  resolution: "1080p",
  durationSec: 16,
});

const done = await client.renders.waitFor(render.id);
console.log(done.url);

Python

pip install videogenai

Python 3.9+. Asyncio-native; sync wrappers included.

from videogenai import VideoGenAI

client = VideoGenAI(api_key=os.environ["VGAI_API_KEY"])

render = client.renders.create(
    prompt="slow-motion waves crashing on a pebble beach",
    resolution="1080p",
    duration_sec=16,
)

done = client.renders.wait_for(render.id)
print(done.url)

Go

go get github.com/videogenai/videogenai-go

Zero-dep client, context-aware.

client := videogenai.NewClient(os.Getenv("VGAI_API_KEY"))

render, err := client.Renders.Create(ctx, &videogenai.RenderParams{
    Prompt:      "slow-motion waves crashing on a pebble beach",
    Resolution:  videogenai.Resolution1080p,
    DurationSec: 16,
})
SDK feature matrix
featureJSPythonGo
Async / awaityesyesyes
Streaming progressyesyesbeta
waitFor helperyesyesno
Automatic retriesyesyesyes
Idempotency key helperyesyesyes
Webhook verify helperyesyesyes
Assets uploadyesyesbeta
TypeScript typesyes

Ship with the API in an afternoon.

API access unlocks on Studio tier. Start on any plan, upgrade when you're ready.