VeoNonStop API

Generate stunning AI videos and images programmatically. Submit tasks, poll for results, and download completed media — all through a simple REST API.

BASE URL https://veononstop.org/api/v1

🔑 Authentication

All API requests require an API key passed via the X-API-Key header.

curl -H "X-API-Key: veo_your_api_key_here" \
     https://veononstop.org/api/v1/account/info
📌 How to get your API key Contact the administrator to create an API key for your account. Keys are prefixed with veo_ and tied to your subscription plan.

🚀 Quick Start

Generate your first video in 3 steps:

1. Submit Task
2. Poll Status
3. Get Video URL

Complete Example (Python)

import requests, time

API_KEY = "veo_your_api_key_here"
BASE    = "https://veononstop.org/api/v1"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}

# 1. Submit a text-to-video task
resp = requests.post(f"{BASE}/video/text-to-video", json={
    "prompt": "A whale jumping out of the ocean at sunset",
    "aspect_ratio": "16:9"
}, headers=HEADERS)
task_id = resp.json()["data"]["task_id"]
print(f"Task created: {task_id}")

# 2. Poll until completed (typically 1-3 minutes)
while True:
    status = requests.get(f"{BASE}/video/status/{task_id}", headers=HEADERS).json()
    state  = status["data"]["status"]
    print(f"  Status: {state}")

    if state == "completed":
        videos = status["data"]["videos"]
        print(f"✅ Done! {len(videos)} video(s) ready")
        for v in videos:
            print(f"   Download: {v['fifeUrl']}")
        break
    elif state == "failed":
        print(f"❌ Failed: {status['data'].get('error')}")
        break

    time.sleep(10)  # Poll every 10 seconds

Complete Example (JavaScript / Node.js)

const API_KEY = "veo_your_api_key_here";
const BASE    = "https://veononstop.org/api/v1";
const headers = { "X-API-Key": API_KEY, "Content-Type": "application/json" };

// 1. Submit task
const res = await fetch(`${BASE}/video/text-to-video`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    prompt: "A whale jumping out of the ocean at sunset",
    aspect_ratio: "16:9"
  })
});
const { data } = await res.json();
console.log(`Task: ${data.task_id}`);

// 2. Poll until done
while (true) {
  await new Promise(r => setTimeout(r, 10000));
  const poll = await fetch(`${BASE}/video/status/${data.task_id}`, { headers });
  const status = (await poll.json()).data;
  console.log(`  Status: ${status.status}`);

  if (status.status === "completed") {
    console.log("✅ Videos:", status.videos.map(v => v.fifeUrl));
    break;
  }
  if (status.status === "failed") {
    console.error("❌ Error:", status.error);
    break;
  }
}

Complete Example (cURL)

# 1. Submit task
curl -X POST https://veononstop.org/api/v1/video/text-to-video \
  -H "X-API-Key: veo_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"A whale jumping out of the ocean","aspect_ratio":"16:9"}'

# Response: {"success":true,"data":{"task_id":"task_textto_abc123","status":"session_init"}}

# 2. Poll status (repeat until status = "completed")
curl https://veononstop.org/api/v1/video/status/task_textto_abc123 \
  -H "X-API-Key: veo_your_api_key_here"

# 3. Download the MP4 file
curl -o video.mp4 https://veononstop.org/api/v1/video/download/task_textto_abc123 \
  -H "X-API-Key: veo_your_api_key_here"

🔄 Task Lifecycle

Every generation request creates a task that goes through these states:

pending queued session_init generating polling completed
Status Description
pending Task created, awaiting processing
queued Concurrency limit reached — task is in the queue and will start automatically
session_init Acquiring credentials and creating project
uploading Uploading images (I2V, Multi-Image, Batch Frame only)
generating Submitting generation request to AI model
polling Generation in progress — video is being created by the AI
completed Video ready — download URLs available in videos array
failed Generation failed — check error field for details
💡 Polling Best Practice Poll every 10 seconds. Typical generation takes 1–3 minutes. Each poll triggers a live status check against the AI model, so you always get the freshest data.

⚡ Rate Limits & Plans

