Generate Videos
November 17, 2025
Table of contents
Generate videos using Google Flow AI models (Veo 3.1 Quality, Veo 3.1 Fast) from text prompts with optional start/end frames or reference images. Videos are returned as signed URLs ready for download.
Video generation typically completes within 60-180 seconds depending on the model and mode. The endpoint automatically polls for completion and returns the final result.
Use a Google AI Ultra $125/m special subscription plan for unlimited Veo 3.1 Fast video generations.
Model Capabilities
| Parameter | Veo 3.1 Qualityveo-3.1-quality | Veo 3.1 Fastveo-3.1-fast (default) |
|---|---|---|
| T2V (text-to-video) | β | β |
| I2V (start frame) | β | β |
| I2V-FL (start + end) | β | β |
| R2V (reference images 1-3) | β | β (landscape only) |
| Aspect ratios | all | all |
count | β (1-4) | β (1-4) |
seed | β | β |
https://api.useapi.net/v1/google-flow/videos
Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data
API tokenis required, see Setup useapi.net for details.
Request Body
{
"prompt": "A serene mountain landscape at sunset with camera slowly panning right",
"model": "veo-3.1-fast",
"aspectRatio": "landscape",
"count": 2,
"seed": 123456
}
emailis optional when only one account configured. However, if you have multiple accounts configured, this parameter becomes required. If reference images (startImage,endImage, orreferenceImage_1to_3) are provided, theemailparameter can be omittedβthe API will automatically use the same account where the images were uploaded.promptis required, text description for video generation.modelis optional, the AI model to use for video generation (default:veo-3.1-fast).
Supported values:veo-3.1-quality,veo-3.1-fast.aspectRatiois optional, output video aspect ratio (default:landscape).
Supported values:landscapeandportrait.countis optional, number of video variations to generate (1-4, default:1).seedis optional, random seed for reproducible results (integer β₯ 0).startImageis optional, mediaGenerationId from POST /assets/emailfor I2V mode (video starts with this frame).endImageis optional, mediaGenerationId from POST /assets/emailfor I2V-FL mode (video ends with this frame, requiresstartImage).referenceImage_1toreferenceImage_3are optional, mediaGenerationId from POST /assets/emailfor R2V mode (1-3 reference images for style/composition). Only works withveo-3.1-fastmodel andlandscapeaspect ratio.
Important:
- Cannot use both reference images (R2V) and start/end frames (I2V) in the same request
- End frame only (without start frame) is not supported
- R2V mode only supports landscape aspect ratio and works with
veo-3.1-fastmodel
Responses
-
Videos generated successfully. Returns operations array with video URLs and metadata.
{ "operations": [ { "operation": { "name": "d00af...redacted...6f7a", "metadata": { "@type": "type.googleapis.com/google.internal.labs.aisandbox.v1.Media", "name": "CAUSJ...redacted...OWQ5ZA", "video": { "seed": 123456, "mediaGenerationId": "CAUSJ...redacted...OWQ5ZA", "prompt": "A serene mountain landscape at sunset with camera slowly panning right", "fifeUrl": "https://storage.googleapis.com/ai-sandbox-videofx/video/...redacted...", "mediaVisibility": "PRIVATE", "servingBaseUri": "https://storage.googleapis.com/ai-sandbox-videofx/image/...redacted...", "model": "veo_3_1_t2v", "isLooped": false, "aspectRatio": "VIDEO_ASPECT_RATIO_LANDSCAPE" } } }, "sceneId": "323c0...redacted...3ebf6", "mediaGenerationId": "CAUSJ...redacted...OWQ5ZA", "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL" } ], "remainingCredits": 18760 } -
Invalid request (validation error, mode conflict, email mismatch, or content policy violation).
General errors:
{ "error": "Reference-to-video only supports landscape aspect ratio" }Content policy error:
{ "error": { "code": 400, "message": "Request contains an invalid argument.", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_UNSAFE_GENERATION" } ] } } -
Invalid API token.
{ "error": "Unauthorized" } -
Subscription expired or insufficient credits.
{ "error": "Account has no subscription or subscription expired" } -
Unauthorized access to reference images from another user.
{ "error": "Unauthorized access to user:123 detected in reference user:123-email:...-image:..." } -
Account not found or not configured.
{ "error": "Google Flow account [email protected] not found" } -
Video generation polling timeout (after 10 minutes).
{ "error": "Video generation polling timeout after 120 attempts (600s)" } -
Concurrency limit reached. Wait 5-10 seconds and retry.
{ "error": { "code": 429, "message": "Resource has been exhausted (e.g. check quota).", "status": "RESOURCE_EXHAUSTED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_USER_REQUESTS_THROTTLED" } ] } } -
Google session refresh failed. The account needs to be reconfigured. Delete the account using DELETE /accounts/
emailand add it again by strictly following the procedure in Setup Google Flow.{ "error": "Failed to refresh session: 500 Internal Server Error" }
Model
operations- Array of video generation operations (1-4 videos based oncount)operations[].operation.name- Unique operation identifieroperations[].operation.metadata.video.seed- Seed used for this generation (for reproducibility)operations[].operation.metadata.video.mediaGenerationId- mediaGenerationId for use in subsequent API callsoperations[].operation.metadata.video.prompt- The prompt used for generationoperations[].operation.metadata.video.fifeUrl- Signed video URL (MP4 format, valid for ~24 hours)operations[].operation.metadata.video.servingBaseUri- Signed thumbnail URL (JPEG format, valid for ~24 hours)operations[].operation.metadata.video.model- Model variant used (veo_3_1_t2v,veo_3_1_i2v,veo_3_1_i2v_fl,veo_3_0_r2vfor R2V mode)operations[].operation.metadata.video.aspectRatio- Generated video aspect ratiooperations[].sceneId- Unique scene identifieroperations[].status- Generation status (MEDIA_GENERATION_STATUS_SUCCESSFUL,MEDIA_GENERATION_STATUS_FAILED, etc.)remainingCredits- Remaining credits balance
{
operations: Array<{
operation: {
name: string
metadata: {
'@type': string
name: string
video: {
seed: number
mediaGenerationId: string
prompt: string
fifeUrl: string // Signed video URL (MP4)
mediaVisibility: string
servingBaseUri: string // Signed thumbnail URL (JPEG)
model: string // veo_3_1_t2v | veo_3_1_i2v | veo_3_1_i2v_fl | veo_3_0_r2v (R2V)
isLooped: boolean
aspectRatio: string // VIDEO_ASPECT_RATIO_LANDSCAPE | PORTRAIT
}
}
}
sceneId: string
mediaGenerationId: string
status: string // MEDIA_GENERATION_STATUS_SUCCESSFUL | FAILED | ...
}>
remainingCredits?: number
error?: string | { // Error: string (useapi.net) or object (Google API)
code: number
message: string
status: string
details: Array<{
'@type': string
reason: string
}>
}
}
Examples
-
curl -X POST \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A serene mountain landscape at sunset with camera slowly panning right", "model": "veo-3.1-fast", "aspectRatio": "landscape", "count": 2, "seed": 123456 }' \ "https://api.useapi.net/v1/google-flow/videos" > response.json # Extract video URLs using jq cat response.json | jq -r '.operations[0].operation.metadata.video.fifeUrl' cat response.json | jq -r '.operations[1].operation.metadata.video.fifeUrl' # Download videos using curl curl "$(cat response.json | jq -r '.operations[0].operation.metadata.video.fifeUrl')" --output video_1.mp4 curl "$(cat response.json | jq -r '.operations[1].operation.metadata.video.fifeUrl')" --output video_2.mp4 -
const token = 'YOUR_API_TOKEN'; const apiUrl = 'https://api.useapi.net/v1/google-flow/videos'; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A serene mountain landscape at sunset with camera slowly panning right', model: 'veo-3.1-fast', aspectRatio: 'landscape', count: 2, seed: 123456 }) }); const result = await response.json(); console.log('Generated videos:', result.operations.length); // Download videos for (const [index, op] of result.operations.entries()) { const video = op.operation.metadata.video; console.log(`Video ${index + 1} seed:`, video.seed); console.log(`mediaGenerationId:`, video.mediaGenerationId); console.log(`Video URL:`, video.fifeUrl); // Download video (Node.js) const videoResponse = await fetch(video.fifeUrl); const videoBuffer = await videoResponse.arrayBuffer(); const fs = require('fs'); fs.writeFileSync(`generated_video_${index + 1}.mp4`, Buffer.from(videoBuffer)); // Download thumbnail (Node.js) const thumbResponse = await fetch(video.servingBaseUri); const thumbBuffer = await thumbResponse.arrayBuffer(); fs.writeFileSync(`generated_video_${index + 1}_thumb.jpg`, Buffer.from(thumbBuffer)); } -
import requests token = 'YOUR_API_TOKEN' api_url = 'https://api.useapi.net/v1/google-flow/videos' headers = { 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json' } data = { 'prompt': 'A serene mountain landscape at sunset with camera slowly panning right', 'model': 'veo-3.1-fast', 'aspectRatio': 'landscape', 'count': 2, 'seed': 123456 } response = requests.post(api_url, headers=headers, json=data) result = response.json() print(f"Generated {len(result['operations'])} videos") # Download videos for index, op in enumerate(result['operations']): video = op['operation']['metadata']['video'] print(f"Video {index + 1} seed:", video['seed']) print(f"mediaGenerationId:", video['mediaGenerationId']) # Download video video_response = requests.get(video['fifeUrl']) with open(f'generated_video_{index + 1}.mp4', 'wb') as f: f.write(video_response.content) # Download thumbnail thumb_response = requests.get(video['servingBaseUri']) with open(f'generated_video_{index + 1}_thumb.jpg', 'wb') as f: f.write(thumb_response.content)