Upscale Videos

January 20, 2026 (February 27, 2026)

Table of contents

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

Upscale a previously generated video to 1080p or 4K resolution.

  • Currently, video upscaling requires a paid Google AI subscription or remaining credits.
  • Currently, 4K resolution requires a Google AI Ultra subscription. Other paid accounts can only use 1080p resolution.
  • 1080p upscaling is free. 4K upscaling currently costs 50 credits.
  • Video upscaling typically completes within 30-60 seconds, with 4K taking a few minutes.
  • Upscaling the same video twice returns a cached result (no additional credits consumed). Use the video URL from the first upscale response.

https://api.useapi.net/v1/google-flow/videos/upscale

Request Headers

Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data

Request Body

{
  "mediaGenerationId": "user:12345-email:6a6f...-video:CAMaJDMx...",
  "resolution": "1080p"
}
  • mediaGenerationId is required. The mediaGenerationId from a previously generated video via POST /videos.
  • resolution is optional. Target resolution for upscaling (default: 1080p).
    Supported values: 1080p, 4K.
  • 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.
  • 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.
  • captchaToken, captchaRetry, captchaOrder are optional, mutually exclusive captcha parameters. See Captcha Parameters for details.

Responses

  • 200 OK

    Video upscaled successfully. Both operations[] (legacy, with fifeUrl) and media[] (current, with videoUrl) are populated.

    {
      "jobId": "j1737312345678v-u12345-email:jo***@gmail.com-bot:google-flow",
      "operations": [
        {
          "operation": {
            "name": "2fefd089-...redacted..._upsampled",
            "metadata": {
              "@type": "type.googleapis.com/google.internal.labs.aisandbox.v1.Media",
              "name": "2fefd089-...redacted..._upsampled",
              "video": {
                "seed": 0,
                "model": "veo_3_1_upsampler_1080p",
                "aspectRatio": "VIDEO_ASPECT_RATIO_LANDSCAPE",
                "isLooped": false,
                "fifeUrl": "https://flow-content.google/video/2fefd089-..._upsampled?Expires=...",
                "servingBaseUri": "https://flow-content.google/image/2fefd089-..._upsampled?Expires=...",
                "mediaGenerationId": "user:12345-email:6a6f...-video:2fefd089-..._upsampled",
                "mediaVisibility": "PRIVATE"
              }
            }
          },
          "sceneId": "",
          "status": "MEDIA_GENERATION_STATUS_SUCCESSFUL",
          "mediaGenerationId": "user:12345-email:6a6f...-video:2fefd089-..._upsampled"
        }
      ],
      "media": [
        {
          "name": "2fefd089-...redacted..._upsampled",
          "projectId": "9f63078c-...redacted...",
          "workflowId": "66612805-...redacted...",
          "workflowStepId": "CAI",
          "mediaMetadata": {
            "createTime": "2026-05-20T23:31:41.145235Z",
            "requestData": { "videoGenerationRequestData": { "...": "..." }, "clientPlatform": "CLIENT_PLATFORM_WEB" },
            "mediaStatus": { "mediaGenerationStatus": "MEDIA_GENERATION_STATUS_SUCCESSFUL" },
            "visibility": "PRIVATE"
          },
          "video": {
            "generatedVideo": {
              "seed": 0,
              "model": "veo_3_1_upsampler_1080p",
              "baseImageMediaGenerationId": "",
              "isLooped": false,
              "aspectRatio": "VIDEO_ASPECT_RATIO_LANDSCAPE",
              "upsampleMetadata": { "videoUpsampleResolution": "VIDEO_UPSAMPLE_RESOLUTION_1080P" }
            },
            "dimensions": { "length": "0s" },
            "operation": { "name": "2fefd089-..._upsampled" }
          },
          "mediaGenerationId": "user:12345-email:6a6f...-video:2fefd089-..._upsampled",
          "videoUrl": "https://flow-content.google/video/2fefd089-..._upsampled?Expires=...",
          "thumbnailUrl": "https://flow-content.google/image/2fefd089-..._upsampled?Expires=..."
        }
      ],
      "remainingCredits": 18760,
      "captcha": {
        "service": "AntiCaptcha",
        "taskId": "abc123...",
        "durationMs": 3500,
        "attempts": [
          {
            "service": "AntiCaptcha",
            "taskId": "abc123...",
            "durationMs": 3500,
            "success": true
          }
        ]
      }
    }
    
  • 201 Created

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

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

    {
      "jobid": "j1737312345678v-u12345-email:jo***@gmail.com-bot:google-flow",
      "type": "video",
      "status": "created",
      "created": "2026-01-19T12:34:56.789Z",
      "request": {
        "async": true,
        "mediaGenerationId": "user:12345-email:6a6f...-video:CAMaJDMx...",
        "resolution": "1080p"
      },
      "response": {
        "captcha": {
          "service": "AntiCaptcha",
          "taskId": "14af1dbb-885c-4e25-8121-7a79489dfd0e",
          "durationMs": 5357
        }
      }
    }
    
  • 400 Bad Request

    Invalid request.

    {
      "error": "Error message"
    }
    
  • 401 Unauthorized

    Invalid API token.

    {
      "error": "Unauthorized"
    }
    
  • 403 Forbidden

    Request rejected by Google.

    Recommendations:

    • Ensure captchaRetry is set to at least 3 (default). Try increasing to a higher value (e.g., 5) to see if that helps
    • If issues persist, contact useapi.net support
    {
      "error": {
        "code": 403,
        "details": [
          {
            "@type": "type.googleapis.com/google.rpc.ErrorInfo",
            "reason": "PUBLIC_ERROR_SOMETHING_WENT_WRONG"
          }
        ],
        "message": "reCAPTCHA evaluation failed",
        "status": "PERMISSION_DENIED"
      },
      "captcha": {
        "service": "AntiCaptcha",
        "taskId": "ab0251dc-6930-4a82-966a-71fe6ab6aa42",
        "durationMs": 5789,
        "attempts": [
          {
            "service": "AntiCaptcha",
            "taskId": "ab0251dc-6930-4a82-966a-71fe6ab6aa42",
            "durationMs": 5789,
            "success": true
          }
        ]
      }
    }
    
  • 404 Not Found

    Account not found or video not found.

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

    Video upscaling polling timeout (after 10 minutes).

    {
      "error": "Polling timeout"
    }
    

