API reference · v1

Build with the Vidova API

Every model in the studio — 50 for video, images, voice, music, sound effects, avatars and enhancement — behind one simple REST API. Pay with the same credits, get results by polling or signed webhooks.

Introduction

The API is organised around REST: JSON request bodies, JSON responses, standard HTTP verbs and status codes. All endpoints live under a versioned base URL — breaking changes only ever ship under a new version.

https://vidova.m7ts.tech/api/v1

Generations are asynchronous: creating one returns immediately with status: "queued". Poll GET /generations/{id} or pass a webhook_url to be notified when it succeeds or fails. Failed generations are refunded automatically.

Authentication

Authenticate every request with a secret key in the Authorization header. Create up to 10 keys in Developers. Keys look like vk_live_… and are shown once — we only store a SHA-256 hash. Revoked keys stop working immediately.

curl https://vidova.m7ts.tech/api/v1/account \
  -H "Authorization: Bearer $VIDOVA_API_KEY"

Keys carry your account's full permissions and spend its credits. Keep them server-side — never in a browser or mobile bundle. API access requires the Studio plan; requests from other plans return 403 plan_required.

Errors

Errors use conventional HTTP status codes and always the same envelope. Every response carries an X-Request-Id header.

{
  "error": {
    "code": "invalid_request",
    "message": "input.duration must be one of: 4, 6, 8.",
    "param": "input.duration",
    "allowed": ["4", "6", "8"]
  }
}
invalid_request400Malformed JSON, unknown input key or a value outside a parameter's options. `param` names the field.
unauthorized401Missing, unknown or revoked API key.
insufficient_credits402Your balance can't cover the generation. Nothing was charged.
plan_required403The key's account is not on a plan with API access (Studio).
not_found / unknown_model404The resource or model doesn't exist (or isn't yours).
conflict409The resource is in a state that forbids the action (e.g. deleting a running generation).
idempotency_in_progress409A request with the same Idempotency-Key is still running.
payload_too_large413Upload over 50 MB.
unsupported_media_type415Wrong Content-Type, or a file that isn't image/video/audio.
idempotency_conflict422The Idempotency-Key was already used with a different body.
rate_limited429Too many requests. Honour the Retry-After header.
concurrency_limit429Too many generations in progress. Wait for one to settle.
provider_error502The model provider rejected the job. Credits are refunded automatically.
internal_error500Our fault. Retry with the same Idempotency-Key; include `request_id` when contacting support.

Rate limits

Limits apply per API key over a sliding one-minute window:

  • 60 requests / minute across all endpoints.
  • 20 creates / minute for POST /generations, /uploads and /autopilot.
  • Concurrent generations: up to 10 queued/running per key, and never more than your plan's parallel jobs across the whole account.

Responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 adds Retry-After (seconds). Back off exponentially on repeated 429s.

Idempotency

Network hiccups happen. Send an Idempotency-Key header (any unique string ≤ 255 chars, e.g. a UUID) on POST /generations and POST /autopilot to retry safely: a repeat with the same key and body returns the original response (with Idempotent-Replayed: true) instead of charging twice. Keys are remembered for 24 hours.

curl -X POST https://vidova.m7ts.tech/api/v1/generations \
  -H "Authorization: Bearer $VIDOVA_API_KEY" \
  -H "Idempotency-Key: 4f1c7a52-0d0e-4b8e-9a77-2c1f3f6f9a10" \
  -H "Content-Type: application/json" \
  -d '{"model":"ideogram-4","input":{"prompt":"a red fox"}}'

Models

The catalog is public — no key needed. Each model lists the media inputs it accepts, its parameters with allowed values and defaults, and the price in credits for the default settings.

List models

GET/api/v1/modelsno key
category
query, optional
One of video, image, voice, music, sfx, avatar, enhance.
Request
curl "https://vidova.m7ts.tech/api/v1/models?category=video"
Response
{
  "object": "list",
  "data": [
    {
      "id": "veo-3.1",
      "object": "model",
      "name": "Veo 3.1",
      "vendor": "Google DeepMind",
      "category": "video",
      "description": "Top-tier cinematic realism with native synchronized audio, dialogue and sound effects. Up to 4K.",
      "output": "video",
      "badges": [
        "top",
        "audio",
        "4k"
      ],
      "inputs": {
        "prompt": "required",
        "image_url": "optional"
      },
      "params": [
        {
          "key": "aspect_ratio",
          "type": "enum",
          "options": [
            "16:9",
            "9:16"
          ],
          "default": "16:9"
        },
        {
          "key": "duration",
          "type": "enum",
          "options": [
            "4",
            "6",
            "8"
          ],
          "default": "8"
        },
        {
          "key": "resolution",
          "type": "enum",
          "options": [
            "720p",
            "1080p",
            "4k"
          ],
          "default": "1080p"
        },
        {
          "key": "generate_audio",
          "type": "boolean",
          "default": true
        }
      ],
      "pricing": {
        "credits": 640,
        "per_input_second": false
      }
    }
  ]
}

