# VEO3 API Guide for Large Language Models

## Overview

The VEO3 API generates AI videos (4, 6, or 8 seconds) from text prompts using Google's VEO 3.0/3.1 models. It uses a simple asynchronous workflow: start generation, poll for completion, get video URL.

**Base URL**: `https://api.veo3gen.app`

## Authentication

The API supports three authentication methods (Bearer recommended):

1. **Authorization Header** (Recommended):
   ```
   Authorization: Bearer veo_your_api_key_here
   ```

2. **X-API-Key Header**:
   ```
   X-API-Key: veo_your_api_key_here
   ```

3. **Query Parameter** (Not recommended):
   ```
   ?api_key=veo_your_api_key_here
   ```

All API keys start with `veo_`.

## Video Generation Workflow

1. **POST** `/api/generate` → Get `taskId`
2. **GET** `/api/status/{taskId}` → Poll every 10 seconds until completion
3. Extract `videoUrl` from completed response

## Generation Types

The API supports three types of video generation:

1. **Text-to-Video**: Generate video from a text prompt only
2. **Image-to-Video**: Generate video from an input image and text prompt (all models)
3. **First-and-Last-Frame**: Generate video between two images (VEO 3.1 only)

All three types use the same credit pricing.

## Available Models

| Model | Speed | Credits No Audio (8s) | Credits With Audio (8s) |
|-------|-------|-----------------------|-------------------------|
| `veo3-lite` | 1-2 minutes | 2–3 credits (720p/1080p) | 3–5 credits (720p/1080p) |
| `veo3-fast` | 1-3 minutes | 6 credits (SD), 19 (4K) | 10 credits (SD), 22 (4K) |
| `veo3-quality` | 2-5 minutes | 13 credits (SD), 26 (4K) | 26 credits (SD), 38 (4K) |

**Duration pricing**: All prices above are for 8-second videos. For 4s or 6s videos, credits are prorated linearly (rounded up): 4s = 50%, 6s = 75% of the 8s price.

**Note**: Image-to-video and first-and-last-frame generation use the same credit pricing as text-to-video.

## API Endpoints

### POST /api/generate

Starts video generation and returns a task ID for polling.

**Request Body (Text-to-Video)**:
```json
{
  "model": "veo3-fast",
  "modelVersion": "3.1",
  "prompt": "A majestic eagle soaring over snow-capped mountains at sunset",
  "audio": true,
  "options": {
    "resolution": "1080p",
    "aspectRatio": "16:9",
    "seed": 1234567890,
    "negativePrompt": "blurry, low quality"
  }
}
```

**Required Parameters**:
- `model`: `"veo3-lite"`, `"veo3-fast"`, or `"veo3-quality"`
- `prompt`: Text description (max 2000 characters)

**Optional Parameters**:
- `audio`: Generate audio (default: `true`)
- `modelVersion`: `"3.0"` or `"3.1"` (default: `"3.0"`)
- `image`: Image object for image-to-video (see below)
- `lastFrame`: Last frame image object for first-and-last-frame (requires VEO 3.1)
- `options.resolution`: `"720p"`, `"1080p"`, or `"4k"` (default: `"1080p"`; 4K requires modelVersion `"3.1"`)
- `options.duration`: `4`, `6`, or `8` (default: `8`) — video length in seconds; credits scale proportionally
- `options.aspectRatio`: `"16:9"` or `"9:16"` (default: `"16:9"`)
- `options.seed`: Number 0-4294967295 for reproducible results
- `options.negativePrompt`: What to avoid in the video (max 500 characters)

**Note**: `enhancePrompt` is always forced to `true` by the API and cannot be disabled.

**Response** (202 Accepted):
```json
{
  "success": true,
  "message": "Video generation started",
  "taskId": "veo_1704067200000_abc123",
  "status": "pending",
  "model": "veo3-fast",
  "creditsRequired": 15,
  "estimatedTime": "1-3 minutes",
  "prompt": "A majestic eagle soaring over snow-capped mountains...",
  "audio": true,
  "options": {
    "resolution": "1080p",
    "aspectRatio": "16:9",
    "seed": 1234567890,
    "negativePrompt": "blurry, low quality",
    "enhancePrompt": true,
    "maxWaitTime": 480000
  },
  "polling": {
    "endpoint": "/api/status/veo_1704067200000_abc123",
    "intervalSeconds": 10,
    "timeoutSeconds": 300
  }
}
```