Model

  • Video upscaling completed. Returns upscaled video data with signed URLs. Re-upscaling the same video returns rawBytes (base64 video data) instead of URLs.

    {
      jobId: string                              // Job identifier
      operations: Array<{                        // Legacy shape, still populated for upscale (with fifeUrl)
        operation: {
          name: string
          metadata: {
            '@type': string
            name: string
            video: {
              seed: number
              model: string                      // veo_3_1_upsampler_1080p | veo_3_1_upsampler_4k
              aspectRatio: string                // VIDEO_ASPECT_RATIO_LANDSCAPE | PORTRAIT
              isLooped: boolean
              fifeUrl: string                    // Signed video URL (MP4, valid ~24h)
              servingBaseUri: string             // Signed thumbnail URL (JPEG, valid ~24h)
              mediaGenerationId: string          // Encoded reference ID for the upscaled video
              mediaVisibility: string
            }
          }
        }
        sceneId: string
        status: string                           // MEDIA_GENERATION_STATUS_SUCCESSFUL | FAILED
        mediaGenerationId: string
      }>
      media: Array<{                             // Current shape — same fields as POST /videos
        name: string                             // Media identifier (raw UUID)
        projectId: string
        workflowId?: string
        workflowStepId?: string                  // e.g. "CAI" for upscale
        mediaMetadata: {
          createTime?: string                    // ISO 8601 timestamp
          requestData?: object                   // Full Google Flow request payload
          mediaStatus: {
            mediaGenerationStatus: string        // MEDIA_GENERATION_STATUS_SUCCESSFUL | FAILED
            error?: { code: number; message: string }
          }
          visibility?: string
        }
        video?: {
          generatedVideo: {
            seed: number
            model: string                        // veo_3_1_upsampler_1080p | veo_3_1_upsampler_4k
            baseImageMediaGenerationId?: string  // Source video media ID
            isLooped: boolean
            aspectRatio: string                  // VIDEO_ASPECT_RATIO_LANDSCAPE | PORTRAIT
            upsampleMetadata?: { videoUpsampleResolution: string }  // VIDEO_UPSAMPLE_RESOLUTION_1080P | _4K
          }
          dimensions?: { length?: string }       // Often "0s" for upscale (not meaningful)
          operation: { name: string }
        }
        mediaGenerationId: string                // Encoded reference ID for use in subsequent API calls
        videoUrl?: string                        // Signed video download URL (MP4, valid ~24h)
        thumbnailUrl?: string                    // Signed thumbnail download URL (JPEG, valid ~24h)
      }>
      remainingCredits?: number
      captcha?: {                                // Captcha metadata
        service: string                          // "CapSolver" | "AntiCaptcha" | "YesCaptcha" | "CapMonster" | "SolveCaptcha" | "2Captcha" | "EzCaptcha" | "UserProvided"
        taskId?: string
        durationMs: number
        attempts: Array<{
          service: string
          taskId?: string
          durationMs: number
          success: boolean
          error?: string
        }>
      }
    }
    
  • 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
        mediaGenerationId: string                // Original video reference
        resolution?: string                      // "1080p" | "4K"
        replyUrl?: string
        replyRef?: string
      }
      response: {
        captcha?: {                              // Present when captcha was used
          service: string                        // Provider or "UserProvided"
          taskId?: string                        // Absent for UserProvided
          durationMs: number
        }
      }
    }
    
  • Error response structure.

    {
      jobId?: string                             // Present for job-related errors
      error: string                              // Error summary message
      code?: number                              // HTTP status code
      response?: {                               // API response with error details
        error?: {
          code: number
          message: string
          status: string
          details?: Array<{
            '@type': string
            reason: string
          }>
        }
      }
    }
    