Retrieve a model

GET/api/v1/models/{id}no key
Request
curl https://vidova.m7ts.tech/api/v1/models/veo-3.1

Quote a price

POST/api/v1/models/{id}/priceno key

Returns exactly what a generation with the same input will charge.

input
object
Same shape as the generation input. Omitted parameters use their defaults.
input_seconds
number, optional
Input media length, for models billed per input second (lip-sync, upscalers…).
Request
curl -X POST https://vidova.m7ts.tech/api/v1/models/veo-3.1/price \
  -H "Content-Type: application/json" \
  -d '{"input":{"duration":"8","generate_audio":true}}'
Response
{
  "model": "veo-3.1",
  "credits": 640,
  "per_input_second": false,
  "estimated": false
}

Generations

A generation runs one model once and produces one or more media outputs.

Create a generation

POST/api/v1/generations

Charges the credits up front and returns 201 with the queued generation and your new balance. Returns 402 insufficient_credits if you can't afford it.

model
string, required
A model id from GET /models.
input.prompt
string
Text prompt (required by most models).
input.negative_prompt
string
What to avoid, where supported.
input.image_url
string
Start/reference image — any public https URL or a URL from POST /uploads.
input.end_image_url
string
End frame for models that support first/last frame.
input.audio_url / video_url
string
Media input for voice, lip-sync and enhancement models.
input.<param>
string | boolean
Model parameters (aspect_ratio, duration, resolution…) — values must be one of the model's options.
input.camera
string
Camera-motion preset id (video models).
webhook_url
string, optional
https URL notified when the generation settles. See Webhooks.
Request
curl -X POST https://vidova.m7ts.tech/api/v1/generations \
  -H "Authorization: Bearer $VIDOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "veo-3.1",
  "input": {
    "prompt": "A paper boat drifting down a rainy neon street, cinematic",
    "aspect_ratio": "9:16",
    "duration": "8"
  },
  "webhook_url": "https://example.com/webhooks/vidova"
}'
Response
{
  "generation": {
    "id": "V1StGXR8_Z5jdHi6B-myT",
    "object": "generation",
    "model": "veo-3.1",
    "category": "video",
    "status": "queued",
    "input": { "prompt": "A paper boat…", "aspect_ratio": "9:16", "duration": "8" },
    "outputs": [],
    "cost": 640,
    "error": null,
    "progress": null,
    "source": "api",
    "created_at": "2026-09-24T12:00:00.000Z",
    "completed_at": null
  },
  "balance": 17360
}

Retrieve a generation

GET/api/v1/generations/{id}

Returns the latest state and advances pending work with the provider, so polling every 3–5 seconds is enough. status moves queued → running → succeeded | failed; progress is 0–1 when known.

Request
curl https://vidova.m7ts.tech/api/v1/generations/V1StGXR8_Z5jdHi6B-myT \
  -H "Authorization: Bearer $VIDOVA_API_KEY"

List generations

GET/api/v1/generations

Newest first, cursor-paginated. Pass next_cursor back as cursor until has_more is false.

limit
1–100, default 20
Page size.
cursor
string
From the previous page.
status
string
queued, running, succeeded or failed.
category / model
string
Filter by category or model id.
source
api | app
Only generations created through the API or in the studio.
Request
curl https://vidova.m7ts.tech/api/v1/generations?limit=20&status=succeeded \
  -H "Authorization: Bearer $VIDOVA_API_KEY"
Response
{
  "object": "list",
  "data": [ { "id": "…", "object": "generation", … } ],
  "has_more": true,
  "next_cursor": "WyIyMDI2LTA5LTI0IDEyOjAwOjAwLjAwMCIsIlYxU3QiXQ"
}

Delete a generation

DELETE/api/v1/generations/{id}