Basic Plan

4
concurrent task

Standard Plan

12
concurrent tasks

VIP Plan

24
concurrent tasks

Task Timeout

30
minutes max

🎬 Video Generation

POST /video/text-to-video Generate video from text prompt

Create a video from a text description. The AI generates a high-quality 8-second video clip.

Request Body

Parameter Type Description
prompt string Required Text description of the desired video
aspect_ratio string Optional "16:9" (landscape) or "9:16" (portrait). Default: "16:9"
count integer Optional Number of videos to generate (1–4). Default: 1
duration string Optional Video duration. Valid values: "4s", "6s". Omit for default 8-second video.

Response

{
  "success": true,
  "data": {
    "task_id": "task_textto_7b9bed6c80ee",
    "type": "text_to_video",
    "status": "session_init",
    "created_at": "2026-03-09T10:22:00.031Z"
  }
}
POST /video/image-to-video Generate video from image + prompt

Upload an image and generate a video that animates it based on your prompt.

Request Body

Parameter Type Description
prompt string Required Text description of how to animate the image
image_base64 string Required Base64-encoded image data (no data: prefix)
mime_type string Optional "image/jpeg", "image/png", "image/webp". Default: "image/jpeg"
aspect_ratio string Optional "16:9" (landscape) or "9:16" (portrait). Default: "9:16"
count integer Optional Number of videos (1–4). Default: 1
duration string Optional Video duration. Valid values: "4s", "6s". Omit for default 8-second video.
POST /video/multi-image-to-video Multiple reference images → video

Upload multiple reference images and generate a video that incorporates elements from all of them.

Request Body

Parameter Type Description
prompt string Required Text description of the desired video
images array Required Array of image objects (see below)
aspect_ratio string Optional "16:9" or "9:16". Default: "16:9"
count integer Optional Number of videos (1–4). Default: 1

Image Object

{
  "name": "Alex",              // Placeholder name (Latin characters only, matched against prompt words)
  "image_base64": "base64_encoded_image_data...",
  "mime_type": "image/jpeg"
}
🎯 Name-Based Matching Each image can have a name that acts as a placeholder. The API scans the prompt for words matching image names (case-insensitive) and uses only the matched images for generation.
Example: Image named "Alex" + prompt "Alex walking in the park" → only that image is used.
If no names match → all images are used as fallback.
⚠️ Latin Characters Only The name field only supports Latin characters (A-Z, a-z). Non-Latin characters (e.g. Chinese, Japanese, Korean, Cyrillic) are not supported and may cause matching failures.
POST /video/batch-frame Start + end image → video transition

Generate a video that transitions between a start image and an end image.

Request Body

Parameter Type Description
prompt string Required Description of the transition
start_image_base64 string Required Base64-encoded start frame image
end_image_base64 string Required Base64-encoded end frame image
aspect_ratio string Optional "16:9" or "9:16". Default: "16:9"
count integer Optional Number of videos (1–4). Default: 1
POST /video/upsample Upscale video to 1080p resolution

Upscale a completed video to 1080p resolution. Use the mediaGenerationId from a completed video result.

Parameter Type Description
media_generation_id string Required The mediaGenerationId from a completed video
aspect_ratio string Optional "16:9" or "9:16". Default: "16:9"
video_url string Optional Public HTTP/HTTPS URL of the original 720p MP4 file (e.g. the fifeUrl or servingBaseUri from the video result).

When provided, the platform routes the upscale job to the high-performance internal FFmpeg worker network instead of the default AI model, resulting in faster processing and reduced latency during peak hours.

Recommended: always pass this field when you have the URL available.
⚡ Performance tip Supplying video_url enables direct FFmpeg-based 1080p upscaling on dedicated VPS nodes. Jobs complete in ~4–8 seconds and the result is a stable publicly accessible MP4 link — no Google token required.

📊 Video Status & Results

GET /video/status/:taskId Poll video generation status

Check the current status of a video generation task. Each call triggers a live status check against the AI model.

Response (in progress)

