Files
marswaveai__skills/shared/api-image.md
T

4.2 KiB

ListenHub API — Image Generation

Base URL: https://api.marswave.ai/openapi/v1 Authentication: Bearer $LISTENHUB_API_KEY (same key, different host)

POST /images/generation

Generate an AI image from a text prompt. Synchronous — returns base64-encoded image data directly (no polling needed).

Request body:

Field Required Type Description
provider Yes string Model provider. Use "google"
prompt Yes string Image description (English recommended)
model No string "gemini-3-pro-image-preview" (default) or "gemini-3.1-flash-image-preview"
imageConfig No object Size and aspect ratio config
imageConfig.imageSize No string "1K", "2K" (default), or "4K"
imageConfig.aspectRatio No string "1:1" (default). See aspect ratio table below.
referenceImages No array Up to 14 reference images for style guidance (see format below)

Aspect ratios:

Ratio Description Models
1:1 Square All
2:3 Portrait photo All
3:2 Landscape photo All
3:4 Poster portrait All
4:3 Traditional landscape All
9:16 Portrait / phone All
16:9 Landscape / widescreen All
21:9 Ultrawide All
1:4 Narrow portrait gemini-3.1-flash-image-preview only
4:1 Wide landscape gemini-3.1-flash-image-preview only
1:8 Extreme narrow portrait gemini-3.1-flash-image-preview only
8:1 Panoramic gemini-3.1-flash-image-preview only

referenceImages format:

Each item must have either fileData (URL) or inlineData (base64), not both. You can mix URL and base64 items in the same array.

URL-based reference:

{
  "fileData": {
    "fileUri": "https://example.com/photo.png",
    "mimeType": "image/png"
  }
}

Infer mimeType from URL suffix: .jpg/.jpegimage/jpeg, .pngimage/png, .webpimage/webp, .gifimage/gif

Base64 reference (inline):

{
  "inlineData": {
    "data": "<base64-encoded-image>",
    "mimeType": "image/png"
  }
}

Supported mimeTypes: image/png, image/jpeg, image/webp, image/heic, image/heif

To encode a local file as base64:

# macOS
BASE64_REF=$(base64 -i /path/to/image.png)

# Linux
BASE64_REF=$(base64 -w 0 /path/to/image.png)

Constraints:

  • Use --max-time 600 (generation can take up to 10 minutes)
  • On 429 (rate limit): wait 15s and retry. Max 3 retries.

curl (text-only):

RESPONSE=$(curl -sS -X POST "https://api.marswave.ai/openapi/v1/images/generation" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Source: skills" \
  --max-time 600 \
  -d '{
    "provider": "google",
    "model": "gemini-3-pro-image-preview",
    "prompt": "cyberpunk city at night, neon lights, highly detailed",
    "imageConfig": {"imageSize": "2K", "aspectRatio": "16:9"}
  }')

curl (with base64 reference image):

BASE64_REF=$(base64 -i /path/to/reference.png)

RESPONSE=$(curl -sS -X POST "https://api.marswave.ai/openapi/v1/images/generation" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  --max-time 600 \
  -d "{
    \"provider\": \"google\",
    \"model\": \"gemini-3-pro-image-preview\",
    \"prompt\": \"cyberpunk city at night\",
    \"imageConfig\": {\"imageSize\": \"2K\", \"aspectRatio\": \"16:9\"},
    \"referenceImages\": [{\"inlineData\": {\"data\": \"$BASE64_REF\", \"mimeType\": \"image/png\"}}]
  }")

Response:

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "inlineData": {
              "data": "<base64-encoded-jpeg>",
              "mimeType": "image/jpeg"
            }
          }
        ]
      }
    }
  ]
}

Extract base64 data:

BASE64_DATA=$(echo "$RESPONSE" | jq -r '.candidates[0].content.parts[0].inlineData.data // .data')

Save to file (macOS):

echo "$BASE64_DATA" | base64 -D > ~/Downloads/listenhub-$(date +%Y%m%d-%H%M%S)-0001.jpg

Save to file (Linux):

echo "$BASE64_DATA" | base64 -d > ~/Downloads/listenhub-$(date +%Y%m%d-%H%M%S)-0001.jpg