### GET /api/status/:taskId

Checks the generation status. Poll this endpoint every 10 seconds.

**Pending/Processing Response**:
```json
{
  "success": true,
  "taskId": "veo_1704067200000_abc123",
  "status": "pending",
  "model": "veo3-fast",
  "prompt": "A majestic eagle soaring over snow-capped mountains...",
  "audio": true,
  "apiKey": {
    "id": "api_key_id",
    "name": "My API Key"
  },
  "timing": {
    "startedAt": "2024-01-01T12:00:00.000Z",
    "elapsedSeconds": 45
  },
  "progress": {
    "stage": "initializing",
    "message": "Request received, preparing for generation...",
    "elapsedSeconds": 45,
    "estimatedRemainingSeconds": 120
  },
  "credits": {
    "required": 15,
    "charged": 0,
    "refunded": 0
  }
}
```

**Completed Response**:
```json
{
  "success": true,
  "taskId": "veo_1704067200000_abc123",
  "status": "completed",
  "model": "veo3-fast",
  "prompt": "A majestic eagle soaring over snow-capped mountains...",
  "audio": true,
  "apiKey": {
    "id": "api_key_id",
    "name": "My API Key"
  },
  "timing": {
    "startedAt": "2024-01-01T12:00:00.000Z",
    "completedAt": "2024-01-01T12:02:30.000Z",
    "totalProcessingSeconds": 150
  },
  "result": {
    "videoUrl": "https://storage.googleapis.com/veo3videosave/video_xyz789.mp4",
    "gcsUri": "gs://veo3videosave/video_xyz789.mp4",
    "mimeType": "video/mp4",
    "duration": 8,
    "resolution": "1080p",
    "aspectRatio": "16:9",
    "hasAudio": true,
    "processingTimeSeconds": 150
  },
  "credits": {
    "required": 15,
    "charged": 15,
    "refunded": 0
  }
}
```

**Failed Response**:
```json
{
  "success": true,
  "taskId": "veo_1704067200000_abc123",
  "status": "failed",
  "model": "veo3-fast",
  "prompt": "A majestic eagle soaring over snow-capped mountains...",
  "audio": true,
  "apiKey": {
    "id": "api_key_id",
    "name": "My API Key"
  },
  "timing": {
    "startedAt": "2024-01-01T12:00:00.000Z",
    "elapsedSeconds": 65
  },
  "error": {
    "type": "CONTENT_POLICY_VIOLATION",
    "message": "Your video was filtered by Google's content safety policies. Please try a different prompt.",
    "retryable": false
  },
  "credits": {
    "required": 15,
    "charged": 0,
    "refunded": 15
  }
}
```

## Status Values

- `pending`: Request queued, waiting to start
- `processing`: Video being generated by Google VEO3
- `completed`: Video ready with URL available
- `failed`: Generation failed, credits automatically refunded
- `timeout`: Generation timed out, credits refunded
- `cancelled`: Generation was cancelled

## Rate Limits

- **Generation requests**: 100 per hour (default, may vary per API key)
- **Status checks**: 120 per minute (very generous for polling)

## Credit System

### Costs (8-second baseline)
| Model | Resolution | No Audio | With Audio |
|-------|-----------|---------|-----------|
| `veo3-lite` | 720p | 2 cr | 3 cr |
| `veo3-lite` | 1080p | 3 cr | 5 cr |
| `veo3-fast` | 720p/1080p | 6 cr | 10 cr |
| `veo3-fast` | 4K | 19 cr | 22 cr |
| `veo3-quality` | 720p/1080p | 13 cr | 26 cr |
| `veo3-quality` | 4K | 26 cr | 38 cr |

**Duration scaling**: Credits are prorated for shorter videos (rounded up):
- **8 seconds** (default): 100% of the table price
- **6 seconds**: 75% of the table price
- **4 seconds**: 50% of the table price

### Behavior
- Credits are **reserved** when generation starts
- **Successful** generations charge the full amount
- **Failed** generations refund all credits
- Check your credit balance before making requests

## Error Handling

Common errors and recommended actions:

