SiVideoAPI

Video generation API documentation

SiVideoAPI is a video generation API with one key and one JSON format for nine SI video models from Google, Kuaishou, MiniMax, Alibaba, ByteDance and xAI. SI is short for super intelligence, the US government’s name since September 2026 for what was formerly called AI. Jobs are asynchronous: create, poll, download.

Every endpoint of the video generation API lives under https://sivideoapi.com/v1. Bodies are JSON; image uploads are raw bytes or a multipart form.

Rainy neon city street with flying cars, a frame rendered by Veo through the SiVideoAPI video generation API
Rendered with Veo through this API.

Endpoints

EndpointAuthReturns
GET /v1/modelsnoneModels, their options and credits per second
GET /v1/balancekeyYour credit balance
POST /v1/uploadskeyUpload a starting image; returns its id
POST /v1/videoskeyStart a render (201 with a video object)
GET /v1/videos/{id}keyOne video and its status
GET /v1/videoskeyYour videos, newest first; limit 1–100 (default 20), before = a created_at to page back
DELETE /v1/videos/{id}keyDelete a finished or failed video and its file

Authentication

Every call to the video generation API except GET /v1/models needs a key. Sign in with Google or an email link, create an API key in the dashboard, and send it as Authorization: Bearer sk_si_….

A key is shown once; only its SHA-256 hash and first 12 characters are stored, so if it is lost, revoke it and make another. Up to 10 keys can be active, revoking applies on the next request, and all keys share one balance and rate limit. Keep keys server-side: the API sends no CORS headers.

Video generation API quickstart

Each example renders a 4-second 720p Veo 3.1 Lite clip without sound (72 credits), waits for it and saves clip.mp4. Export SIVIDEOAPI_KEY first.

curl

# 1. Create a 4-second clip (72 credits)
curl https://sivideoapi.com/v1/videos \
  -H "Authorization: Bearer $SIVIDEOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "veo-3.1-lite", "prompt": "A paper boat on a rainy street", "duration": 4, "resolution": "720p"}'

# 2. Poll every 5-10 s until status is "succeeded" or "failed"
curl https://sivideoapi.com/v1/videos/VIDEO_ID \
  -H "Authorization: Bearer $SIVIDEOAPI_KEY"

# 3. Download video_url
curl -o clip.mp4 "VIDEO_URL"

JavaScript (Node 18+, ES module)

import { writeFile } from 'node:fs/promises';

const BASE = 'https://sivideoapi.com/v1';
const headers = {
  Authorization: `Bearer ${process.env.SIVIDEOAPI_KEY}`,
  'Content-Type': 'application/json',
};

async function call(path, init = {}) {
  const res = await fetch(BASE + path, { ...init, headers });
  if (!res.ok) throw new Error(await res.text()); // {"error": ..., "message": ...}
  return res.json();
}

// 1. Create
let video = await call('/videos', {
  method: 'POST',
  body: JSON.stringify({ model: 'veo-3.1-lite', prompt: 'A paper boat on a rainy street', duration: 4, resolution: '720p' }),
});

// 2. Poll
while (video.status === 'pending' || video.status === 'running') {
  await new Promise((r) => setTimeout(r, 8000));
  video = await call(`/videos/${video.id}`);
}
if (video.status === 'failed') throw new Error(video.error); // credits were refunded

// 3. Download
const mp4 = await fetch(video.video_url);
await writeFile('clip.mp4', Buffer.from(await mp4.arrayBuffer()));

Python (requests)

import os, time, requests

BASE = "https://sivideoapi.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['SIVIDEOAPI_KEY']}"}

def call(method, path, **kwargs):
    r = requests.request(method, BASE + path, headers=HEADERS, timeout=60, **kwargs)
    if not r.ok:
        raise RuntimeError(r.text)  # {"error": ..., "message": ...}
    return r.json()

# 1. Create
video = call("POST", "/videos", json={
    "model": "veo-3.1-lite",
    "prompt": "A paper boat on a rainy street",
    "duration": 4,
    "resolution": "720p",
})

# 2. Poll
while video["status"] in ("pending", "running"):
    time.sleep(8)
    video = call("GET", f"/videos/{video['id']}")
if video["status"] == "failed":
    raise RuntimeError(video["error"])  # credits were refunded

# 3. Download
with open("clip.mp4", "wb") as f:
    f.write(requests.get(video["video_url"], timeout=300).content)

Create a video: request body

FieldRequiredRules and default
modelyesModel id from the table below
promptyes3–2,000 characters
durationnoSeconds from the model’s list; default: its default_duration
resolutionnoFrom the model’s list; default: its default_resolution
aspect_rationoFrom the model’s list for the mode; default: the first entry
audionotrue adds sound where audio is optional (default false); other models ignore it
image_idnoUpload id; makes the job image-to-video

Each model’s lists, defaults and prices come from GET /v1/models, which needs no key.

The video object