Examples

  • # First generate a video
    curl -X POST \
         -H "Authorization: Bearer YOUR_API_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{"prompt": "A serene mountain landscape at sunset"}' \
         "https://api.useapi.net/v1/google-flow/videos" > generate.json
    
    # Extract mediaGenerationId from the response
    MEDIA_ID=$(jq -r '.media[0].mediaGenerationId' generate.json)
    
    # Upscale the video to 1080p
    curl -X POST \
         -H "Authorization: Bearer YOUR_API_TOKEN" \
         -H "Content-Type: application/json" \
         -d "{\"mediaGenerationId\": \"$MEDIA_ID\", \"resolution\": \"1080p\"}" \
         "https://api.useapi.net/v1/google-flow/videos/upscale" > upscale.json
    
    # Extract upscaled video URL and download
    VIDEO_URL=$(jq -r '.media[0].videoUrl' upscale.json)
    curl "$VIDEO_URL" --output upscaled_video.mp4
    
  • const token = 'YOUR_API_TOKEN';
    
    // First generate a video
    const generateResponse = await fetch('https://api.useapi.net/v1/google-flow/videos', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        prompt: 'A serene mountain landscape at sunset'
      })
    });
    
    const generated = await generateResponse.json();
    // Prefer media[] over deprecated operations[]
    const mediaGenerationId = generated.media[0].mediaGenerationId;
    
    // Upscale the video
    const upscaleResponse = await fetch('https://api.useapi.net/v1/google-flow/videos/upscale', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        mediaGenerationId,
        resolution: '1080p'
      })
    });
    
    const upscaled = await upscaleResponse.json();
    // Prefer media[] over deprecated operations[]
    const videoUrl = upscaled.media[0].videoUrl;
    
    // Download upscaled video (Node.js)
    const videoResponse = await fetch(videoUrl);
    const videoBuffer = await videoResponse.arrayBuffer();
    require('fs').writeFileSync('upscaled_video.mp4', Buffer.from(videoBuffer));
    console.log('Upscaled video saved!');
    
  • import requests
    
    token = 'YOUR_API_TOKEN'
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }
    
    # First generate a video
    generate_response = requests.post(
        'https://api.useapi.net/v1/google-flow/videos',
        headers=headers,
        json={'prompt': 'A serene mountain landscape at sunset'}
    )
    generated = generate_response.json()
    # Prefer media[] over deprecated operations[]
    media_generation_id = generated['media'][0]['mediaGenerationId']
    
    # Upscale the video
    upscale_response = requests.post(
        'https://api.useapi.net/v1/google-flow/videos/upscale',
        headers=headers,
        json={
            'mediaGenerationId': media_generation_id,
            'resolution': '1080p'
        }
    )
    upscaled = upscale_response.json()
    # Prefer media[] over deprecated operations[]
    video_url = upscaled['media'][0]['videoUrl']
    
    # Download upscaled video
    video_response = requests.get(video_url)
    with open('upscaled_video.mp4', 'wb') as f:
        f.write(video_response.content)
    print('Upscaled video saved!')
    

Try It