- **Insufficient credits**: Top up credits before retrying
- **Rate limit exceeded**: Wait and retry with exponential backoff
- **Content policy violation**: Modify prompt and retry
- **System error**: Retry after a short delay

## Image-to-Video Generation

Generate a video from an input image. Works with **all models (VEO 3.0 and 3.1)**. Same pricing as text-to-video.

**Key Features**:
- Same credit pricing as text-to-video
- Works with both VEO 3.0 and 3.1
- Optional prompt for controlling motion
- All aspect ratios supported (16:9 and 9:16)

**Request Body**:
```json
{
  "model": "veo3-quality",
  "modelVersion": "3.1",
  "prompt": "A serene lake with gentle waves and birds flying overhead",
  "audio": true,
  "image": {
    "bytesBase64Encoded": "base64_encoded_image_data_here",
    "mimeType": "image/jpeg"
  },
  "options": {
    "resolution": "1080p",
    "aspectRatio": "16:9"
  }
}
```

**Supported Image Formats**:
- `image/jpeg`
- `image/png`
- `image/webp`

**Image Requirements**:
- Maximum size: 20MB
- Recommended resolution: 720p or higher
- Both `bytesBase64Encoded` and `mimeType` are required

**Note**: The developer `POST /api/generate` endpoint always requires `prompt`, including for image-to-video. It must be a non-empty string of at most 2,000 characters.

## First-and-Last-Frame Generation

Generate a video that smoothly transitions between two images (first and last frame). **Requires VEO 3.1 models.** Perfect for creating transformations, before/after sequences, and precise video keyframing.

**Key Features**:
- Same credit pricing as regular video generation
- Requires VEO 3.1 models (both fast and quality)
- Control both start and end of your video
- Perfect for product transformations and storytelling
- Smooth AI-generated transitions between frames

**Request Body**:
```json
{
  "model": "veo3-quality",
  "modelVersion": "3.1",  // REQUIRED for first-and-last-frame
  "prompt": "A smooth cinematic transition from sunrise to sunset",
  "audio": true,
  "image": {
    "bytesBase64Encoded": "base64_encoded_first_frame_here",
    "mimeType": "image/jpeg"
  },
  "lastFrame": {
    "bytesBase64Encoded": "base64_encoded_last_frame_here",
    "mimeType": "image/jpeg"
  },
  "options": {
    "resolution": "1080p",
    "aspectRatio": "16:9"
  }
}
```

**Important Requirements**:
- First-and-last-frame generation **ONLY works with VEO 3.1** models
- `modelVersion` must be set to `"3.1"` - you'll receive a validation error otherwise
- Both `image` (first frame) and `lastFrame` (last frame) must be provided
- Same credit pricing as text-to-video generation
- Prompt is recommended to guide the transition style

**Use Cases**:
- Product before/after transformations
- Cinematic scene transitions
- Story boarding and animation keyframing
- Time-lapse style videos with specific start/end points

## Complete Implementation Example

### JavaScript/Node.js
```javascript
async function generateVideo(prompt, options = {}) {
  const API_KEY = 'veo_your_api_key_here';
  const BASE_URL = 'https://api.veo3gen.app';
  
  // 1. Start generation
  const response = await fetch(`${BASE_URL}/api/generate`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: options.model || 'veo3-fast',
      prompt: prompt,
      audio: options.audio !== false,
      options: {
        resolution: options.resolution || '720p',
        seed: options.seed,
        negativePrompt: options.negativePrompt
      }
    })
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Generation failed: ${error.error}`);
  }

  const { taskId } = await response.json();
  console.log(`Generation started: ${taskId}`);

  // 2. Poll for completion
  const maxWaitTime = 300000; // 5 minutes
  const startTime = Date.now();
  
  while (Date.now() - startTime < maxWaitTime) {
    const statusResponse = await fetch(`${BASE_URL}/api/status/${taskId}`, {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    });

    if (!statusResponse.ok) {
      const error = await statusResponse.json();
      throw new Error(`Status check failed: ${error.error}`);
    }

    const status = await statusResponse.json();
    console.log(`Status: ${status.status}`);

    if (status.status === 'completed') {
      return {
        videoUrl: status.result.videoUrl,
        duration: status.result.duration,
        creditsUsed: status.credits.charged
      };
    }
    
    if (status.status === 'failed') {
      throw new Error(`Generation failed: ${status.error.message}`);
    }

    // Wait 10 seconds before next check
    await new Promise(resolve => setTimeout(resolve, 10000));
  }

  throw new Error('Generation timed out');
}