Permanently removes a settled generation from your library. Running generations return 409 conflict.

Request
curl -X DELETE https://vidova.m7ts.tech/api/v1/generations/V1StGXR8_Z5jdHi6B-myT \
  -H "Authorization: Bearer $VIDOVA_API_KEY"
Response
{ "id": "V1StGXR8_Z5jdHi6B-myT", "object": "generation", "deleted": true }

Uploads

Upload media

POST/api/v1/uploads

Send a multipart file (image, video or audio, ≤ 50 MB) or JSON {"url"} to re-host a public file. Use the returned url as image_url, audio_url or video_url.

Request
curl -X POST https://vidova.m7ts.tech/api/v1/uploads \
  -H "Authorization: Bearer $VIDOVA_API_KEY" \
  -F "file=@./product.jpg"
Response
{
  "upload": {
    "object": "upload",
    "url": "https://…/product.jpg",
    "content_type": "image/jpeg",
    "size": 482113
  }
}

Account

Retrieve your account

GET/api/v1/account

Credit balance, plan and the limits that apply to the calling key.

Request
curl https://vidova.m7ts.tech/api/v1/account \
  -H "Authorization: Bearer $VIDOVA_API_KEY"
Response
{
  "account": {
    "object": "account",
    "credits": 17360,
    "plan": { "id": "studio", "monthly_credits": 18000, "parallel_jobs": 20 },
    "api_key": { "id": "key_…", "name": "Production", "prefix": "vk_live_Ab12" },
    "limits": { "requests_per_minute": 60, "creates_per_minute": 20, "concurrent_generations": 10 }
  }
}

Autopilot

Turn one idea into a finished, edited video: Autopilot writes the storyboard, generates every scene, voiceover and soundtrack, and assembles them on a timeline. Credits are charged per job as production runs.

Start a run

POST/api/v1/autopilot
idea
string, required
What the video is about (3–4000 chars).
format
16:9 | 9:16 | 1:1
Default 16:9.
length
15 | 30 | 60 | 90
Target seconds. Default 30.
language
string
Narration language code, e.g. en, ar, es. Default en.
tier
express | draft | standard | premium
Quality/price tier. Default standard.
style / voice / music / captions
optional
Visual style id, narrator voice, soundtrack and captions toggles.
Request
curl -X POST https://vidova.m7ts.tech/api/v1/autopilot \
  -H "Authorization: Bearer $VIDOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "idea": "30s ad for a handmade ceramic coffee mug",
  "format": "9:16",
  "length": 30,
  "language": "en",
  "tier": "standard"
}'

Retrieve a run

GET/api/v1/autopilot/{id}

Each call advances production, so poll every 3–5 seconds. status is producing, blocked (out of credits — top up and keep polling) or succeeded, at which point editor_url opens the assembled timeline. Final MP4 export over the API is coming soon.

Request
curl https://vidova.m7ts.tech/api/v1/autopilot/run_id \
  -H "Authorization: Bearer $VIDOVA_API_KEY"
Response
{
  "run": {
    "id": "…",
    "object": "autopilot_run",
    "status": "producing",
    "progress": 0.42,
    "scenes": [ { "id": "…", "image": { "status": "succeeded", "url": "…" }, "video": { … }, "voice": { … } } ],
    "editor_url": null
  }
}

Webhooks

Pass webhook_url (https, publicly reachable) when creating a generation. When it settles we POST a generation.succeeded or generation.failed event. Any 2xx acknowledges it; timeouts (10 s), 408, 429 and 5xx are retried 3 times with backoff (5 s, 30 s, 2 min). Use Vidova-Delivery to de-duplicate.

Delivery
POST https://example.com/webhooks/vidova
Content-Type: application/json
Vidova-Event: generation.succeeded
Vidova-Delivery: evt_3kTMd9Qz0aL1nVb7cXyE
Vidova-Signature: t=1790000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

{
  "id": "evt_3kTMd9Qz0aL1nVb7cXyE",
  "object": "event",
  "event": "generation.succeeded",
  "created_at": "2026-09-24T12:01:12.000Z",
  "data": { "id": "V1StGXR8_Z5jdHi6B-myT", "object": "generation", "status": "succeeded",
            "outputs": [{ "url": "https://…/video.mp4", "type": "video" }], … }
}

Every delivery is signed with your key's signing secret (whsec_…, shown per key in Developers). The Vidova-Signature header is t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "t.body")>. Verify it against the raw body and reject timestamps older than 5 minutes.

