Skip to content

Gemini Image Generation ​

Use this endpoint to create image generation tasks from text descriptions or reference images. It supports text-to-image and image editing (image-to-image). Gemini image models are collectively referred to as Nano Banana; they have a built-in Thinking process, generated images are returned Base64-encoded and carry a SynthID watermark.

Endpoint ​

http
POST /v1beta/models/<Model ID>:generateContent

Authentication ​

MethodDescription
Bearer TokenInclude Authorization: Bearer <API_key> in the request header to authenticate your account.

Authentication Note: If the Authorization parameter cannot be recognized, pass the authentication credentials via the x-goog-api-key header instead:

http
x-goog-api-key: <API Key>

Request Headers ​

ParameterTypeRequiredDescription
Content-TypestringYesThe media type of the request body. Set it to application/json
AuthorizationstringYesBearer API_key, used to authenticate your account

Note: The model ID is specified by the <Model ID> placeholder in the URL path (e.g., /v1beta/models/ge-3.1-fl-im:generateContent). Do not include a model field in the request body.

Request Body ​

ParameterTypeRequiredDefaultDescription
contentsarrayYes-List of input contents, can contain text and images. See subtables below
generationConfig.responseModalitiesarrayYes["TEXT"]Output modality. Set to ["IMAGE"] for image generation; set to ["TEXT","IMAGE"] to return both text and image
generationConfig.imageConfigobjectNo-Image generation configuration (aspect ratio, resolution, persons, etc.). See subtables below
toolsarrayNo-Tool configuration, e.g., [{ "googleSearch": {} }] to generate images from real-time information online

contents Parameters ​

ParameterTypeRequiredDescription
contents[].rolestringNoMessage role: user / model. Defaults to user when omitted
contents[].partsarrayYesList of content parts, supports text and images. See the parts subtable below

parts Parameters ​

ParameterTypeRequiredDescription
parts[].textstringNoText prompt describing the desired image or the editing instruction
parts[].inline_dataobjectNoInline image data for image editing; use it together with or instead of text
parts[].inline_data.mime_typestringConditionalImage MIME type, e.g., image/png, image/jpeg, image/webp
parts[].inline_data.datastringConditionalBase64-encoded image content (without the data:...;base64, prefix)

imageConfig Parameters ​

ParameterTypeRequiredDefaultDescription
imageConfig.aspectRatiostringNo1:1Aspect ratio of the generated image. See the list below
imageConfig.imageSizestringNo1KOutput image resolution: 1K, 2K, 4K. ge-3.1-fl-im additionally supports 0.5K (512px). K must be uppercase; lowercase values (e.g., 1k) are rejected
imageConfig.personGenerationstringNoPERSON_GENERATION_UNSPECIFIED (default when unspecified)Whether to allow generating images of people. Older models use dont_allow / allow_adult / allow_all; Nano Banana 2.1 and later models use PERSON_GENERATION_UNSPECIFIED / ALLOW_ALL / ALLOW_ADULT / ALLOW_NONE. See the note below

Aspect Ratio (aspectRatio) Values ​

  • ge-3.1-fl-im / ge-3-pr-im / ge-2.5-fl-im: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9
  • ge-3.1-fl-im additionally supports: 1:4, 1:8, 4:1, 8:1

Request Example ​

Text-to-Image ​

Use responseModalities to request image output and generate an image from a text prompt. It is officially recommended to set responseModalities to ["TEXT", "IMAGE"], allowing the model to return accompanying text alongside the image; set it to ["IMAGE"] to return only the image.

bash
curl --location --request POST 'https://neolink.com/api/v1beta/models/<Model ID>:generateContent' \
     --header 'Content-Type: application/json' \
     --header 'Authorization: Bearer <API Key>' \
     --data-raw '{
         "contents": [
             {
                 "parts": [
                     {
                         "text": "A cute orange cat wearing round-framed glasses, sitting by the windowsill reading a newspaper in warm afternoon sunlight"
                     }
                 ]
             }
         ],
         "generationConfig": {
             "responseModalities": ["TEXT", "IMAGE"],
             "imageConfig": {
                 "aspectRatio": "1:1",
                 "imageSize": "2K",
                 "personGeneration": "ALLOW_NONE"
             }
         }
     }'
python
import base64
import requests

url = "https://neolink.com/api/v1beta/models/<Model ID>:generateContent"

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <API Key>",
}

