Generate Videos

November 17, 2025 (November 26, 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, Veo 3.1 Fast Relaxed) from text prompts with optional start/end frames or reference images. Videos are returned as signed URLs ready for download.

This endpoint features dynamic concurrency management. If you receive a 429 Too Many Requests or 503 Service Unavailable response, simply wait 5-10 seconds before retryingβ€”both status codes indicate temporary capacity constraints and are safe to retry. If you consistently receive 429 errors, you may need to execute a cool-off period of at least a few hours before trying again. 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 Veo 3.1 Fast $5cents/video and Veo 3.1 Quality $50cents/video generations. Veo 3.1 Fast Relaxed is available for Ultra subscribers with no credit cost but lower generation priority.

Model Capabilities

Parameter Veo 3.1 Quality
veo-3.1-quality
Veo 3.1 Fast
veo-3.1-fast (default)
Veo 3.1 Fast Relaxed
veo-3.1-fast-relaxed
T2V (text-to-video) βœ“ βœ“ βœ“
I2V (start frame) βœ“ βœ“ βœ“
I2V-FL (start + end) βœ“ βœ“ βœ“
R2V (reference images 1-3) βœ— βœ“ (landscape only) βœ“ (landscape only)
Aspect ratios all all all
count βœ“ (1-4) βœ“ (1-4) βœ“ (1-4)
seed βœ“ βœ“ βœ“
Subscription all all Ultra only
Cost 100 credits / $0.50 10 credits / $0.05 free (lower priority)

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. The email address of the Google Flow account to use.

    When only one account is configured, the API will automatically use that account.

    With multiple accounts configured, omitting the email parameter triggers automatic load balancing based on video generation job statistics to select the healthiest account.

    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, veo-3.1-fast-relaxed (Ultra only, no credits, lower priority).
  • 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.
  • async is optional, enables fire-and-forget mode (default: false). When true, returns immediately with 201 Created and job metadata. Poll GET /jobs/jobId for completion status. Useful for avoiding long request timeouts since video generation takes 60-180 seconds.
  • replyUrl is optional, webhook URL for job status callbacks. Receives POST requests with job status updates (created, started, completed, failed). The JSON payload shape matches GET /jobs/jobId response.
  • replyRef is optional, custom reference string passed back in webhook callbacks. Useful for tracking jobs on your end.

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 and veo-3.1-fast-relaxed models

Responses

  • 200 OK

    Videos generated successfully. Returns job ID and operations array with video URLs and metadata.

    {
      "jobId": "j1731859234567v-u12345-email:jo***@gmail.com-bot:google-flow",
      "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
    }
    
  • 201 Created

    Job created in async mode (async: true). Video generation is processing in the background.

    Use GET /jobs/jobId to poll for completion status.

    {
      "jobid": "j1731859234567v-u12345-email:jo***@gmail.com-bot:google-flow",
      "type": "video",
      "status": "created",
      "created": "2025-11-17T12:34:56.789Z",
      "request": {
        "async": true,
        "prompt": "A serene mountain landscape at sunset with camera slowly panning right",
        "email": "jo***@gmail.com",
        "model": "veo-3.1-fast",
        "aspectRatio": "landscape",
        "count": 2,
        "seed": 123456,
        "replyUrl": "https://your-domain.com/webhook",
        "replyRef": "custom-reference-123"
      },
      "response": {
        "operations": [
          {
            "operation": {
              "name": "1450903d...redacted...9c86f0"
            },
            "sceneId": "1450903d...redacted...9c86f0",
            "status": "MEDIA_GENERATION_STATUS_PENDING"
          },
          {
            "operation": {
              "name": "f2eec9bd...redacted...e16f7a"
            },
            "sceneId": "f2eec9bd...redacted...e16f7a",
            "status": "MEDIA_GENERATION_STATUS_PENDING"
          }
        ]
      }
    }
    
  • 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

    Rate limit or quota exhausted (concurrency limit or account quota reached). Wait 5-10 seconds and retry. If this persists, you may need to cool this account off for a few hours before trying again.

    {
      "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

  • Video generation completed. Returns full video data with signed URLs.

    {
      jobId: string                              // Job identifier
      operations: Array<{
        operation: {
          name: string
          metadata: {
            '@type': string
            name: string
            video: {
              seed: number
              mediaGenerationId: string
              prompt: string
              fifeUrl: string                    // Signed video URL (MP4, valid ~24h)
              mediaVisibility: string
              servingBaseUri: string             // Signed thumbnail URL (JPEG, valid ~24h)
              model: string                      // veo_3_1_t2v | veo_3_1_i2v | veo_3_1_i2v_fl | veo_3_0_r2v
              isLooped: boolean
              aspectRatio: string                // VIDEO_ASPECT_RATIO_LANDSCAPE | PORTRAIT
            }
          }
        }
        sceneId: string
        mediaGenerationId: string
        status: string                           // MEDIA_GENERATION_STATUS_SUCCESSFUL | FAILED
      }>
      remainingCredits?: number
    }
    
  • Job created and processing in background. Structure matches GET /jobs/jobId response.

    {
      jobid: string                              // Job identifier
      type: 'video'                              // Job type
      status: 'created'                          // Job status
      created: string                            // ISO 8601 timestamp
      request: {
        async: true
        prompt: string
        email?: string
        model?: string
        aspectRatio?: string
        count?: number
        seed?: number
        startImage?: string
        endImage?: string
        referenceImage_1?: string
        referenceImage_2?: string
        referenceImage_3?: string
        replyUrl?: string
        replyRef?: string
      }
      response: {
        operations: Array<{
          operation: {
            name: string                         // Operation identifier
          }
          sceneId: string                        // Scene identifier
          status: 'MEDIA_GENERATION_STATUS_PENDING'
        }>
      }
    }
    
  • Error response structure (applies to both sync and async modes).

    {
      error: string | {                          // 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