{
  "success": true,
  "data": {
    "task_id": "task_textto_7b9bed6c80ee",
    "type": "text_to_video",
    "status": "polling",
    "created_at": "2026-03-09T10:22:00.031Z",
    "updated_at": "2026-03-09T10:23:45.939Z",
    "progress": { "total": 1, "completed": 0 }
  }
}

Response (completed)

{
  "success": true,
  "data": {
    "task_id": "task_textto_7b9bed6c80ee",
    "status": "completed",
    "completed_at": "2026-03-09T10:25:43.217Z",
    "videos": [
      {
        "sceneId": "f3753407-feb6-4dee-...",
        "fifeUrl": "https://storage.googleapis.com/ai-sandbox-videofx/video/...",
        "servingBaseUri": "https://storage.googleapis.com/...",
        "mediaGenerationId": "CAUSJDQ1OW...",
        "model": "veo_3_1_t2v_fast_ultra_relaxed",
        "seed": 788754185,
        "aspectRatio": "VIDEO_ASPECT_RATIO_LANDSCAPE",
        "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL"
      }
    ],
    "progress": { "total": 1, "completed": 1 }
  }
}
POST /video/cancel/:taskId Cancel a running task and release slot

Cancel a task that is in progress (pending, queued, session_init, uploading, generating, or polling). Immediately releases the cookie slot so new tasks can start.

Response (success)

{
  "success": true,
  "data": {
    "task_id": "task_textto_7b9bed6c80ee",
    "status": "failed",
    "error": "Cancelled by user"
  }
}

Response (already completed)

// HTTP 400
{
  "success": false,
  "error": "Cannot cancel task in 'completed' state"
}
💡 Use cancel to free stuck slots If you encounter All cookie slots full errors, cancel any running tasks you no longer need to immediately free up slots for new requests.
POST /video/cancel-all Cancel ALL running tasks and release all slots

Cancel every active task for your API key. Use this as an emergency reset when encountering All cookie slots full errors.

Response

{
  "success": true,
  "data": {
    "cancelled_count": 3,
    "tasks": [
      "task_textto_7b9bed6c80ee",
      "task_imaget_a1b2c3d4e5f6",
      "task_multii_f6e5d4c3b2a1"
    ]
  }
}
GET /video/result/:taskId Get completed video URLs only

Returns video URLs if the task is completed. Returns HTTP 202 if still processing.

GET /video/download/:taskId Download video as MP4 binary

Downloads the generated video as an MP4 file. Returns binary data with Content-Type: video/mp4.

Query Parameters

Parameter Type Description
video_index integer Optional If multiple videos were generated, select which one (0-indexed). Default: 0
curl -o output.mp4 \
  https://veononstop.org/api/v1/video/download/task_textto_abc123 \
  -H "X-API-Key: veo_your_key"

🖼️ Image Generation

⚡ Synchronous — No Polling Required All image endpoints return results immediately in the response body. No task ID, no polling. Images are ready in ~15–50 seconds.
POST /image/banana/generate Generate images with Banana model — synchronous

Generate 1–8 images using Google's Banana (GemPix) model. Supports two reference image modes: Name-Based Matching (default) and Use All Ref Images (new). Returns direct image URLs immediately.

Request Body

Parameter Type Description
prompt string Required Text description
num_images integer Optional Number of images (1–8). Default: 1
aspect_ratio string Optional "16:9" (landscape), "9:16" (portrait), "1:1" (square), "4:3" (landscape), or "3:4" (portrait). Default: "16:9"
model_key string Optional "NARWHAL" or "GEM_PIX_2". Default: "GEM_PIX_2"
project_id string Optional Reuse an existing project ID. If omitted, a new project is created automatically.
reference_images array Optional Array of {name, image_base64, mime_type} objects. The name field enables name-based matching (see below)
use_all_ref_images boolean Optional When true, bypasses name-based matching — all uploaded reference images (up to 9) are applied to every prompt regardless of which names appear in the text. Default: false

Response

