Generate Videos

November 17, 2025

Table of contents

  1. Model Capabilities
  2. Request Headers
  3. Request Body
  4. Responses
  5. Model
  6. Examples
  7. Try It

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 Quality
veo-3.1-quality
Veo 3.1 Fast
veo-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

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
}
  • email is optional when only one account configured. However, if you have multiple accounts configured, this parameter becomes required. If reference images (startImage, endImage, or referenceImage_1 to _3) are provided, the email parameter can be omittedβ€”the API will automatically use the same account where the images were uploaded.
  • prompt is required, text description for video generation.
  • model is optional, the AI model to use for video generation (default: veo-3.1-fast).
    Supported values: veo-3.1-quality, veo-3.1-fast.
  • aspectRatio is optional, output video aspect ratio (default: landscape).
    Supported values: landscape and portrait.
  • count is optional, number of video variations to generate (1-4, default: 1).
  • seed is optional, random seed for reproducible results (integer β‰₯ 0).
  • startImage is optional, mediaGenerationId from POST /assets/email for I2V mode (video starts with this frame).
  • endImage is optional, mediaGenerationId from POST /assets/email for I2V-FL mode (video ends with this frame, requires startImage).
  • referenceImage_1 to referenceImage_3 are optional, mediaGenerationId from POST /assets/email for R2V mode (1-3 reference images for style/composition). Only works with veo-3.1-fast model and landscape aspect 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-fast model

Responses

  • 200 OK

    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
    }
    
  • 400 Bad Request

    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"
          }
        ]
      }
    }
    
  • 401 Unauthorized

    Invalid API token.

    {
      "error": "Unauthorized"
    }
    
  • 402 Payment Required

    Subscription expired or insufficient credits.

    {
      "error": "Account has no subscription or subscription expired"
    }
    
  • 403 Forbidden

    Unauthorized access to reference images from another user.

    {
      "error": "Unauthorized access to user:123 detected in reference user:123-email:...-image:..."
    }
    
  • 404 Not Found

    Account not found or not configured.

    {
      "error": "Google Flow account [email protected] not found"
    }
    
  • 408 Request Timeout

    Video generation polling timeout (after 10 minutes).

    {
      "error": "Video generation polling timeout after 120 attempts (600s)"
    }
    
  • 429 Too Many Requests

    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"
          }
        ]
      }
    }
    
  • 596 Session Error

    Google session refresh failed. The account needs to be reconfigured. Delete the account using DELETE /accounts/email and 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 on count)
  • operations[].operation.name - Unique operation identifier
  • operations[].operation.metadata.video.seed - Seed used for this generation (for reproducibility)
  • operations[].operation.metadata.video.mediaGenerationId - mediaGenerationId for use in subsequent API calls
  • operations[].operation.metadata.video.prompt - The prompt used for generation
  • operations[].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_r2v for R2V mode)
  • operations[].operation.metadata.video.aspectRatio - Generated video aspect ratio
  • operations[].sceneId - Unique scene identifier
  • operations[].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)
    

Try It