// Usage
generateVideo('A peaceful sunset over calm ocean waters', {
  model: 'veo3-quality',
  resolution: '1080p',
  audio: true
})
.then(result => {
  console.log('Video ready:', result.videoUrl);
  console.log('Credits used:', result.creditsUsed);
})
.catch(error => {
  console.error('Error:', error.message);
});
```

### Python
```python
import requests
import time

def generate_video(prompt, model='veo3-fast', audio=True, resolution='720p', **options):
    API_KEY = 'veo_your_api_key_here'
    BASE_URL = 'https://api.veo3gen.app'
    
    headers = {
        'Authorization': f'Bearer {API_KEY}',
        'Content-Type': 'application/json'
    }
    
    # 1. Start generation
    payload = {
        'model': model,
        'prompt': prompt,
        'audio': audio,
        'options': {
            'resolution': resolution,
            'seed': options.get('seed'),
            'negativePrompt': options.get('negativePrompt')
        }
    }
    
    # Remove None values
    payload['options'] = {k: v for k, v in payload['options'].items() if v is not None}
    
    response = requests.post(f'{BASE_URL}/api/generate', headers=headers, json=payload)
    
    if not response.ok:
        error = response.json()
        raise Exception(f"Generation failed: {error.get('error', 'Unknown error')}")
    
    task_id = response.json()['taskId']
    print(f'Generation started: {task_id}')
    
    # 2. Poll for completion
    max_wait_time = 300  # 5 minutes
    start_time = time.time()
    
    while time.time() - start_time < max_wait_time:
        status_response = requests.get(f'{BASE_URL}/api/status/{task_id}', headers=headers)
        
        if not status_response.ok:
            error = status_response.json()
            raise Exception(f"Status check failed: {error.get('error', 'Unknown error')}")
        
        status = status_response.json()
        print(f'Status: {status["status"]}')
        
        if status['status'] == 'completed':
            return {
                'videoUrl': status['result']['videoUrl'],
                'duration': status['result']['duration'],
                'resolution': status['result']['resolution'],
                'hasAudio': status['result']['hasAudio'],
                'processingTime': status['result']['processingTimeSeconds'],
                'creditsUsed': status['credits']['charged']
            }
        
        if status['status'] == 'failed':
            raise Exception(f"Generation failed: {status['error']['message']}")
        
        time.sleep(10)  # Wait 10 seconds
    
    raise Exception('Generation timed out')

# Usage
try:
    result = generate_video(
        'A serene mountain lake with gentle ripples reflecting the sky',
        model='veo3-quality',
        resolution='1080p',
        audio=True
    )
    
    print(f'Video ready: {result["videoUrl"]}')
    print(f'Credits used: {result["creditsUsed"]}')
    
except Exception as e:
    print(f'Error: {e}')
```

## Best Practices

1. **Always handle errors gracefully** - Check response status codes
2. **Implement exponential backoff** for retryable errors
3. **Poll every 10 seconds** - Don't poll faster than necessary
4. **Set reasonable timeouts** - 5 minutes for fast, 8 minutes for quality
5. **Validate inputs** - Check prompt length, model names, etc.
6. **Monitor credits** - Ensure sufficient balance before generation
7. **Store API keys securely** - Use environment variables, never hardcode

## Technical Specifications

- **Video Duration**: 4, 6, or 8 seconds (default: 8) — set via `options.duration`
- **Aspect Ratios**: 16:9 (landscape) and 9:16 (portrait)
- **Resolutions**: 720p, 1080p (all models); 4K (veo3-fast/quality with modelVersion "3.1")
- **Format**: MP4
- **Audio**: Optional AI-generated audio
- **Prompt Limit**: 2000 characters
- **Image Formats**: JPEG, PNG, WebP
- **Request Timeout**: 5 minutes for polling
- **Generation Types**: Text-to-video, image-to-video, first-and-last-frame (VEO 3.1 only)
- **Model Versions**: 3.0 (stable), 3.1 (stable with enhanced features including 4K)

This guide contains everything needed for LLMs to successfully implement VEO3 video generation.
