Upscale Images

January 2, 2026 (February 14, 2026)

Table of contents

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

Upscale a previously generated image to 2K or 4K resolution. This endpoint uses Google Flow’s native image upscaling capabilities.

Important:

  • Upscaling is only supported for images generated with nano-banana-pro and nano-banana-2. The imagen-4 and legacy nano-banana alias images cannot be upscaled.
  • 4k resolution requires a paid Google account with an active subscription. Free accounts can only use 2k resolution.

https://api.useapi.net/v1/google-flow/images/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...-image:CAMaJDMx...",
  "resolution": "2k"
}
  • mediaGenerationId is required. The mediaGenerationId from a previously generated image via POST /images.
  • resolution is optional. Target resolution for upscaling (default: 2k). Supported values: 2k, 4k.
  • captchaToken, captchaRetry, captchaOrder are optional, mutually exclusive captcha parameters. See Captcha Parameters for details.

Responses

  • 200 OK

    Image upscaled successfully. Returns base64-encoded image data.

    {
      "encodedImage": "/9j/4AAQSkZJRgABAQAAAQ...base64 encoded image data...",
      "captcha": {
        "service": "AntiCaptcha",
        "taskId": "abc123...",
        "durationMs": 3500,
        "attempts": [
          {
            "service": "AntiCaptcha",
            "taskId": "abc123...",
            "durationMs": 3500,
            "success": true
          }
        ]
      }
    }
    
  • 400 Bad Request

    Invalid request (missing or invalid mediaGenerationId).

    {
      "error": "mediaGenerationId is required"
    }
    
  • 401 Unauthorized

    Invalid API token.

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

    Request rejected by Google — the reCAPTCHA token was outright rejected (not just scored low). After internal retries with fresh tokens, the worker returns this. The top-level error field carries a captcha_quality: prefix so tooling can detect this failure class. Increase captchaRetry (default 3) in the request body to 5 or higher, and configure additional providers via POST /accounts/captcha-providers so captchaOrder can cycle across them. If issues persist, contact your reCAPTCHA provider(s) support.

  • 404 Not Found

    Account not found or image not found.

    {
      "error": "Google Flow account [email protected] not found"
    }
    
  • 429 Too Many Requests

    Google returns several RESOURCE_EXHAUSTED 429 variants. Check the reason field and respond accordingly:

    Reason Meaning Scope What to do Cooldown
    PUBLIC_ERROR_
    USER_REQUESTS_THROTTLED
    Per-user concurrency limit (the token was fine) All models on the account Run fewer parallel requests, retry later ~30 min
    PUBLIC_ERROR_
    USER_QUOTA_REACHED
    Account’s overall Flow quota cap All models on the account Add accounts, or omit email to load-balance ~30 min
    PUBLIC_ERROR_
    PER_MODEL_DAILY_QUOTA_REACHED
    Per-model daily quota Only that model, on that account Switch model, or wait Next UTC midnight
    PUBLIC_ERROR_
    UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC
    Captcha-provider issue — low reCAPTCHA score (worker already auto-retried) Per request Add more captcha providers + captchaOrder, or raise captchaRetry 60s

    Every 429 returns the cooldown two ways — an HTTP Retry-After: <seconds> header and a body retryAfter: <ISO timestamp> field. Honor it before retrying.

    When email is omitted, the first three reasons quarantine the account and the load balancer routes around it. If every account is quarantined for the model you get 429 with error: "no_eligible_account". Routing details: GET /jobs › Load Balancing Algorithm.

    Captcha-quality failures prefix the top-level error with captcha_quality: (e.g. "captcha_quality: PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC after 3 attempts") so you can detect them without parsing the nested body.

  • 503 Service Unavailable

    503 has two distinct causes — check the response body to tell them apart.

    A transient Google-side outage. Wait 5-10 seconds and retry.

    {
      "error": {
        "code": 503,
        "message": "Service temporarily unavailable.",
        "status": "UNAVAILABLE"
      }
    }
    

    A captcha-provider failure — the top-level error is prefixed Captcha service failed:. The problem is your captcha provider (check its API key and balance), not Google. Don’t retry until the provider is back.

    {
      "error": "Captcha service failed: ERROR_ZERO_BALANCE",
      "code": 503
    }
    

Model

  • encodedImage - Base64-encoded upscaled image data (JPEG format)
  • captcha - Captcha metadata for debugging/research
  • captcha.service - Provider that returned the successful token
  • captcha.taskId - Task ID from the captcha service
  • captcha.durationMs - Total time for all captcha attempts
  • captcha.attempts - Array of all captcha attempts (including failures)
{
  encodedImage: string                // Base64-encoded image (decode and save as .jpg)
  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
    }>
  }
  error?: string | {                  // Error: string (useapi.net) or object (Google API)
    code: number
    message: string
    status: string
    details: Array<{
      '@type': string
      reason: string
    }>
  }
}

Examples

  • # First generate an image
    curl -X POST \
         -H "Authorization: Bearer YOUR_API_TOKEN" \
         -H "Content-Type: application/json" \
         -d '{"prompt": "A beautiful sunset over mountains"}' \
         "https://api.useapi.net/v1/google-flow/images" > generate.json
    
    # Extract mediaGenerationId from the response
    MEDIA_ID=$(jq -r '.media[0].image.generatedImage.mediaGenerationId' generate.json)
    
    # Upscale the image to 2K
    curl -X POST \
         -H "Authorization: Bearer YOUR_API_TOKEN" \
         -H "Content-Type: application/json" \
         -d "{\"mediaGenerationId\": \"$MEDIA_ID\", \"resolution\": \"2k\"}" \
         "https://api.useapi.net/v1/google-flow/images/upscale" > upscale.json
    
    # Decode base64 and save as image
    jq -r '.encodedImage' upscale.json | base64 -d > upscaled_image.jpg
    
  • const token = 'YOUR_API_TOKEN';
    
    // First generate an image
    const generateResponse = await fetch('https://api.useapi.net/v1/google-flow/images', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        prompt: 'A beautiful sunset over mountains'
      })
    });
    
    const generated = await generateResponse.json();
    const mediaGenerationId = generated.media[0].image.generatedImage.mediaGenerationId;
    
    // Upscale the image
    const upscaleResponse = await fetch('https://api.useapi.net/v1/google-flow/images/upscale', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        mediaGenerationId,
        resolution: '2k'
      })
    });
    
    const upscaled = await upscaleResponse.json();
    
    // Decode base64 and save
    const buffer = Buffer.from(upscaled.encodedImage, 'base64');
    require('fs').writeFileSync('upscaled_image.jpg', buffer);
    console.log('Upscaled image saved!');
    
  • import requests
    import base64
    
    token = 'YOUR_API_TOKEN'
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }
    
    # First generate an image
    generate_response = requests.post(
        'https://api.useapi.net/v1/google-flow/images',
        headers=headers,
        json={'prompt': 'A beautiful sunset over mountains'}
    )
    generated = generate_response.json()
    media_generation_id = generated['media'][0]['image']['generatedImage']['mediaGenerationId']
    
    # Upscale the image
    upscale_response = requests.post(
        'https://api.useapi.net/v1/google-flow/images/upscale',
        headers=headers,
        json={
            'mediaGenerationId': media_generation_id,
            'resolution': '2k'
        }
    )
    upscaled = upscale_response.json()
    
    # Decode base64 and save
    image_data = base64.b64decode(upscaled['encodedImage'])
    with open('upscaled_image.jpg', 'wb') as f:
        f.write(image_data)
    print('Upscaled image saved!')
    

Try It