{
  "success": true,
  "data": {
    "project_id": "d7d7a744-0fb6-4a1b-b4e2-b6852b017ab5",
    "matched_references": 1,  // How many ref images matched the prompt
    "media": [
      {
        "mediaGenerationId": "a37a9eca-3d78-4ad7-8acb-85e73243c675",  // UUID — use as media_id for upscale ✅
        "mediaGenerationIdRaw": "CAMSJDQyZjFmZWZh...",  // Internal protobuf (do not use for upscale)
        "fifeUrl": "https://storage.googleapis.com/ai-sandbox-videofx/image/a37a...",
        "mediaName": "a37a9eca-3d78-4ad7-8acb-85e73243c675",
        "width": 1376,
        "height": 768,
        "modelName": "GEM_PIX_2"
      }
    ]
  }
}
💡 Image URL & Upscale ID Each fifeUrl is a signed Google Cloud Storage URL valid for ~30 minutes. Download and store the image immediately.

Use mediaGenerationId (the UUID) as media_id when calling the upscale endpoint. Do not use mediaGenerationIdRaw — it is a protobuf-encoded string that is not accepted by the upscale API.

Reference Image Object

{
  "name": "Alex",              // Placeholder name (used for prompt matching)
  "image_base64": "base64_encoded_image_data...",
  "mime_type": "image/jpeg"
}

Reference Image Modes

🎯 Mode 1 (Default): Name-Based Matching Give each reference image a name matching a word in your prompt. The API scans each prompt and injects only the images whose names appear.

Example:
• Image 1: name: "Alex", Image 2: name: "Linda"
• Prompt: "Alex walking" → uses only Image 1
• Prompt: "Alex holding hands with Linda" → uses both images
• Prompt: "sunset over the ocean" → no match, uses no ref images
🖼️ Mode 2 (New): Use All Ref Images — use_all_ref_images: true Bypasses name matching entirely. Every prompt receives all uploaded reference images (up to 9) regardless of what text appears in the prompt. Useful when you want consistent style or characters applied universally across a batch.

Example:
• Upload 5 reference images
• Set "use_all_ref_images": true
• Every prompt → all 5 images applied as reference

Example: Name-Based Matching (Default)

curl -X POST https://veononstop.org/api/v1/image/banana/generate \
  -H "X-API-Key: veo_your_key" \
  -H "Content-Type: application/json" \
  -d '{
  "prompt": "Alex walking in the park",
  "reference_images": [
    {"name": "Alex", "image_base64": "...", "mime_type": "image/jpeg"},
    {"name": "Linda", "image_base64": "...", "mime_type": "image/jpeg"}
  ]
}'

Example: Use All Ref Images Mode

curl -X POST https://veononstop.org/api/v1/image/banana/generate \
  -H "X-API-Key: veo_your_key" \
  -H "Content-Type: application/json" \
  -d '{
  "prompt": "playing in the park",
  "use_all_ref_images": true,
  "reference_images": [
    {"name": "ref1", "image_base64": "...", "mime_type": "image/jpeg"},
    {"name": "ref2", "image_base64": "...", "mime_type": "image/jpeg"},
    {"name": "ref3", "image_base64": "...", "mime_type": "image/jpeg"},
    {"name": "ref4", "image_base64": "...", "mime_type": "image/jpeg"},
    {"name": "ref5", "image_base64": "...", "mime_type": "image/jpeg"}
  ]
}'
# → All 5 reference images are applied to the prompt (no name matching needed)

Example: Simple (No References)

curl -X POST https://veononstop.org/api/v1/image/banana/generate \
  -H "X-API-Key: veo_your_key" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A futuristic city at night", "aspect_ratio": "16:9", "num_images": 2}'
POST /image/banana/upscale Upscale image to 2K or 4K — synchronous

Upscale a previously generated Banana image to higher resolution (2K or 4K). Returns the upscaled image as a base64-encoded JPEG immediately. Default resolution is 2K.

Request Body

Parameter Type Description
media_id string Required mediaGenerationId from the banana/generate response
project_id string Required project_id from the banana/generate response
target_resolution string Optional Target upscale resolution. Accepted values:
UPSAMPLE_IMAGE_RESOLUTION_2K — 2K (default)
UPSAMPLE_IMAGE_RESOLUTION_4K — 4K

