Veo 3.1 Video Generation API
API for generating videos using Google Veo 3.1 with text-to-video, reference image, and first/last frame modes. Supports multi-shot long videos up to 168 seconds.
Try it online: https://nanophoto.ai/veo-3
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/veo-3/generate | Generate a video |
| POST | /api/veo-3/check-status | Check task status |
Authentication
Authorization: Bearer YOUR_API_KEYCredits
| Resolution | Shots | Credits |
|---|---|---|
| 720p | per shot | 10 |
| 1080p | 1 shot only | 14 |
| 4K | 1 shot only | 30 |
Each shot generates an 8-second video clip. Multi-shot videos are concatenated automatically.
Maximum 21 shots per request (168 seconds total). 1080p and 4K are only available for single-shot generation.
Generate Video
POST /api/veo-3/generateHeaders
| Header | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer YOUR_API_KEY |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
shots | object[] | Yes | Array of shot objects (max 21) |
shots[].id | string | Yes | Unique identifier for the shot |
shots[].prompt | string | Yes | Video generation prompt |
shots[].generationType | string | Yes | TEXT_2_VIDEO, FIRST_AND_LAST_FRAMES_2_VIDEO, or REFERENCE_2_VIDEO |
shots[].aspectRatio | string | Yes | 16:9 or 9:16 |
shots[].imageUrls | string[] | Conditional | Public image URLs (see generation type requirements) |
resolution | string | No | 720p (default), 1080p, or 4k (single shot only) |
Generation Types
| Type | Description | Images Required |
|---|---|---|
TEXT_2_VIDEO | Text to video | None (no images allowed) |
FIRST_AND_LAST_FRAMES_2_VIDEO | First/last frame to video | 1-2 images |
REFERENCE_2_VIDEO | Reference image to video | 1-3 images |
API calls only accept imageUrls (public URLs). Base64 image upload is not supported via API.
Examples
Text to Video (Single Shot)
curl -X POST "https://nanophoto.ai/api/veo-3/generate" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-raw '{
"shots": [
{
"id": "shot-1",
"prompt": "A golden retriever running on a beach at sunset, cinematic lighting",
"generationType": "TEXT_2_VIDEO",
"aspectRatio": "16:9"
}
],
"resolution": "720p"
}'Reference Image to Video
curl -X POST "https://nanophoto.ai/api/veo-3/generate" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-raw '{
"shots": [
{
"id": "shot-1",
"prompt": "The character comes alive, walking through a magical forest",
"generationType": "REFERENCE_2_VIDEO",
"aspectRatio": "16:9",
"imageUrls": ["https://static.nanophoto.ai/demo/nano-banana-pro.webp"]
}
],
"resolution": "720p"
}'Multi-Shot Video
curl -X POST "https://nanophoto.ai/api/veo-3/generate" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-raw '{
"shots": [
{
"id": "shot-1",
"prompt": "Wide shot of a city skyline at dawn, golden hour lighting",
"generationType": "TEXT_2_VIDEO",
"aspectRatio": "16:9"
},
{
"id": "shot-2",
"prompt": "Close-up of a coffee cup on a windowsill, steam rising",
"generationType": "TEXT_2_VIDEO",
"aspectRatio": "16:9"
},
{
"id": "shot-3",
"prompt": "A person walking through a park, autumn leaves falling",
"generationType": "TEXT_2_VIDEO",
"aspectRatio": "16:9"
}
],
"resolution": "720p"
}'TypeScript
async function generateVideo() {
// Step 1: Submit generation task
const response = await fetch("https://nanophoto.ai/api/veo-3/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer YOUR_API_KEY",
},
body: JSON.stringify({
shots: [
{
id: "shot-1",
prompt: "A golden retriever running on a beach at sunset",
generationType: "TEXT_2_VIDEO",
aspectRatio: "16:9",
},
],
resolution: "720p",
}),
});
const data = await response.json();
if (data.status === "failed") {
console.error("Generation failed:", data.error);
return;
}
// Step 2: Poll for status
const taskIds = data.shots.map((shot: any) => ({
shotId: shot.shotId,
taskId: shot.taskId,
}));
while (true) {
await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait 5s
const statusRes = await fetch(
"https://nanophoto.ai/api/veo-3/check-status",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer YOUR_API_KEY",
},
body: JSON.stringify({ taskIds, resolution: "720p" }),
}
);
const status = await statusRes.json();
if (status.status === "completed") {
for (const shot of status.shots) {
console.log(`Shot ${shot.shotId} Video URL:`, shot.videoUrl);
}
return;
}
if (status.status === "failed") {
console.error("Generation failed:", status.shots);
return;
}
console.log("Still processing...");
}
}
generateVideo();Response
Processing
{
"status": "processing",
"shots": [
{
"shotId": "shot-1",
"taskId": "task_abc123",
"status": "processing"
}
],
"creditsUsed": 10
}When you receive status: "processing", poll the check-status endpoint every 5-10 seconds.
Error
{
"error": "Insufficient credits",
"errorCode": "INSUFFICIENT_CREDITS",
"requiredCredits": 10
}Check Task Status
POST /api/veo-3/check-statusHeaders
| Header | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer YOUR_API_KEY |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskIds | object[] | Yes | Array of task ID objects from generate response |
taskIds[].shotId | string | Yes | Shot ID |
taskIds[].taskId | string | Yes | Task ID from generate response |
resolution | string | No | 720p (default), 1080p, or 4k |
Example
curl -X POST "https://nanophoto.ai/api/veo-3/check-status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-raw '{
"taskIds": [
{"shotId": "shot-1", "taskId": "task_abc123"}
],
"resolution": "720p"
}'Response
Still Processing
{
"status": "processing",
"shots": [
{
"shotId": "shot-1",
"taskId": "task_abc123",
"status": "processing"
}
]
}Completed
{
"status": "completed",
"shots": [
{
"shotId": "shot-1",
"taskId": "task_abc123",
"status": "completed",
"videoUrl": "https://video.nanophoto.ai/veo/...",
"generationTime": 90
}
]
}Failed
{
"status": "failed",
"shots": [
{
"shotId": "shot-1",
"taskId": "task_abc123",
"status": "failed",
"error": "Video generation failed"
}
]
}Polling Strategy
- Poll
/api/veo-3/check-statusevery 5-10 seconds - Typical generation time: 2-5 minutes per shot
- Multi-shot videos take longer as each shot is generated sequentially
- Credits are automatically refunded if generation fails
Error Codes
| errorCode | HTTP Status | Description |
|---|---|---|
LOGIN_REQUIRED | 401 | Authentication required |
API_KEY_RATE_LIMIT_EXCEEDED | 429 | Rate limit exceeded (100 req/hour) |
INSUFFICIENT_CREDITS | 402 | Not enough credits |
SHOTS_REQUIRED | 400 | Missing shots array |
PROMPT_REQUIRED | 400 | Missing prompt in a shot |
INVALID_IMAGE_COUNT | 400 | Wrong number of images for generation type |
IMAGE_URLS_REQUIRED | 400 | API calls require imageUrls (no base64) |
GENERATION_FAILED | 500 | Video generation failed |
TASK_IDS_REQUIRED | 400 | Missing task IDs |
TASK_NOT_FOUND | 404 | Task not found or not owned by user |
INTERNAL_ERROR | 500 | Internal server error |
Nano Banana 2 Image Generation API
API for generating AI images with text-to-image and image-to-image modes using Nano Banana 2, with Google Search enhanced prompts.
SeeDance 1.5 Pro Video Generation API
API for generating videos using SeeDance 1.5 Pro with text-to-video and image-to-video modes. Supports multiple resolutions, durations, and audio generation.
وثائق NanoPhoto.AI