Vidgen API v2

Introduction

The Vidgen API provides AI-powered video generation using multi-scene diffusion models. Each generation produces a 5-second scene (up to 5 scenes), with optional upscaling, background music, FX sound, content credentials, and watermarking. All workflow construction and post-processing are handled server-side.

  • Multi-scene video generation (1 to 5 scenes per request)
  • Text-to-video (t2v) and image-to-video (i2v) modes per scene
  • Optional AI upscaling and RIFE frame interpolation
  • Optional background music and FX sound generation
  • Pre-generation content compliance checking
  • C2PA manifest signing, watermark embedding, and fingerprinting
  • S3-hosted output with pre-signed URLs for video and thumbnail

Base URL

POST https://vidgen.umbrosus.com/api/v2
Content-Type: application/json
Authorization: Bearer <API-KEY>

{
  "action": "generate",
  ...
}

Authentication

Authorization: Bearer <API-KEY>

API keys are managed through the admin panel.

Prompt Syntax

TokenSyntaxExampleDescription
Negative-term-blurryComma-separated term prefixed with - is moved to negative prompt.
Positiveeverything elsewoman dancing, smooth cameraDescriptive prompt text.

Endpoints

POST models

{ "action": "models" }

Response

{
  "models": {
    "wan22": { "label": "Wan 2.2" }
  },
  "max_scenes": 5
}

POST generate

Request Parameters

ParameterTypeRequiredDefaultDescription
actionstringyes"generate"
scenesarrayyes1 to max_scenes scene objects.
scenes[].promptstringyesScene prompt. Supports -negative.
scenes[].negativestringno""Additional negatives for the scene.
scenes[].start_framestringnoBase64 data URI of the start frame (i2v).
scenes[].end_framestringnoBase64 data URI of the end frame (i2v).
modelstringnofirst modelModel key.
sizeintegerno720Max dimension for i2v resize (720–1280).
widthintegerno832Width for t2v mode (divisible by 8).
heightintegerno480Height for t2v mode (divisible by 8).
upscalebooleannofalseEnable 2x AI upscaling.
optimizebooleannofalseLLM-enhance each scene prompt.
music.enabledbooleannofalseEnable background music.
music.tagsstringno""Music style tags.
music.lyricsstringno"[Inst]"Lyrics or instrumental marker.
music.bpmintegerno85Tempo.
music.keyscalestringno"Eb minor"Key signature.
fx_sound.enabledbooleannofalseEnable FX sound.
fx_sound.promptstringno""FX audio prompt.
fx_sound.negative_promptstringno""FX negative prompt.
wm_*variousnoWatermark options (position, scale, etc.).
cs_*stringnoC2PA metadata overrides.
Scene modesNo frames → text-to-video. Start frame only → image-to-video. Both frames → first-last frame to video.

Response

{
  "id": "run_abc123",
  "gen_id": "a1b2c3d4e5f6g7h8i9j0",
  "model": "wan22",
  "scenes": [{ "prompt": "scene prompt text" }]
}

POST status

{
  "action": "status",
  "id": "run_abc123",
  "model": "wan22"
}

Completed (Safe)

{
  "status": "COMPLETED",
  "meta": {
    "id": "run_abc123",
    "gen_id": "a1b2c3d4e5f6g7h8i9j0",
    "compliance": "safe",
    "fingerprint": "a4f8e2c1...",
    "images": [
      { "url": "https://s3.../video.mp4?...", "filename": "genid_fp_00001.mp4", "type": "signed" },
      { "url": "https://s3.../thumb.jpg?...", "filename": "genid_fp_00001_thumb.jpg", "type": "thumbnail" }
    ]
  }
}

POST optimize

{
  "action": "optimize",
  "prompt": "woman walking in rain",
  "model": "wan22"
}

POST random

{ "action": "random" }

Polling Strategy

SettingRecommended
Interval5 seconds
Max polls360 (30 min timeout)

Video generation takes ~100s per scene at 480p, 4–5× longer at 720p.

Error Handling

StatusErrorCause
400scenes array is requiredMissing or empty scenes
400Content blockedPre-generation ACS check failed
401UnauthorizedInvalid API key
502Generation failedUpstream error

Code Examples

const API = 'https://vidgen.umbrosus.com/api/v2';
const TOKEN = 'your-api-key';

async function api(body) {
  const r = await fetch(API, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${TOKEN}` },
    body: JSON.stringify(body)
  });
  return r.json();
}

async function generateVideo(scenes, opts = {}) {
  const job = await api({
    action: 'generate', scenes, model: opts.model || 'wan22',
    size: opts.size || 720, upscale: opts.upscale || false
  });
  if (job.error) throw new Error(job.error);
  for (let i = 0; i < 360; i++) {
    await new Promise(r => setTimeout(r, 5000));
    const s = await api({ action: 'status', id: job.id, model: job.model });
    if (s.status === 'IN_QUEUE' || s.status === 'IN_PROGRESS') continue;
    if (s.status === 'COMPLETED') {
      if (s.compliance === 'unsafe') throw new Error(s.error);
      return s.meta;
    }
    throw new Error(s.error || 'Failed: ' + s.status);
  }
  throw new Error('Timeout');
}

const meta = await generateVideo([{ prompt: 'cinematic ocean waves at sunset' }]);
const video = meta.images.find(i => i.type === 'signed');
console.log('Video URL:', video?.url);
import requests, time

API = "https://vidgen.umbrosus.com/api/v2"
TOKEN = "your-api-key"

def api(body):
    return requests.post(API, json=body, headers={"Authorization": f"Bearer {TOKEN}"}).json()

def generate(scenes, model="wan22", size=720):
    job = api({"action":"generate","scenes":scenes,"model":model,"size":size})
    if "error" in job: raise Exception(job["error"])
    for _ in range(360):
        time.sleep(5)
        s = api({"action":"status","id":job["id"],"model":job["model"]})
        if s["status"] in ("IN_QUEUE","IN_PROGRESS"): continue
        if s["status"] == "COMPLETED":
            if s.get("compliance") == "unsafe": raise Exception(s.get("error"))
            return s["meta"]
        raise Exception(s.get("error", f"Failed: {s['status']}"))
    raise TimeoutError("Polling timed out")

meta = generate([{"prompt": "cinematic ocean waves at sunset"}])
video = next(i for i in meta["images"] if i["type"] == "signed")
print("URL:", video["url"])