NanoBanana Pro Edit

Image editing uses the same Gemini API (generateContent) as NanoBanana Pro image generation. You send the original image + edit instruction in the request and receive the edited image in the response. See Gemini docs: Image editing.

Endpoint: Same as generation: POST https://aiberm.com/v1beta/models/gemini-3-pro-image-preview:generateContent.

Key points: Put an image part (inlineData) and a text part (edit instruction) in contents; set generationConfig.responseModalities to ["TEXT", "IMAGE"] to get the edited image; read the result from candidates[0].content.partsinline_data.

Example code

Python uses snake_case; REST/cURL uses camelCase. Same meaning.

1from google import genai
2from google.genai import types
3from PIL import Image
4from io import BytesIO
5 
6base_url = "https://aiberm.com"
7api_key = "YOUR_API_KEY"
8model = "gemini-3-pro-image-preview"
9output_file = "edited.png"
10 
11image_path = "original.png"
12edit_prompt = "Add a stylish top hat to this image, keep the rest unchanged."
13 
14client = genai.Client(
15 api_key=api_key,
16 http_options=types.HttpOptions(api_version="v1beta", base_url=base_url),
17)
18image = Image.open(image_path)
19 
20response = client.models.generate_content(
21 model=model,
22 contents=[edit_prompt, image],
23 config=types.GenerateContentConfig(
24 response_modalities=["TEXT", "IMAGE"],
25 ),
26)
27 
28for part in response.parts:
29 if part.text is not None:
30 print(part.text)
31 elif part.inline_data is not None:
32 Image.open(BytesIO(part.inline_data.data)).save(output_file)
33 print(f"Saved edited image: {output_file}")

Edit vs generate

Generate (NanoBanana Pro)Edit (this page)
contentsText only (describe the image to create)Image + text (describe how to edit)
generationConfig.imageConfigRequired (aspect ratio, 1K/2K/4K)Optional for edit
responseModalities["IMAGE"] or ["TEXT","IMAGE"]Typically ["TEXT","IMAGE"]

Same endpoint and auth; only contents and whether you pass imageConfig differ. For more parameters see NanoBanana Pro.

Multiple images

Put several image parts in contents.parts (one inlineData per image), then one text part with the edit instruction. The model uses all images and the instruction to produce the result (e.g. “compose the subject from the first image onto the background of the second”).

Python: pass multiple image objects and one text in contents.

image1 = Image.open("photo.png")
image2 = Image.open("background.png")
response = client.models.generate_content(
    model=model,
    contents=["Place the person from the first image onto the background of the second.", image1, image2],
    config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"]),
)

cURL: in contents[0].parts, add one inlineData per image, then one text.

"contents": [{
  "parts": [
    { "inlineData": { "mimeType": "image/png", "data": "<BASE64_IMAGE1>" }},
    { "inlineData": { "mimeType": "image/png", "data": "<BASE64_IMAGE2>" }},
    { "text": "Place the person from the first image onto the background of the second." }
  ]
}]

Using an image URL

The API only accepts inlineData (base64) or fileData (via the File API); it does not accept image URLs directly. For images at a URL, download them first and then include them in the request.

Python: download from URL and pass the image to the SDK (the SDK will encode it as needed).

import requests
from io import BytesIO

image_url = "https://example.com/photo.jpg"
resp = requests.get(image_url)
image = Image.open(BytesIO(resp.content))

response = client.models.generate_content(
    model=model,
    contents=["Add a top hat to this image.", image],
    config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"]),
)

cURL: download the image from the URL, convert it to base64, then put the result in inlineData.data.