Verify
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.VIDOVA_WEBHOOK_SECRET; // whsec_… from /app/developers

// Use the RAW body — re-serialized JSON won't match the signature.
app.post("/webhooks/vidova", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("Vidova-Signature") ?? "";
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = crypto.createHmac("sha256", SECRET).update(`${t}.${req.body}`).digest("hex");

  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300; // 5 min tolerance
  const valid = v1 && v1.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
  if (!fresh || !valid) return res.status(400).send("bad signature");

  const event = JSON.parse(req.body);
  if (event.event === "generation.succeeded") {
    console.log("done:", event.data.outputs[0]?.url);
  }
  res.sendStatus(200); // any 2xx acknowledges the delivery
});

Model catalog

Live from the registry — 50 models. Prices are credits for the default parameters; call POST /models/{id}/price for an exact quote.

video

Model idNameInputsParametersCredits
veo-3.1Veo 3.1 · Google DeepMindprompt*, image_urlaspect_ratio: 16:9|9:16; duration: 4|6|8; resolution: 720p|1080p|4k; generate_audio: bool640
veo-3.1-fastVeo 3.1 Fast · Google DeepMindprompt*, image_urlaspect_ratio: 16:9|9:16; duration: 4|6|8; resolution: 720p|1080p|4k; generate_audio: bool240
veo-3.1-liteVeo 3.1 Lite · Google DeepMindprompt*, image_urlaspect_ratio: 16:9|9:16; duration: 4|6|8; resolution: 720p|1080p; generate_audio: bool80
kling-3-proKling 3.0 Pro · Kuaishouprompt*, image_urlaspect_ratio: 16:9|9:16|1:1; duration: 5|10|15; generate_audio: bool169
kling-3-turboKling 3.0 Turbo · Kuaishouprompt*, image_urlaspect_ratio: 16:9|9:16|1:1; duration: 5|10|15140
seedance-2.5Seedance 2.5 · ByteDanceprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4|21:9; duration: 5|10|15; resolution: 720p|1080p|480p; generate_audio: bool470
seedance-2-fastSeedance 2.0 Fast · ByteDanceprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 5|10|15; resolution: 720p|480p; generate_audio: bool250
minimax-h3-maxMiniMax H3 Max · MiniMaxprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4|21:9; duration: 5|10|15; resolution: 768P|1080P|480P80
wan-3Wan 3.0 · Alibabaprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 5|10|20; resolution: 720p|1080p|480p; generate_audio: bool100
gemini-omni-flashGemini Omni Flash · Googleprompt*, image_urlaspect_ratio: 16:9|9:16; duration: 4|8|10; resolution: 720p|1080p|4k160
flux-3-videoFLUX 3 Video · Black Forest Labsprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4|21:9; duration: 5|10|15; resolution: 720p|1080p; generate_audio: bool171
ray-3.2Ray 3.2 · Luma AIprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4|21:9; duration: 5|10; resolution: 720p|1080p|540p200
pixverse-6PixVerse V6 · PixVerseprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 5|8|10; resolution: 720p|1080p|540p; generate_audio: bool45
grok-video-1.5Grok Imagine Video · xAIprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 6|10|15; resolution: 720p|1080p|480p169
ltx-2.5-proLTX 2.5 Pro · Lightricksprompt*, image_urlaspect_ratio: 16:9|9:16; duration: 6|8|10; resolution: 1080p|720p; generate_audio: bool204
vidu-q3Vidu Q3 · Shengshuprompt*, image_urlaspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 4|8|16; resolution: 720p|1080p|540p; generate_audio: bool247

image