payload = {
    "contents": [
        {
            "parts": [
                {
                    "text": "A cute orange cat wearing round-framed glasses, sitting by the windowsill reading a newspaper in warm afternoon sunlight"
                }
            ]
        }
    ],
    "generationConfig": {
        "responseModalities": ["TEXT", "IMAGE"],
        "imageConfig": {
            "aspectRatio": "1:1",
            "imageSize": "2K",
            "personGeneration": "ALLOW_NONE"
        }
    }
}

resp = requests.post(url, headers=headers, json=payload, timeout=60)
resp.raise_for_status()
data = resp.json()

# Iterate over the returned parts: print text parts, decode and save image parts
for part in data["candidates"][0]["content"]["parts"]:
    if part.get("text"):
        print(part["text"])
    elif "inlineData" in part:
        image = part["inlineData"]["data"]
        with open("output.png", "wb") as f:
            f.write(base64.b64decode(image))

Image Editing (Image-to-Image) ​

In parts, pass a reference image (inline_data) together with the editing instruction text; the model edits the image based on the reference.

Base64 Encoding Note: inline_data.data is the Base64-encoded string of the image file. See the script below:

bash
#!/usr/bin/env bash
set -euo pipefail
IMAGE_PATH="./input.jpg"

if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
    B64FLAGS="--input"
else
    B64FLAGS="-w0"
fi
base64 $B64FLAGS "$IMAGE_PATH" > base64.txt
bash
curl --location --request POST 'https://neolink.com/api/v1beta/models/<Model ID>:generateContent' \
     --header 'Content-Type: application/json' \
     --header 'Authorization: Bearer <API Key>' \
     --data-raw '{
         "contents": [
             {
                 "parts": [
                     {
                         "text": "Replace the background with a seaside sunset, keeping a photorealistic style"
                     },
                     {
                         "inline_data": {
                             "mime_type": "image/jpeg",
                             "data": "<Base64 Code>"
                         }
                     }
                 ]
             }
         ],
         "generationConfig": {
             "responseModalities": ["IMAGE"],
             "imageConfig": {
                 "aspectRatio": "16:9",
                 "personGeneration": "ALLOW_NONE"
             }
         }
     }'
python
import base64
import requests

url = "https://neolink.com/api/v1beta/models/<Model ID>:generateContent"

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <API Key>",
}

# Read and encode the local image
with open("input.jpg", "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "contents": [
        {
            "parts": [
                {
                    "text": "Replace the background with a seaside sunset, keeping a photorealistic style"
                },
                {
                    "inline_data": {
                        "mime_type": "image/jpeg",
                        "data": image_base64
                    }
                }
            ]
        }
    ],
    "generationConfig": {
        "responseModalities": ["IMAGE"],
        "imageConfig": {
            "aspectRatio": "16:9",
            "personGeneration": "ALLOW_NONE"
        }
    }
}

resp = requests.post(url, headers=headers, json=payload, timeout=60)
resp.raise_for_status()
data = resp.json()

# Extract the returned image and save it
for part in data["candidates"][0]["content"]["parts"]:
    if "inlineData" in part:
        image = part["inlineData"]["data"]
        with open("output.png", "wb") as f:
            f.write(base64.b64decode(image))
        break

Multi-turn Image Editing ​

Place the image returned by the model in the previous turn into the conversation history (in the parts of a role: "model" message) to keep editing on top of it, enabling iterative multi-turn refinements.

Note: Multi-turn editing is not supported on ge-3.1-fl-li-im (Nano Banana 2 Lite).

bash
curl --location --request POST 'https://neolink.com/api/v1beta/models/<Model ID>:generateContent' \
     --header 'Content-Type: application/json' \
     --header 'Authorization: Bearer <API Key>' \
     --data-raw '{
         "contents": [
             {
                 "role": "user",
                 "parts": [
                     {
                         "text": "Generate a photo of a living room with a light-colored sofa and floor-to-ceiling windows"
                     }
                 ]
             },
             {
                 "role": "model",
                 "parts": [
                     {
                         "inline_data": {
                             "mime_type": "image/png",
                             "data": "<Base64 of the image generated in the previous turn>"
                         }
                     }
                 ]
             },
             {
                 "role": "user",
                 "parts": [
                     {
                         "text": "Change the sofa to dark blue velvet, keep everything else unchanged"
                     }
                 ]
             }
         ],
         "generationConfig": {
             "responseModalities": ["TEXT", "IMAGE"],
             "imageConfig": {
                 "aspectRatio": "16:9"
             }
         }
     }'
python
import base64
import requests

url = "https://neolink.com/api/v1beta/models/<Model ID>:generateContent"

headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <API Key>",
}


def generate(contents):
    payload = {
        "contents": contents,
        "generationConfig": {
            "responseModalities": ["TEXT", "IMAGE"],
            "imageConfig": {"aspectRatio": "16:9"},
        },
    }
    resp = requests.post(url, headers=headers, json=payload, timeout=60)
    resp.raise_for_status()
    return resp.json()


