Vidancee API
Create Veo 3.1 videos and Nano Banana images from your own code, automations and apps — with the same credits, prices and queue as the Studio. You only pay for jobs that finish.
Base URL
https://vidancee.com/api/v1.phpModels on the API
| Model | ID | Best for |
|---|---|---|
| Omni Flash | Omni-Flash | Google Omni Flash — fast all-rounder with sound, 4–10s |
| Veo 3.1 Lite | Veo-3.1-Lite | Lower-priority queue — costs far less, can take a little longer at busy times |
| Veo 3.1 Fast | Veo-3.1-Fast | Google Veo 3.1 Fast — sharper motion, priority render |
| Nano Banana Pro | nano-banana-pro | Images: best detail and text, edits from your photos |
| Nano Banana 2 | nano-banana-2 | Images: fast everyday images and edits |
Prices, lengths and aspect ratios can change. Read them from models rather than hard-coding them.
Quickstart
Make your first video in three steps.
- Get a keyOpen Account and click Create my connector link. Copy the API key — it starts with
vdk_and is shown only once. - Queue a videoSend a
generaterequest. You get the job IDs back immediately. - Collect the resultPoll
jobsuntil the status iscompleted, then downloadurl.
curl -X POST "https://vidancee.com/api/v1.php?action=generate" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "Veo-3.1-Lite",
"prompt": "A red fox runs through fresh snow at sunrise, low tracking shot",
"duration": 8,
"aspect_ratio": "16:9"
}'
# → {"ok": true, "job_ids": [1201], ...}
curl "https://vidancee.com/api/v1.php?action=jobs&ids=1201&wait=30" \
-H "Authorization: Bearer vdk_your_key"import requests
API_URL = "https://vidancee.com/api/v1.php"
HEADERS = {"Authorization": "Bearer vdk_your_key"}
response = requests.post(
API_URL,
params={"action": "generate"},
headers=HEADERS,
json={
"model": "Veo-3.1-Lite",
"prompt": "A red fox runs through fresh snow at sunrise, low tracking shot",
"duration": 8,
"aspect_ratio": "16:9",
},
)
print(response.json()) # {"ok": True, "job_ids": [1201], ...}const response = await fetch("https://vidancee.com/api/v1.php?action=generate", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "Veo-3.1-Lite",
prompt: "A red fox runs through fresh snow at sunrise, low tracking shot",
duration: 8,
aspect_ratio: "16:9",
}),
});
console.log(await response.json()); // { ok: true, job_ids: [1201], ... }Authentication
Send your API key in the Authorization header of every request. POST requests also need Content-Type: application/json.
Authorization: Bearer vdk_your_key
Content-Type: application/jsonResponses & errors
Every response is JSON with an ok field. When ok is false, error holds a plain-English message you can show to your users as-is.
| Status | Meaning |
|---|---|
| 200 | Success. |
| 400 | Invalid request — model, length, ratio, prompt or images. The error names the field. |
| 401 | Missing, wrong or revoked key. |
| 403 | Not included in your plan. |
| 404 · 405 | Unknown action, or the wrong method. |
| 429 | Rate limit, daily limit or too many jobs running. The error says when to retry. |
| 500 | Something went wrong on our side. Retry shortly. |
{
"ok": false,
"error": "Not enough credits for this clip. Top up to continue."
}How a job works
- Credits are held, not taken, when a job is queued. They are charged only when it completes. Failed jobs cost nothing and include a
reason. - Poll with
wait=30. Thejobsendpoint holds the request open (up to 40 seconds) until something changes, so one request every 30–40 seconds is enough. - Typical times: images under a minute, videos 1–5 minutes. Veo 3.1 Lite runs in a lower-priority queue and can take longer at busy times.
- Download promptly. Results are kept for 24 hours, uploaded references for 3 days.
?action=modelsList models
Every model your key can use, with the credit price for each length, supported aspect ratios, how many reference images it accepts, which modes it supports and whether it is paused.
Prices are your prices — Veo 3.1 Lite costs less on Ultra and is free on Ultra Max.
curl "https://vidancee.com/api/v1.php?action=models" \
-H "Authorization: Bearer vdk_your_key"import requests
response = requests.get(
"https://vidancee.com/api/v1.php",
params={"action": "models"},
headers={"Authorization": "Bearer vdk_your_key"},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=models", {
headers: { Authorization: "Bearer vdk_your_key" },
});
console.log(await response.json());{
"ok": true,
"models": [
{
"model": "Veo-3.1-Lite",
"name": "Veo 3.1 Lite",
"type": "video",
"prices": [
{ "duration": 4, "label": "4s", "credits": 4 },
{ "duration": 8, "label": "8s", "credits": 4 }
],
"aspect_ratios": ["16:9", "9:16"],
"max_reference_images": 3,
"supports_frames": true,
"supports_cc": true,
"paused": null
}
]
}?action=accountAccount
Your balance, credits held by running jobs, plan, how many videos and images render at once, your batch limit and any modes your plan doesn't include.
curl "https://vidancee.com/api/v1.php?action=account" \
-H "Authorization: Bearer vdk_your_key"import requests
response = requests.get(
"https://vidancee.com/api/v1.php",
params={"action": "account"},
headers={"Authorization": "Bearer vdk_your_key"},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=account", {
headers: { Authorization: "Bearer vdk_your_key" },
});
console.log(await response.json());{
"ok": true,
"credits": 13500,
"held_by_running_jobs": 8,
"plan": "Pro",
"clips_at_once": 2,
"images_at_once": 6,
"batch_limit_prompts": 9,
"locked_modes": [],
"plan_expires_utc": "2026-12-01 10:00:00"
}?action=generateGenerate
Queues one job per prompt (times quantity) and returns their IDs straight away.
| Field | Description |
|---|---|
modelrequiredstring | A model ID from models. |
promptstring | One prompt, 10–50,000 characters. Or use prompts. |
promptsstring[] | A batch — each prompt becomes its own job, up to your plan's batch limit. |
kindstring | video (default) or image. |
modestring | Video only: text-to-video, image-to-video (one start frame), frame-to-frame (start and end frame) or cc (1–3 character references). Chosen from your images when omitted. |
durationinteger | Clip length in seconds — one of the model's lengths. |
aspect_ratiostring | For example 16:9 or 9:16. |
reference_imagesstring[] | Each item is a data: URL, raw base64, an https:// link, or job:<id> of one of your finished images. Order matters: the first is the start frame. Max 4 MB each. |
quantityinteger | 1–4 takes of each prompt. Default 1. |
curl -X POST "https://vidancee.com/api/v1.php?action=generate" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "Veo-3.1-Lite",
"prompts": [
"A barista pours latte art, macro shot",
"Steam rises from the cup, slow push-in"
],
"duration": 8,
"aspect_ratio": "9:16",
"quantity": 1
}'import requests
response = requests.post(
"https://vidancee.com/api/v1.php",
params={"action": "generate"},
headers={"Authorization": "Bearer vdk_your_key"},
json={
"model": "Veo-3.1-Lite",
"prompts": [
"A barista pours latte art, macro shot",
"Steam rises from the cup, slow push-in"
],
"duration": 8,
"aspect_ratio": "9:16",
"quantity": 1
},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=generate", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
"model": "Veo-3.1-Lite",
"prompts": [
"A barista pours latte art, macro shot",
"Steam rises from the cup, slow push-in"
],
"duration": 8,
"aspect_ratio": "9:16",
"quantity": 1
}),
});
console.log(await response.json());{
"ok": true,
"job_ids": [1201, 1202],
"status": "queued",
"model": "Veo 3.1 Lite",
"credits_per_item": 4,
"credits_if_all_succeed": 8
}?action=jobsGet jobs
Status and results of up to 50 jobs.
| Parameter | Description |
|---|---|
idsrequiredstring | Comma-separated job IDs, e.g. 1201,1202. |
waitinteger | 0–40 seconds to wait for a change before answering. |
Completed jobs carry url (plus thumbnail_url for videos) and credits_charged. Failed jobs carry reason.
curl "https://vidancee.com/api/v1.php?action=jobs&ids=1201%2C1202&wait=30" \
-H "Authorization: Bearer vdk_your_key"import requests
response = requests.get(
"https://vidancee.com/api/v1.php",
params={"action": "jobs", "ids": "1201,1202", "wait": 30},
headers={"Authorization": "Bearer vdk_your_key"},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=jobs&ids=1201%2C1202&wait=30", {
headers: { Authorization: "Bearer vdk_your_key" },
});
console.log(await response.json());{
"ok": true,
"jobs": [
{
"job_id": 1201,
"status": "completed",
"type": "video",
"mode": "text-to-video",
"length": "8s",
"aspect_ratio": "9:16",
"url": "https://vidancee.com/renders/v1201_….mp4",
"thumbnail_url": "https://vidancee.com/renders/v1201_….jpg",
"credits_charged": 4
},
{
"job_id": 1202,
"status": "failed",
"reason": "The prompt was blocked by the safety filter.",
"credits_charged": 0
}
]
}?action=extendExtend a clip
Continues one of your finished Veo 3.1 clips with a new shot of about 7 seconds — same scene, the motion carries on. Extend the new clip again to build a longer video.
Costs the same as one clip of that model.
curl -X POST "https://vidancee.com/api/v1.php?action=extend" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"job_id": 1201,
"prompt": "The camera follows the fox as it leaps over a frozen stream"
}'import requests
response = requests.post(
"https://vidancee.com/api/v1.php",
params={"action": "extend"},
headers={"Authorization": "Bearer vdk_your_key"},
json={
"job_id": 1201,
"prompt": "The camera follows the fox as it leaps over a frozen stream"
},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=extend", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
"job_id": 1201,
"prompt": "The camera follows the fox as it leaps over a frozen stream"
}),
});
console.log(await response.json());{
"ok": true,
"job_ids": [1205],
"status": "queued",
"extends_job": 1201,
"length": "~7s",
"credits_if_successful": 4
}?action=upscaleUpscale an image or video
Creates a bigger version of a finished job. Nano Banana image: resolution is 2k (2 credits) or 4k (4 credits). Veo 3.1 / Omni Flash video: 1080p (10 credits, free on Ultra Max) or 4k (200 credits). The upscale is a new job — poll it like any other. Charged only on success.
curl -X POST "https://vidancee.com/api/v1.php?action=upscale" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"job_id": 1188,
"resolution": "4k"
}'import requests
response = requests.post(
"https://vidancee.com/api/v1.php",
params={"action": "upscale"},
headers={"Authorization": "Bearer vdk_your_key"},
json={
"job_id": 1188,
"resolution": "4k"
},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=upscale", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
"job_id": 1188,
"resolution": "4k"
}),
});
console.log(await response.json());{
"ok": true,
"job_ids": [1206],
"status": "queued",
"upscales_job": 1188,
"resolution": "4k",
"credits_if_successful": 4
}?action=listList jobs
Your recent jobs, newest first.
| Parameter | Description |
|---|---|
limitinteger | 1–50. Default 20. |
statusstring | any, queued, processing, completed or failed. |
typestring | any, video or image. |
searchstring | Words that appear in the prompt. |
curl "https://vidancee.com/api/v1.php?action=list&limit=20&status=completed&type=video" \
-H "Authorization: Bearer vdk_your_key"import requests
response = requests.get(
"https://vidancee.com/api/v1.php",
params={"action": "list", "limit": 20, "status": "completed", "type": "video"},
headers={"Authorization": "Bearer vdk_your_key"},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=list&limit=20&status=completed&type=video", {
headers: { Authorization: "Bearer vdk_your_key" },
});
console.log(await response.json());{
"ok": true,
"jobs": [
{ "job_id": 1206, "status": "completed", "type": "image", "url": "https://vidancee.com/renders/…png" },
{ "job_id": 1205, "status": "processing", "type": "video" }
]
}Regenerate · cancel · delete
| Action | Body | What it does |
|---|---|---|
POST regenerate | job_id, prompt | A new job with the same settings and references — optionally with a new prompt. |
POST cancel | job_ids | Cancels jobs still in the queue. Nothing is charged. |
POST delete | job_ids | Removes finished jobs from your library permanently. |
curl -X POST "https://vidancee.com/api/v1.php?action=cancel" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"job_ids": [1203, 1204]
}'import requests
response = requests.post(
"https://vidancee.com/api/v1.php",
params={"action": "cancel"},
headers={"Authorization": "Bearer vdk_your_key"},
json={
"job_ids": [1203, 1204]
},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=cancel", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
"job_ids": [1203, 1204]
}),
});
console.log(await response.json());{
"ok": true,
"cancelled": 2,
"not_cancelled": 0,
"note": "Nothing was charged for cancelled jobs."
}Regenerate
curl -X POST "https://vidancee.com/api/v1.php?action=regenerate" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"job_id": 1202,
"prompt": "A calm lake at dawn, mist over the water, slow pan"
}'import requests
response = requests.post(
"https://vidancee.com/api/v1.php",
params={"action": "regenerate"},
headers={"Authorization": "Bearer vdk_your_key"},
json={
"job_id": 1202,
"prompt": "A calm lake at dawn, mist over the water, slow pan"
},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=regenerate", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
"job_id": 1202,
"prompt": "A calm lake at dawn, mist over the water, slow pan"
}),
});
console.log(await response.json());Recipes
Animate an image you made
Generate an image first, then pass job:<id> as the start frame.
curl -X POST "https://vidancee.com/api/v1.php?action=generate" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "Veo-3.1-Lite",
"mode": "image-to-video",
"reference_images": ["job:1188"],
"prompt": "The sneaker spins slowly while a soft light sweeps across it",
"duration": 8
}'import requests
response = requests.post(
"https://vidancee.com/api/v1.php",
params={"action": "generate"},
headers={"Authorization": "Bearer vdk_your_key"},
json={
"model": "Veo-3.1-Lite",
"mode": "image-to-video",
"reference_images": ["job:1188"],
"prompt": "The sneaker spins slowly while a soft light sweeps across it",
"duration": 8
},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=generate", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
"model": "Veo-3.1-Lite",
"mode": "image-to-video",
"reference_images": ["job:1188"],
"prompt": "The sneaker spins slowly while a soft light sweeps across it",
"duration": 8
}),
});
console.log(await response.json());Start and end frame
Two images — the clip moves from the first to the second.
curl -X POST "https://vidancee.com/api/v1.php?action=generate" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "Veo-3.1-Lite",
"mode": "frame-to-frame",
"reference_images": ["job:1190", "job:1191"],
"prompt": "Day turns to night as the city lights switch on",
"duration": 8
}'import requests
response = requests.post(
"https://vidancee.com/api/v1.php",
params={"action": "generate"},
headers={"Authorization": "Bearer vdk_your_key"},
json={
"model": "Veo-3.1-Lite",
"mode": "frame-to-frame",
"reference_images": ["job:1190", "job:1191"],
"prompt": "Day turns to night as the city lights switch on",
"duration": 8
},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=generate", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
"model": "Veo-3.1-Lite",
"mode": "frame-to-frame",
"reference_images": ["job:1190", "job:1191"],
"prompt": "Day turns to night as the city lights switch on",
"duration": 8
}),
});
console.log(await response.json());Keep a character consistent
Give 1–3 reference images of the character; they are placed into a new scene.
curl -X POST "https://vidancee.com/api/v1.php?action=generate" \
-H "Authorization: Bearer vdk_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "Veo-3.1-Lite",
"mode": "cc",
"reference_images": ["data:image/png;base64,iVBORw0KGgo…"],
"prompt": "The same woman walks through a rainy Tokyo street at night",
"duration": 8
}'import requests
response = requests.post(
"https://vidancee.com/api/v1.php",
params={"action": "generate"},
headers={"Authorization": "Bearer vdk_your_key"},
json={
"model": "Veo-3.1-Lite",
"mode": "cc",
"reference_images": ["data:image/png;base64,iVBORw0KGgo…"],
"prompt": "The same woman walks through a rainy Tokyo street at night",
"duration": 8
},
)
print(response.json())const response = await fetch("https://vidancee.com/api/v1.php?action=generate", {
method: "POST",
headers: {
Authorization: "Bearer vdk_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
"model": "Veo-3.1-Lite",
"mode": "cc",
"reference_images": ["data:image/png;base64,iVBORw0KGgo…"],
"prompt": "The same woman walks through a rainy Tokyo street at night",
"duration": 8
}),
});
console.log(await response.json());A longer video
Generate the first clip, then call extend on each new clip with what happens next.
Photo edit
Send "kind": "image" with reference_images and describe the change.
Full example
A complete script: queue a batch, wait for it and download every finished file.
import requests
API_URL = "https://vidancee.com/api/v1.php"
HEADERS = {"Authorization": "Bearer vdk_your_key"}
def call(action, body=None, **params):
"""Run one API action: POST when there is a body, GET otherwise."""
params["action"] = action
if body is None:
r = requests.get(API_URL, params=params, headers=HEADERS, timeout=60)
else:
r = requests.post(API_URL, params=params, json=body, headers=HEADERS, timeout=60)
data = r.json()
if not data.get("ok"):
raise RuntimeError(data.get("error"))
return data
def wait_for(job_ids):
"""Poll until every job is completed or failed."""
ids = ",".join(str(i) for i in job_ids)
while True:
jobs = call("jobs", ids=ids, wait=30)["jobs"]
if all(job["status"] in ("completed", "failed") for job in jobs):
return jobs
def download(url, path):
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(1 << 20):
f.write(chunk)
job_ids = call("generate", {
"model": "Veo-3.1-Lite",
"duration": 8,
"aspect_ratio": "9:16",
"prompts": [
"A barista pours latte art, macro shot",
"Steam rises from the cup, slow push-in",
],
})["job_ids"]
for job in wait_for(job_ids):
if job["status"] == "completed":
download(job["url"], f"clip_{job['job_id']}.mp4")
print("saved", job["job_id"])
else:
print("failed", job["job_id"], job["reason"])const API_URL = "https://vidancee.com/api/v1.php";
const HEADERS = {
Authorization: `Bearer ${process.env.VIDANCEE_vdk_your_key}`,
"Content-Type": "application/json",
};
async function call(action, body, params = {}) {
const qs = new URLSearchParams({ action, ...params });
const res = await fetch(`${API_URL}?${qs}`, body
? { method: "POST", headers: HEADERS, body: JSON.stringify(body) }
: { headers: HEADERS });
const data = await res.json();
if (!data.ok) throw new Error(data.error);
return data;
}
async function waitFor(jobIds) {
for (;;) {
const { jobs } = await call("jobs", null, { ids: jobIds.join(","), wait: 30 });
if (jobs.every((j) => ["completed", "failed"].includes(j.status))) return jobs;
}
}
// 1. Make an image
const { job_ids: [imageId] } = await call("generate", {
kind: "image",
model: "nano-banana-pro",
prompt: "Studio photo of a red sneaker on a white background",
aspect_ratio: "16:9",
});
await waitFor([imageId]);
// 2. Animate it
const { job_ids: [videoId] } = await call("generate", {
model: "Veo-3.1-Lite",
mode: "image-to-video",
reference_images: [`job:${imageId}`],
prompt: "The sneaker spins slowly while a soft light sweeps across it",
duration: 8,
aspect_ratio: "16:9",
});
const [video] = await waitFor([videoId]);
console.log(video.url);Claude Ultra · Ultra Max
Ask Claude for a video in plain words — it picks the model, makes the clip and gives you the link, using your credits. The connector, like the REST API, is part of the Ultra and Ultra Max plans; on other plans it can only show your balance.
- Add the connectorIn Claude (web, desktop or mobile) open Settings → Connectors → Add custom connector.
- Paste your linkName it Vidancee and paste your connector link (
https://vidancee.com/mcp.php/vdk_…) as the URL. - AskTurn Vidancee on in a chat and try "Make a 9:16 video of a fox in the snow" or "Show my balance".
Claude Code
claude mcp add --transport http vidancee https://vidancee.com/mcp.php/vdk_your_keyn8n Ultra · Ultra Max
Four nodes: Generate → Wait → Check → IF, looping back to Wait until the job is done.
- CredentialCreate a Header Auth credential with name
Authorizationand valueBearer vdk_your_key. - HTTP Request — GenerateMethod POST, URL
https://vidancee.com/api/v1.php?action=generate, authentication = the credential above, body = JSON:Body{ "model": "Veo-3.1-Lite", "prompt": "{{ $json.prompt }}", "duration": 8, "aspect_ratio": "9:16" } - Wait20 seconds.
- HTTP Request — CheckMethod GET, same credential, URL:
URL
https://vidancee.com/api/v1.php?action=jobs&ids={{ $('Generate').item.json.job_ids.join(',') }}&wait=30 - IF — done?Condition:
True → useExpression
{{ $json.jobs.every(j => ['completed', 'failed'].includes(j.status)) }}{{ $json.jobs[0].url }}(upload to Drive, post to YouTube…). False → back to Wait.
prompts array — each becomes its own job and they render in parallel.Desktop app Ultra · Ultra Max
The Windows app runs large batches from your PC and saves every file to a folder as it finishes.
- InstallDownload and open the app.
- Add your keyPaste your API key in Settings → API key. It is stored encrypted on your PC.
- Run a batchPick a model and mode, paste one prompt per line and press Start.
Make · Zapier · others
Make.com
HTTP → Make a request with the URL, header and JSON body above. Add Sleep and a Repeater to poll jobs.
Zapier
Webhooks by Zapier → Custom Request to queue, then Delay and a second request to jobs.
Google Sheets
Apps Script UrlFetchApp.fetch with the Authorization header; write the url back to the sheet when done.
Plans & limits
| Lite | Pro | Ultra | Ultra Max | |
|---|---|---|---|---|
| REST API · desktop app · n8n | — | — | ✓ | ✓ |
| Claude connector | — | — | ✓ | ✓ |
| Videos rendering at once | 2 | 4 | 8 | 8 |
| …of which Veo 3.1 Lite LP | 1 | 2 | 4 | 4 |
| Images rendering at once | 4 | 6 | 10 | 10 |
| Queue (waiting + rendering) | 100 | 190 | 320 | 500 |
| Prompts per request | 6 | 9 | 12 | 24 |
| Frames · characters · extend · photo edit · upscale | — | ✓ | ✓ | ✓ |
| Veo 3.1 Lite per day | 42 | No limit | No limit | Unlimited (fair use 500) |
| Nano Banana images per plan (free) | 2,000 | 6,000 | 10,000 | 15,000 |
| Nano Banana images per day (free) | 150 | 350 | 500 | 850 |
| Requests per minute | 120 | 120 | 120 | 120 |
Jobs beyond your "at once" number wait in the queue and start automatically. Nano Banana images and their 2K / 4K upscales use no credits — an upscale counts 2 or 4 of the day's images. Daily limits reset at midnight.
FAQ
Am I charged for failed jobs?
No. Credits are held while a job runs and charged only when it completes.
Do images cost credits?
Nano Banana images don't — each plan has a free allowance for the whole plan and per day (see the table above), and a 2K / 4K upscale counts 2 / 4 of it. GPT Image uses credits.
Why are some Veo 3.1 Lite clips slower?
Lite runs in a lower-priority queue, which is why it costs so little. At busy times a clip can wait a few extra minutes.
Can I use Omni Flash or GPT Image over the API?
Not yet — they are available in the website Studio.
Is there a webhook?
Not yet. Poll jobs with wait=30; it answers the moment a job changes.
How long are files kept?
Results for 24 hours and uploaded references for 3 days. Download what you want to keep.