Table of Contents
- Authentication and Setup
- Step 1: Enable the Required APIs
- Step 2: Authentication Methods
- Step 3: Install the Client Library
- API Endpoints
- Vertex AI REST Endpoint
- Gemini API REST Endpoint
- gRPC Endpoint (Vertex AI)
- Generation Parameters
- Common Parameters (Both APIs)
- Vertex AI-Specific Parameters
- Image-to-Video Parameters (Additional)
- Complete API Examples
- Vertex AI: Text-to-Video (Python)
- Gemini API: Text-to-Video (Python)
- REST API: curl Example
- Async Job Lifecycle
- Job States
- Polling Best Practices
- Webhook Integration (Vertex AI)
- Pricing and Cost Calculation
- Cost Estimation for Common Workloads
- Vertex AI vs Gemini API Pricing
- Cost Optimization Strategies
- Rate Limits and Quotas
- Vertex AI Default Quotas
- Gemini API Default Quotas
- Requesting Quota Increases
- Error Codes and Troubleshooting
- Common API Errors
- Retry Logic Implementation
- API Usage Limits by Tier
- FAQ
- How do I generate videos longer than 60 seconds with the API?
- Can I use the Veo 3.1 API for commercial applications?
- Does the API support batch generation?
- How do I handle the SynthID watermark via API?
- What happens if my generation request times out?
- Can I choose the output video codec?
- Summary
Veo 3.1 API Guide: Complete Reference for Google's Video Generation API
You have a working Veo 3.1 integration idea. You know the model can generate high-quality video from text prompts. But when you open the Vertex AI documentation and search for "Veo 3.1 API reference," you find scattered pages, incomplete code samples, and no clear guide on how to authenticate, submit a generation job, poll for completion, and handle errors.
This gap between "the model works" and "the API works" costs development teams days or weeks of trial and error.
This guide consolidates everything I learned building a production Veo 3.1 integration — authentication setup, API endpoint references for all generation modes, parameter tables, pricing calculations, async job handling, error codes, and complete Python examples. It covers both the Vertex AI API (for production pipelines) and the Gemini API (for lightweight integrations).
By the end of this reference, you will be able to write a working Veo 3.1 API call from scratch, understand how billing works at scale, and handle the common failure modes that the official documentation glosses over.
Authentication and Setup
Before making any API calls, you need to set up authentication. Veo 3.1 uses Google Cloud's standard authentication framework.
Step 1: Enable the Required APIs
Veo 3.1 is accessible through two API surfaces:
| API | Use Case | Quota Model |
|---|---|---|
| Vertex AI API | Production pipelines, batch processing, team workflows | Per-second pricing, project-based quotas |
| Gemini API | Lightweight integrations, testing, single-user tools | Per-second pricing, API key based |
For both APIs, you must enable the service in your Google Cloud project:
# Enable Vertex AI API
gcloud services enable aiplatform.googleapis.com
# Or enable Gemini API
gcloud services enable generativelanguage.googleapis.com
Step 2: Authentication Methods
Option A: Service Account (Recommended for Production)
Create a service account in Google Cloud IAM, assign the Vertex AI User role, and download a JSON key file:
gcloud iam service-accounts create veo-api-sa \
--display-name="Veo 3.1 API Service Account"
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:veo-api-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
gcloud iam service-accounts keys create ./veo-sa-key.json \
--iam-account=veo-api-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com
Set the environment variable for authentication:
export GOOGLE_APPLICATION_CREDENTIALS="./veo-sa-key.json"
Option B: API Key (Gemini API Only)
For quick testing with the Gemini API, generate an API key:
gcloud alpha services api-keys create --api-target="generativelanguage.googleapis.com"
API keys are simpler but provide less granular access control than service accounts.
Step 3: Install the Client Library
pip install google-cloud-aiplatform google-generativeai
API Endpoints
Vertex AI REST Endpoint
POST https://YOUR_LOCATION-aiplatform.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/YOUR_LOCATION/publishers/google/models/veo-3.1:generateVideo
The supported locations for Veo 3.1 are us-central1, us-east1, europe-west4, and asia-east1. Generation latency varies by region — us-central1 typically has the lowest queue times.
Gemini API REST Endpoint
POST https://generativelanguage.googleapis.com/v1beta/models/veo-3.1:generateContent
gRPC Endpoint (Vertex AI)
aiplatform.googleapis.com:443
gRPC is recommended for high-volume production workloads because it supports streaming and has better performance under load compared to REST.
Generation Parameters
Common Parameters (Both APIs)
| Parameter | Type | Required | Description | Valid Values |
|---|---|---|---|---|
prompt | string | Yes | Text description of the video to generate | 1-1000 characters |
tier | string | No | Generation quality tier | lite, fast, quality (default: fast) |
duration | integer | No | Video length in seconds | 5, 8, 10, 15, 30, 60 (default: 8) |
aspectRatio | string | No | Output aspect ratio | 16:9, 9:16, 1:1, 4:3 (default: 16:9) |
seed | integer | No | Random seed for reproducible generation | 0-2147483647 (default: random) |
personGeneration | string | No | Policy for human figure generation | allow_all, dont_allow (default: allow_all) |
Vertex AI-Specific Parameters
| Parameter | Type | Required | Description | Valid Values |
|---|---|---|---|---|
negativePrompt | string | No | Things to avoid in the output | 1-500 characters |
stylePreset | string | No | Visual style guide | cinematic, anime, photorealistic, 3d-render, claymation |
motionIntensity | integer | No | How much motion occurs (0-10) | 0-10 (default: 5) |
enhancePrompt | boolean | No | Auto-enhance the prompt text | true, false (default: false) |
outputFormat | string | No | Video codec | mp4, webm (default: mp4) |
fps | integer | No | Frames per second | 24, 30 (default: 24) |
Image-to-Video Parameters (Additional)
| Parameter | Type | Required | Description |
|---|---|---|---|
inputImage | base64 | Yes (for image-to-video) | Base64-encoded reference image |
imageAction | string | No | Motion direction hint |
Complete API Examples
Vertex AI: Text-to-Video (Python)
import vertexai
from vertexai.preview.vision_models import VideoGenerationModel, VideoGenerationConfig
# Initialize Vertex AI
vertexai.init(project="YOUR_PROJECT_ID", location="us-central1")
# Load the Veo 3.1 model
model = VideoGenerationModel.from_pretrained("veo-3.1")
# Configure generation parameters
config = VideoGenerationConfig(
prompt="A black wolf walks through a snowy pine forest at dusk, "
"snow falling gently, cinematic lighting, shallow depth of field, "
"slow tracking shot following the wolf from the side",
negative_prompt="blurry, low quality, watermark",
tier="quality",
duration=8,
aspect_ratio="16:9",
seed=42,
person_generation="allow_all"
)
# Submit generation job
response = model.generate_video(config)
print(f"Generation job submitted: {response.job_id}")
# Poll for completion
import time
while True:
job = model.get_generation_job(response.job_id)
if job.status == "SUCCEEDED":
print(f"Video generated: {job.video_uri}")
break
elif job.status == "FAILED":
print(f"Generation failed: {job.error}")
break
print(f"Status: {job.status}, waiting 10 seconds...")
time.sleep(10)
# Download the video
if job.status == "SUCCEEDED":
job.video.save("output.mp4")
Gemini API: Text-to-Video (Python)
import google.generativeai as genai
import time
# Configure API key
genai.configure(api_key="YOUR_API_KEY")
# Initialize the model
model = genai.GenerativeModel("veo-3.1")
# Submit generation request
response = model.generate_content(
"Generate a video: A black wolf walks through a snowy pine forest at dusk",
generation_config={
"tier": "fast",
"duration": 8,
"aspect_ratio": "16:9",
}
)
# Get the operation ID
operation_id = response.result.get("operation_id")
print(f"Operation ID: {operation_id}")
# Poll for result
while True:
status = genai.get_operation(operation_id)
if status.done:
video_url = status.response.get("video_url")
print(f"Video ready: {video_url}")
break
print("Generating...")
time.sleep(5)
REST API: curl Example
# Submit a generation request
curl -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"instances": [{
"prompt": "A black wolf walks through a snowy pine forest at dusk, cinematic lighting"
}],
"parameters": {
"tier": "fast",
"duration": 8,
"aspectRatio": "16:9",
"seed": 42
}
}' \
"https://us-central1-aiplatform.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/us-central1/publishers/google/models/veo-3.1:generateVideo"
Async Job Lifecycle
Veo 3.1 generation jobs are asynchronous. Understanding the job lifecycle is essential for building reliable integrations.
Job States
| State | Description | Expected Duration | Action Required |
|---|---|---|---|
QUEUED | Request accepted, waiting for resources | 0-30 seconds | None (auto-advances) |
GENERATING | Model actively generating video | Tier-dependent: Lite 8-15s, Fast 25-45s, Quality 60-180s | None (auto-advances) |
SUCCEEDED | Generation complete, video ready | N/A | Download video |
FAILED | Generation encountered an error | N/A | Check error code and retry |
CANCELLED | Job was cancelled by user | N/A | Submit new request |
TIMEOUT | Job exceeded max processing time | N/A | Retry with simpler prompt or higher tier |
Polling Best Practices
def wait_for_generation(job_id, max_retries=60, interval=10):
"""
Poll for generation completion with exponential backoff.
Args:
job_id: The generation job ID
max_retries: Maximum number of poll attempts
interval: Initial poll interval in seconds
"""
import time
for attempt in range(max_retries):
job = model.get_generation_job(job_id)
if job.status == "SUCCEEDED":
return job
elif job.status == "FAILED":
raise Exception(f"Generation failed: {job.error}")
# Exponential backoff, capped at 60 seconds
wait = min(interval * (1.5 ** attempt), 60)
time.sleep(wait)
raise TimeoutError(f"Generation did not complete within {max_retries * interval} seconds")
Webhook Integration (Vertex AI)
For production systems, polling is inefficient. Vertex AI supports Cloud Pub/Sub notifications for generation completion:
from google.cloud import pubsub_v1
# Configure Pub/Sub topic for notifications
notification_config = {
"pubsub_topic": "projects/YOUR_PROJECT_ID/topics/veo-completion",
}
# Submit with notification config
response = model.generate_video(
config,
notification_config=notification_config
)
When the generation completes, Pub/Sub delivers a message containing the job ID and either the video URI or error details.
Pricing and Cost Calculation
Veo 3.1 pricing is per-second of generated video, varying by tier:
| Tier | Price per Second | 8-Second Clip Cost | 60-Second Clip Cost |
|---|---|---|---|
| Lite | $0.15 | $1.20 | $9.00 |
| Fast | $0.35 | $2.80 | $21.00 |
| Quality | $0.70 | $5.60 | $42.00 |
Cost Estimation for Common Workloads
| Use Case | Tier | Clips/Month | Estimated Monthly Cost |
|---|---|---|---|
| Social media content (8s each) | Fast | 200 | $560 |
| Prototyping and iteration | Lite | 500 | $600 |
| Commercial video production (60s each) | Quality | 50 | $2,100 |
| Batch A/B testing | Lite | 2,000 | $1,800 |
Vertex AI vs Gemini API Pricing
The per-second pricing is identical across both APIs. However, Vertex AI adds standard Cloud Platform fees for:
- Cloud Storage (for video output storage): ~$0.026/GB/month
- Pub/Sub (for notification): ~$0.50 per million messages
- Network egress: ~$0.12/GB (varies by region)
Cost Optimization Strategies
- Use Lite for draft work. Reserve Quality for final renders. This can reduce your monthly bill by 60-70%.
- Batch similar prompts. Submitting multiple similar requests in sequence can trigger caching optimizations.
- Monitor with billing alerts. Set up Google Cloud budget alerts to avoid surprise bills:
gcloud billing budgets create \ --billing-account=YOUR_BILLING_ACCOUNT \ --display-name="Veo 3.1 Budget" \ --budget-amount=1000 \ --threshold-rules=percent=50,percent=90
Rate Limits and Quotas
Vertex AI Default Quotas
| Resource | Limit | Scope |
|---|---|---|
| Generation requests per minute | 10 | Per project per region |
| Concurrent generation jobs | 5 | Per project per region |
| Daily video output minutes | 600 | Per project |
| Max prompt length | 1000 characters | Per request |
Gemini API Default Quotas
| Resource | Limit | Scope |
|---|---|---|
| Requests per minute (RPM) | 60 | Per API key |
| Tokens per minute (TPM) | 1,000,000 | Per API key |
| Daily requests | 10,000 | Per API key |
Requesting Quota Increases
For production workloads, the default quotas are often insufficient. Submit a quota increase request through the Google Cloud Console:
- Go to IAM & Admin > Quotas
- Search for "Vertex AI API" or "Generative Language API"
- Select the quota metric you need to increase
- Click "Edit Quotas" and request a higher limit
- Include a justification (expected volume, use case, project timeline)
Most quota increase requests are processed within 2-3 business days.
Error Codes and Troubleshooting
Common API Errors
| HTTP Status | Error Code | Meaning | Resolution |
|---|---|---|---|
| 400 | INVALID_ARGUMENT | Malformed request parameters | Check required fields and data types |
| 400 | INVALID_PROMPT | Prompt violates content policy | Review Google's content guidelines |
| 401 | UNAUTHENTICATED | Missing or invalid credentials | Verify API key or service account |
| 403 | PERMISSION_DENIED | Insufficient permissions | Add Vertex AI User role to service account |
| 429 | QUOTA_EXCEEDED | Rate limit hit | Implement retry with backoff |
| 429 | RESOURCE_EXHAUSTED | Daily quota exhausted | Wait for reset or request increase |
| 500 | INTERNAL | Server-side error | Retry with exponential backoff |
| 503 | UNAVAILABLE | Service temporarily unavailable | Retry after 30 seconds |
Retry Logic Implementation
import time
from google.api_core import exceptions
def generate_with_retry(model, config, max_retries=3):
"""Generate video with automatic retry for transient errors."""
for attempt in range(max_retries):
try:
response = model.generate_video(config)
return response
except exceptions.ResourceExhausted:
if attempt == max_retries - 1:
raise
wait = (2 ** attempt) * 30 # 30s, 60s, 120s
print(f"Rate limited. Retrying in {wait}s...")
time.sleep(wait)
except exceptions.ServiceUnavailable:
if attempt == max_retries - 1:
raise
time.sleep(30)
except exceptions.InvalidArgument as e:
# Invalid arguments won't succeed on retry
raise e
API Usage Limits by Tier
Each tier has different compute requirements that affect how many concurrent requests you can run:
| Tier | Average GPU Time per 8s Clip | Recommended Max Concurrent | Typical Queue Time |
|---|---|---|---|
| Lite | 2-4 seconds | 10-20 | <5 seconds |
| Fast | 8-12 seconds | 5-10 | <15 seconds |
| Quality | 20-40 seconds | 2-5 | <30 seconds |
FAQ
How do I generate videos longer than 60 seconds with the API?
The API does not support single generations longer than 60 seconds. For longer videos, generate multiple clips and stitch them together in post-production. The API's seed parameter helps maintain visual consistency across clips — use the same seed with slightly offset prompts.
Can I use the Veo 3.1 API for commercial applications?
Yes. Both the Vertex AI and Gemini APIs grant full commercial usage rights to generated content. Unlike the free tier, API-based generations include a commercial license by default.
Does the API support batch generation?
The Vertex AI API supports batch generation through the batchGenerateVideo endpoint. Submit an array of up to 10 generation configurations in a single request. Batch requests are processed sequentially but share authentication overhead.
How do I handle the SynthID watermark via API?
All API-generated videos include SynthID watermarking by default. There is no API parameter to disable it. The watermark is embedded at the pixel level and is detectable programmatically using Google's SynthID detection library.
What happens if my generation request times out?
The API returns a TIMEOUT status if generation exceeds 10 minutes for Quality tier or 3 minutes for Lite/Fast. Retry with a shorter prompt, lower tier, or shorter duration.
Can I choose the output video codec?
Yes. Use the outputFormat parameter. mp4 is H.264 encoded. webm is VP9 encoded. The Quality tier also supports H.265 (HEVC) as an option when outputFormat is set to mp4.
Summary
The Veo 3.1 API gives developers programmatic access to all three generation tiers through both Vertex AI and Gemini API surfaces. Key takeaways:
- Authentication: Use service accounts for production, API keys for testing. Enable the required APIs in your GCP project first.
- Parameters: The API supports text-to-video, image-to-video, and batch generation. The
tierparameter controls the speed-quality-cost trade-off. - Async lifecycle: Generation jobs are asynchronous. Implement polling with exponential backoff or use Pub/Sub webhooks for production.
- Error handling: Implement retry logic for transient errors (429, 503). Invalid arguments (400) and auth failures (401/403) should not be retried.
- Cost management: Use Lite tier for draft work, Fast for standard output, Quality for final renders. Set up billing alerts to prevent cost overruns.
The fastest path to a working integration: enable the Vertex AI API, create a service account, install the Python client library, and run the text-to-video example from this guide. From there, add the parameters and error handling your specific use case requires.