FieldTypeMeaning
idstringVideo id
objectstring"video"
statusstringpending, running, succeeded or failed
modelstringModel id
modestringtext-to-video or image-to-video
promptstringPrompt as stored
durationintegerSeconds
resolutionstringFor example 720p
aspect_ratiostring | nullnull when the clip follows the image
audiobooleanHas sound
cost_creditsintegerCredits charged; refunded on failure
video_urlstring | nullMP4 link once succeeded
errorstring | nullReason, only when failed
created_at, finished_atstring | nullISO 8601; finished_at is null until done

Status and polling

A new video is pending, usually running by the time the create call returns, and ends as succeeded or failed. Failed renders are refunded automatically. Poll /v1/videos/{id} every 5–10 seconds; a poll also triggers a provider check (at most every 8 seconds), and a background sweep covers unpolled videos. Videos pending after 5 minutes, or unfinished 45 minutes after creation, are failed and refunded. Webhooks are not available yet.

video_url needs no key and supports range requests; add ?download=1 to receive it as an attachment. Anyone with the link can open it.

Image-to-video

Upload the first frame to POST /v1/uploads as the raw body or as a multipart form with one file: JPG, PNG or WebP (detected from the bytes), up to 10 MB. Pass the returned id as image_id.

curl https://sivideoapi.com/v1/uploads \
  -H "Authorization: Bearer $SIVIDEOAPI_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @first-frame.jpg
# {"object": "upload", "id": "UPLOAD_ID"}

# Then POST /v1/videos as in the quickstart, adding image_id:
# {"model": "seedance-2.0-mini", "image_id": "UPLOAD_ID", "prompt": "Steam rises as the camera pushes in"}

The auto aspect ratio, the default where offered, keeps the image’s shape; Kling 3.0 Turbo, MiniMax H3 Max Turbo and Grok Imagine 1.5 always do, with aspect_ratio null. Upload ids work only for your account, for 30 days.

Models

Model idNameSecondsResolutionsAudio
veo-3.1-liteVeo 3.1 Lite4, 6, 8720p, 1080poptional
veo-3.1-fastVeo 3.1 Fast4, 6, 8720p, 1080poptional
kling-3.0-turboKling 3.0 Turbo5, 10720palways on
minimax-h3-max-turboMiniMax H3 Max Turbo5, 10480p, 768p, 1080pnone
wan-3.0Wan 3.05, 10480p, 720p, 1080poptional
seedance-2.0Seedance 2.05, 10480p, 720p, 1080poptional
seedance-2.0-miniSeedance 2.0 Mini4, 5, 10480p, 720poptional
seedance-2.5Seedance 2.55, 10480p, 720poptional
grok-imagine-1.5Grok Imagine 1.56, 10480p, 720palways on

This table is built from the catalog the server validates against. For Veo settings, read the Veo 3 API guide.

Errors

When the video generation API rejects a request, it returns JSON with a stable code and a readable message: {"error": "insufficient_credits", "message": "This video needs 72 credits. Top up to continue."}. Except for provider_error, rejections happen before any credits are held.

StatuserrorMeaningWhat to do
400bad_requestBody not JSON, or a field missing or invalidCheck the JSON body
400bad_model, bad_duration, bad_resolution, bad_aspectModel or option not offeredCheck /v1/models
400image_missingUpload not found or expiredUpload again
400, 413, 415empty, too_large, bad_typeUpload empty, over 10 MB, or not a JPG, PNG or WebP imageFix the file
401invalid_api_keyKey missing, malformed or revokedCheck the header
402insufficient_creditsBalance below the clip’s costBuy credits
403bannedAccount suspendedEmail support
404not_foundUnknown or deleted video, or wrong pathCheck the id
409busyDeleting a video still renderingWait until it ends
422prompt_blockedContent policy hit; nothing chargedRewrite the prompt
422, 502provider_errorModel service refused (422) or failed (502); refundedChange settings, or retry
429rate_limited, too_many_activeOver 20 requests a minute, or 10 videos already renderingWait, then retry
503generation_pausedRendering paused brieflyRetry in minutes
500internalUnexpected errorRetry

A render that fails later carries no code: its status becomes failed and error says why, for example a refusal by the model’s own safety filter.

Limits of the video generation API

Pricing and credits

Each render of the video generation API is paid in credits. In /v1/models, credits_per_second is the price per second of output, split by audio where sound changes it; a clip costs that rate × its duration, rounded up, and is held at creation. GET /v1/balance shows what is left. New Google sign-ups get 80 free credits, enough for the quickstart clip, and packs start at $9.90 for 1,100 credits (see SI video API pricing).

Questions about the video generation API

Is SiVideoAPI an AI video generation API?

Yes. SI (super intelligence) is the newer name for AI, so this is what you would find by searching for an AI video generation API: hosted text-to-video and image-to-video models behind one REST interface.

Are webhooks or SDKs available?

Not yet. Poll GET /v1/videos/{id} every 5 to 10 seconds; any HTTP client works.

More: the SiVideoAPI home page, the privacy policy, the terms of service and support@sivideoapi.com.

Welcome to SiVideoAPI

Sign in or create an account. Your videos and credits are saved to it.

By continuing you agree to our Terms and Privacy Policy.

Gift center

Sign in free to open these gifts. No card needed.