Response

{
  "success": true,
  "data": {
    "encodedImage": "/9j/4AAQSkZJRgAB...",  // Base64 JPEG of upscaled image
    "mimeType": "image/jpeg"
  }
}
📌 How to use the upscaled image Decode the base64 string to get the raw JPEG bytes:
const imgBytes = Buffer.from(data.encodedImage, 'base64');
fs.writeFileSync('upscaled.jpg', imgBytes);

End-to-End Example (Python)

import requests, base64

API_KEY = "veo_your_api_key"
BASE    = "https://veononstop.org/api/v1"
H       = {"X-API-Key": API_KEY, "Content-Type": "application/json"}

# Step 1: Generate image
gen = requests.post(f"{BASE}/image/banana/generate", json={
    "prompt": "A cat sitting on a rainbow cloud, photorealistic",
    "aspect_ratio": "16:9"
}, headers=H).json()

img      = gen["data"]["media"][0]
fife_url = img["fifeUrl"]         # Signed URL — valid ~30 min
media_id = img["mediaGenerationId"]
project  = gen["data"]["project_id"]
print(f"Generated: {fife_url}")

# Step 2: Upscale to 2K (default)
up = requests.post(f"{BASE}/image/banana/upscale", json={
    "media_id": media_id,
    "project_id": project
}, headers=H).json()
# ↑ Omit target_resolution → defaults to 2K

# Or upscale to 4K:
# up = requests.post(f"{BASE}/image/banana/upscale", json={
#     "media_id": media_id,
#     "project_id": project,
#     "target_resolution": "UPSAMPLE_IMAGE_RESOLUTION_4K"
# }, headers=H).json()

img_bytes = base64.b64decode(up["data"]["encodedImage"])
with open("upscaled.jpg", "wb") as f:
    f.write(img_bytes)
print("Upscaled image saved!")

👤 Account

GET /account/info Get API key info and plan details
{
  "success": true,
  "data": {
    "username": "john_doe",
    "plan": "standard",
    "concurrent_tasks": 12,
    "expires_at": "2026-12-31T23:59:59.000Z",
    "key_prefix": "veo_45604bf9"
  }
}
GET /account/usage Real-time task usage and concurrency status

Returns the number of active/queued/completed/failed tasks, cookie slots allocated, and a list of all tasks (including their current status). Useful for monitoring concurrency limits and debugging.

Response

{
  "success": true,
  "data": {
    "max_concurrent_tasks": 12,       // Plan limit (cookies × 4)
    "active_tasks": 3,               // Currently running
    "queued_tasks": 5,               // Waiting for a slot
    "completed_tasks": 10,            // Finished successfully
    "failed_tasks": 2,               // Failed or cancelled
    "cookies_allocated": 3,           // Google account sessions in use
    "tasks": [
      {
        "task_id": "task_textto_a1b2c3d4e5f6",
        "type": "text_to_video",
        "status": "polling",
        "created_at": "2026-03-26T14:00:00.000Z",
        "updated_at": "2026-03-26T14:02:30.000Z"
      },
      {
        "task_id": "task_upsamp_g7h8i9j0k1l2",
        "type": "upsample",
        "status": "completed",
        "created_at": "2026-03-26T13:50:00.000Z",
        "updated_at": "2026-03-26T13:55:12.000Z"
      }
    ]
  }
}
💡 Concurrency When active_tasks reaches max_concurrent_tasks, new tasks will be queued and auto-start when a slot frees up. Use this endpoint to monitor your usage before submitting more tasks.
📌 Task Retention Tasks are kept in memory for 2 hours after creation, then automatically cleaned up. Completed and failed tasks will appear in the list until they expire.

⚠️ Error Handling

All errors follow this format:

{
  "success": false,
  "error": "Description of what went wrong"
}
HTTP Code Meaning
400 Bad Request — missing or invalid parameters
401 Unauthorized — invalid, expired, or missing API key
404 Not Found — task ID does not exist or belongs to another user
429 Rate Limited — too many requests, slow down
500 Server Error — internal error, try again