# Round 1: generate the initial image
contents = [
    {
        "role": "user",
        "parts": [
            {
                "text": "Generate a photo of a living room with a light-colored sofa and floor-to-ceiling windows"
            }
        ],
    }
]
first = generate(contents)
image_part = next(
    p for p in first["candidates"][0]["content"]["parts"] if "inlineData" in p
)

# Round 2: put the model-returned image into the history and keep editing
contents.append({"role": "model", "parts": [image_part]})
contents.append(
    {
        "role": "user",
        "parts": [
            {"text": "Change the sofa to dark blue velvet, keep everything else unchanged"}
        ],
    }
)
second = generate(contents)

for part in second["candidates"][0]["content"]["parts"]:
    if "inlineData" in part:
        with open("output_round2.png", "wb") as f:
            f.write(base64.b64decode(part["inlineData"]["data"]))
        break

Note: The image part in the role: "model" history message must keep the complete inlineData (including mimeType and data) returned in the previous turn. In the Python example, simply append the part object from the response to contents; when using cURL, convert it to snake_case (inline_data, mime_type).

Supported Model IDs ​

  • ge-3.1-fl-im (Nano Banana 2) — Best balance of performance and cost; the recommended image model. Supports up to 4K and 512px output, up to 10 objects / 4 characters for consistency references, Google Search and Image Search grounding, and video-to-image generation
  • ge-3.1-fl-li-im (Nano Banana 2 Lite) — The fastest and cheapest image model. Supports 1K resolution only; no web search or multi-turn editing; up to 14 objects with high fidelity
  • ge-3-pr-im (Nano Banana Pro) — The professional image model, up to 4K, suited for complex instructions and professional asset production. Supports up to 6 objects / 5 characters / 3 style references, interleaved text-and-image output, and web search
  • ge-2.5-fl-im (Nano Banana) — The previous-generation model, fixed 1024px resolution, up to 3 reference images. Recommended to migrate to Nano Banana 2 Lite

<Model ID> should be replaced with the actual model ID, i.e., the name returned by List Models with the models/ prefix removed, e.g., ge-3.1-fl-im. The actual available models, resolutions, and reference image counts depend on the platform.

personGeneration values:

  • Older models (before Nano Banana 2.1): dont_allow, allow_adult, allow_all
  • Nano Banana 2.1 and later models: PERSON_GENERATION_UNSPECIFIED (default), ALLOW_ALL, ALLOW_ADULT, ALLOW_NONE
Older modelsNano Banana 2.1 and laterDescription
dont_allowALLOW_NONEDo not generate people
allow_adultALLOW_ADULTAdults only
allow_allALLOW_ALLAll people, including children
——PERSON_GENERATION_UNSPECIFIED (default)Used when the field is unspecified; the model decides whether to generate people

Response Body ​

ParameterTypeDescription
candidatesarrayList of generated candidates
candidates[].contentobjectContent generated by the model
candidates[].content.rolestringMessage role, always model
candidates[].content.partsarrayList of content parts; contains inlineData for image generation
candidates[].content.parts[].inlineData.mimeTypestringMIME type of the generated image, e.g., image/png
candidates[].content.parts[].inlineData.datastringBase64-encoded data of the generated image
candidates[].finishReasonstringStop reason: STOP (normal) / MAX_TOKENS / SAFETY / RECITATION / IMAGE_SAFETY / PROHIBITED_CONTENT, etc.
usageMetadataobjectToken usage information
usageMetadata.promptTokenCountintNumber of tokens in the input prompt
usageMetadata.candidatesTokenCountintNumber of tokens in the generated response
usageMetadata.totalTokenCountintTotal number of tokens (input + output)
modelVersionstringActual model version used

Response Example ​

json
{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "inlineData": {
              "mimeType": "image/png",
              "data": "<Base64 Code>"
            }
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 11,
    "candidatesTokenCount": 1290,
    "totalTokenCount": 1301
  },
  "modelVersion": "ge-3.1-fl-im"
}

Notes:

  • The returned image data is a Base64-encoded string (inlineData.data field) that must be decoded on the client before use or saving as an image file. See the decoding script in "Image Editing" above.
  • Image models have a built-in Thinking process that is enabled by default to optimize composition before outputting the final image; all generated images carry a SynthID watermark.
  • Enabling Google Search via tools allows generating images from real-time information (ge-3.1-fl-im also supports Google Image Search); this capability is not supported on ge-3.1-fl-li-im.