Model idNameInputsParametersCredits
nano-banana-proNano Banana Pro · Googleprompt*, image_urlaspect_ratio: 1:1|16:9|9:16|4:3|3:4; resolution: 1K|2K|4K; num_images: 1|2|430
nano-banana-2Nano Banana 2 · Googleprompt*, image_urlaspect_ratio: 1:1|16:9|9:16|4:3|3:4; resolution: 1K|2K|4K; num_images: 1|2|416
gpt-image-2GPT Image 2 · OpenAIprompt*, image_urlaspect_ratio: 1:1|16:9|9:16|4:3|3:4; quality: medium|high|low; num_images: 1|2|416
seedream-5-proSeedream 5.0 Pro · ByteDanceprompt*, image_urlaspect_ratio: 1:1|16:9|9:16|4:3|3:4; num_images: 1|2|414
seedream-5-liteSeedream 5.0 Lite · ByteDanceprompt*, image_urlaspect_ratio: 1:1|16:9|9:16|4:3|3:4; num_images: 1|2|48
flux-2-proFLUX.2 [pro] · Black Forest Labsprompt*, image_urlaspect_ratio: 1:1|16:9|9:16|4:3|3:49
flux-kontext-proFLUX.1 Kontext [pro] · Black Forest Labsprompt*, image_url*num_images: 1|2|48
ideogram-4Ideogram V4 · Ideogramprompt*aspect_ratio: 1:1|16:9|9:16|4:3|3:4; num_images: 1|2|46
recraft-4.1Recraft V4.1 · Recraftprompt*aspect_ratio: 1:1|16:9|9:16|4:3|3:48
qwen-image-3Qwen Image 3 · Alibabaprompt*, image_urlaspect_ratio: 1:1|16:9|9:16|4:3|3:4; num_images: 1|2|48

voice

Model idNameInputsParametersCredits
elevenlabs-v3Eleven v3 · ElevenLabsprompt*voice: Rachel|Aria|Sarah|Laura|Charlotte|Alice|Roger|George|Brian|Daniel|Liam|Will3
elevenlabs-multilingual-v2Multilingual v2 · ElevenLabsprompt*voice: Rachel|Aria|Sarah|Laura|Charlotte|Alice|Roger|George|Brian|Daniel|Liam|Will3
gemini-flash-ttsGemini 3.1 Flash TTS · Googleprompt*voice: Kore|Puck|Charon|Aoede|Fenrir|Leda|Orus|Zephyr2
minimax-speech-2.8-hdSpeech 2.8 HD · MiniMaxprompt*voice: Wise_Woman|Friendly_Person|Deep_Voice_Man|Calm_Woman|Casual_Guy|Lively_Girl|Inspirational_girl|Elegant_Man3
xai-ttsGrok Voice · xAIprompt*voice: eve|ara|leo|rex1

music

Model idNameInputsParametersCredits
lyria-3.5Lyria 3.5 · Google DeepMindprompt*—20
elevenlabs-musicEleven Music · ElevenLabsprompt*duration: 30|60|120; instrumental: bool120
minimax-music-2.6MiniMax Music 2.6 · MiniMaxprompt*instrumental: bool30
stable-audio-3Stable Audio 3 · Stability AIprompt*duration: 15|30|60|1208

sfx

Model idNameInputsParametersCredits
elevenlabs-sfxSound Effects v2 · ElevenLabsprompt*duration: 3|5|10|202
kling-video-to-audioAuto Soundtrack · Kuaishouprompt, video_url*—8
mmaudio-v2MMAudio (video → sound) · Open sourceprompt*, video_url*—2per 10s input

avatar

Model idNameInputsParametersCredits
omnihuman-1.5OmniHuman 1.5 · ByteDanceprompt, image_url*, audio_url*resolution: 720p|1080p320per 10s input
kling-avatar-2-proKling Avatar 2.0 Pro · Kuaishouprompt, image_url*, audio_url*—231per 10s input
heygen-avatar-4HeyGen Avatar IV · HeyGenprompt, image_url*, audio_url*aspect_ratio: 16:9|9:16|1:1; resolution: 720p|1080p200per 10s input
sync-lipsync-3Lipsync 3 · Sync Labsaudio_url*, video_url*—267per 10s input
sync-lipsync-2Lipsync 2 · Sync Labsaudio_url*, video_url*—100per 10s input

enhance

Model idNameInputsParametersCredits
video-upscaleVideo Upscale 4K · ByteDancevideo_url*resolution: 4k|2k|1080p116per 10s input
topaz-videoTopaz Video Upscale · Topaz Labsvideo_url*upscale_factor: 2|440per 10s input
image-upscaleImage Upscale · Topaz Labsimage_url*upscale_factor: 2|416
remove-bgRemove Background · Briaimage_url*—4
video-remove-bgVideo Background Removal · Briavideo_url*background_color: Transparent|Black|White|Green|Blue100per 10s input
kling-o1-editKling O1 Video Edit · Kuaishouprompt*, video_url*—337per 10s input
ray-2-modifyLuma Modify Video · Luma AIprompt*, video_url*—700per 10s input

* required input.