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/v1Generations 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,/uploadsand/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
/api/v1/modelsno keycategorycurl "https://vidova.m7ts.tech/api/v1/models?category=video"{
"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
/api/v1/models/{id}no keycurl https://vidova.m7ts.tech/api/v1/models/veo-3.1Quote a price
/api/v1/models/{id}/priceno keyReturns exactly what a generation with the same input will charge.
inputinput_secondscurl -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}}'{
"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
/api/v1/generationsCharges 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.
modelinput.promptinput.negative_promptinput.image_urlinput.end_image_urlinput.audio_url / video_urlinput.<param>input.camerawebhook_urlcurl -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"
}'{
"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
/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.
curl https://vidova.m7ts.tech/api/v1/generations/V1StGXR8_Z5jdHi6B-myT \
-H "Authorization: Bearer $VIDOVA_API_KEY"List generations
/api/v1/generationsNewest first, cursor-paginated. Pass next_cursor back as cursor until has_more is false.
limitcursorstatuscategory / modelsourcecurl https://vidova.m7ts.tech/api/v1/generations?limit=20&status=succeeded \
-H "Authorization: Bearer $VIDOVA_API_KEY"{
"object": "list",
"data": [ { "id": "…", "object": "generation", … } ],
"has_more": true,
"next_cursor": "WyIyMDI2LTA5LTI0IDEyOjAwOjAwLjAwMCIsIlYxU3QiXQ"
}Delete a generation
/api/v1/generations/{id}Permanently removes a settled generation from your library. Running generations return 409 conflict.
curl -X DELETE https://vidova.m7ts.tech/api/v1/generations/V1StGXR8_Z5jdHi6B-myT \
-H "Authorization: Bearer $VIDOVA_API_KEY"{ "id": "V1StGXR8_Z5jdHi6B-myT", "object": "generation", "deleted": true }Uploads
Upload media
/api/v1/uploadsSend 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.
curl -X POST https://vidova.m7ts.tech/api/v1/uploads \
-H "Authorization: Bearer $VIDOVA_API_KEY" \
-F "file=@./product.jpg"{
"upload": {
"object": "upload",
"url": "https://…/product.jpg",
"content_type": "image/jpeg",
"size": 482113
}
}Account
Retrieve your account
/api/v1/accountCredit balance, plan and the limits that apply to the calling key.
curl https://vidova.m7ts.tech/api/v1/account \
-H "Authorization: Bearer $VIDOVA_API_KEY"{
"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
/api/v1/autopilotideaformatlengthlanguagetierstyle / voice / music / captionscurl -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
/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.
curl https://vidova.m7ts.tech/api/v1/autopilot/run_id \
-H "Authorization: Bearer $VIDOVA_API_KEY"{
"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.
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.
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 id | Name | Inputs | Parameters | Credits |
|---|---|---|---|---|
veo-3.1 | Veo 3.1 · Google DeepMind | prompt*, image_url | aspect_ratio: 16:9|9:16; duration: 4|6|8; resolution: 720p|1080p|4k; generate_audio: bool | 640 |
veo-3.1-fast | Veo 3.1 Fast · Google DeepMind | prompt*, image_url | aspect_ratio: 16:9|9:16; duration: 4|6|8; resolution: 720p|1080p|4k; generate_audio: bool | 240 |
veo-3.1-lite | Veo 3.1 Lite · Google DeepMind | prompt*, image_url | aspect_ratio: 16:9|9:16; duration: 4|6|8; resolution: 720p|1080p; generate_audio: bool | 80 |
kling-3-pro | Kling 3.0 Pro · Kuaishou | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1; duration: 5|10|15; generate_audio: bool | 169 |
kling-3-turbo | Kling 3.0 Turbo · Kuaishou | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1; duration: 5|10|15 | 140 |
seedance-2.5 | Seedance 2.5 · ByteDance | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4|21:9; duration: 5|10|15; resolution: 720p|1080p|480p; generate_audio: bool | 470 |
seedance-2-fast | Seedance 2.0 Fast · ByteDance | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 5|10|15; resolution: 720p|480p; generate_audio: bool | 250 |
minimax-h3-max | MiniMax H3 Max · MiniMax | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4|21:9; duration: 5|10|15; resolution: 768P|1080P|480P | 80 |
wan-3 | Wan 3.0 · Alibaba | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 5|10|20; resolution: 720p|1080p|480p; generate_audio: bool | 100 |
gemini-omni-flash | Gemini Omni Flash · Google | prompt*, image_url | aspect_ratio: 16:9|9:16; duration: 4|8|10; resolution: 720p|1080p|4k | 160 |
flux-3-video | FLUX 3 Video · Black Forest Labs | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4|21:9; duration: 5|10|15; resolution: 720p|1080p; generate_audio: bool | 171 |
ray-3.2 | Ray 3.2 · Luma AI | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4|21:9; duration: 5|10; resolution: 720p|1080p|540p | 200 |
pixverse-6 | PixVerse V6 · PixVerse | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 5|8|10; resolution: 720p|1080p|540p; generate_audio: bool | 45 |
grok-video-1.5 | Grok Imagine Video · xAI | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 6|10|15; resolution: 720p|1080p|480p | 169 |
ltx-2.5-pro | LTX 2.5 Pro · Lightricks | prompt*, image_url | aspect_ratio: 16:9|9:16; duration: 6|8|10; resolution: 1080p|720p; generate_audio: bool | 204 |
vidu-q3 | Vidu Q3 · Shengshu | prompt*, image_url | aspect_ratio: 16:9|9:16|1:1|4:3|3:4; duration: 4|8|16; resolution: 720p|1080p|540p; generate_audio: bool | 247 |
image
| Model id | Name | Inputs | Parameters | Credits |
|---|---|---|---|---|
nano-banana-pro | Nano Banana Pro · Google | prompt*, image_url | aspect_ratio: 1:1|16:9|9:16|4:3|3:4; resolution: 1K|2K|4K; num_images: 1|2|4 | 30 |
nano-banana-2 | Nano Banana 2 · Google | prompt*, image_url | aspect_ratio: 1:1|16:9|9:16|4:3|3:4; resolution: 1K|2K|4K; num_images: 1|2|4 | 16 |
gpt-image-2 | GPT Image 2 · OpenAI | prompt*, image_url | aspect_ratio: 1:1|16:9|9:16|4:3|3:4; quality: medium|high|low; num_images: 1|2|4 | 16 |
seedream-5-pro | Seedream 5.0 Pro · ByteDance | prompt*, image_url | aspect_ratio: 1:1|16:9|9:16|4:3|3:4; num_images: 1|2|4 | 14 |
seedream-5-lite | Seedream 5.0 Lite · ByteDance | prompt*, image_url | aspect_ratio: 1:1|16:9|9:16|4:3|3:4; num_images: 1|2|4 | 8 |
flux-2-pro | FLUX.2 [pro] · Black Forest Labs | prompt*, image_url | aspect_ratio: 1:1|16:9|9:16|4:3|3:4 | 9 |
flux-kontext-pro | FLUX.1 Kontext [pro] · Black Forest Labs | prompt*, image_url* | num_images: 1|2|4 | 8 |
ideogram-4 | Ideogram V4 · Ideogram | prompt* | aspect_ratio: 1:1|16:9|9:16|4:3|3:4; num_images: 1|2|4 | 6 |
recraft-4.1 | Recraft V4.1 · Recraft | prompt* | aspect_ratio: 1:1|16:9|9:16|4:3|3:4 | 8 |
qwen-image-3 | Qwen Image 3 · Alibaba | prompt*, image_url | aspect_ratio: 1:1|16:9|9:16|4:3|3:4; num_images: 1|2|4 | 8 |
voice
| Model id | Name | Inputs | Parameters | Credits |
|---|---|---|---|---|
elevenlabs-v3 | Eleven v3 · ElevenLabs | prompt* | voice: Rachel|Aria|Sarah|Laura|Charlotte|Alice|Roger|George|Brian|Daniel|Liam|Will | 3 |
elevenlabs-multilingual-v2 | Multilingual v2 · ElevenLabs | prompt* | voice: Rachel|Aria|Sarah|Laura|Charlotte|Alice|Roger|George|Brian|Daniel|Liam|Will | 3 |
gemini-flash-tts | Gemini 3.1 Flash TTS · Google | prompt* | voice: Kore|Puck|Charon|Aoede|Fenrir|Leda|Orus|Zephyr | 2 |
minimax-speech-2.8-hd | Speech 2.8 HD · MiniMax | prompt* | voice: Wise_Woman|Friendly_Person|Deep_Voice_Man|Calm_Woman|Casual_Guy|Lively_Girl|Inspirational_girl|Elegant_Man | 3 |
xai-tts | Grok Voice · xAI | prompt* | voice: eve|ara|leo|rex | 1 |
music
| Model id | Name | Inputs | Parameters | Credits |
|---|---|---|---|---|
lyria-3.5 | Lyria 3.5 · Google DeepMind | prompt* | — | 20 |
elevenlabs-music | Eleven Music · ElevenLabs | prompt* | duration: 30|60|120; instrumental: bool | 120 |
minimax-music-2.6 | MiniMax Music 2.6 · MiniMax | prompt* | instrumental: bool | 30 |
stable-audio-3 | Stable Audio 3 · Stability AI | prompt* | duration: 15|30|60|120 | 8 |
sfx
| Model id | Name | Inputs | Parameters | Credits |
|---|---|---|---|---|
elevenlabs-sfx | Sound Effects v2 · ElevenLabs | prompt* | duration: 3|5|10|20 | 2 |
kling-video-to-audio | Auto Soundtrack · Kuaishou | prompt, video_url* | — | 8 |
mmaudio-v2 | MMAudio (video → sound) · Open source | prompt*, video_url* | — | 2per 10s input |
avatar
| Model id | Name | Inputs | Parameters | Credits |
|---|---|---|---|---|
omnihuman-1.5 | OmniHuman 1.5 · ByteDance | prompt, image_url*, audio_url* | resolution: 720p|1080p | 320per 10s input |
kling-avatar-2-pro | Kling Avatar 2.0 Pro · Kuaishou | prompt, image_url*, audio_url* | — | 231per 10s input |
heygen-avatar-4 | HeyGen Avatar IV · HeyGen | prompt, image_url*, audio_url* | aspect_ratio: 16:9|9:16|1:1; resolution: 720p|1080p | 200per 10s input |
sync-lipsync-3 | Lipsync 3 · Sync Labs | audio_url*, video_url* | — | 267per 10s input |
sync-lipsync-2 | Lipsync 2 · Sync Labs | audio_url*, video_url* | — | 100per 10s input |
enhance
| Model id | Name | Inputs | Parameters | Credits |
|---|---|---|---|---|
video-upscale | Video Upscale 4K · ByteDance | video_url* | resolution: 4k|2k|1080p | 116per 10s input |
topaz-video | Topaz Video Upscale · Topaz Labs | video_url* | upscale_factor: 2|4 | 40per 10s input |
image-upscale | Image Upscale · Topaz Labs | image_url* | upscale_factor: 2|4 | 16 |
remove-bg | Remove Background · Bria | image_url* | — | 4 |
video-remove-bg | Video Background Removal · Bria | video_url* | background_color: Transparent|Black|White|Green|Blue | 100per 10s input |
kling-o1-edit | Kling O1 Video Edit · Kuaishou | prompt*, video_url* | — | 337per 10s input |
ray-2-modify | Luma Modify Video · Luma AI | prompt*, video_url* | — | 700per 10s input |
* required input.