Nano Banana Pro API: Python-Tutorial, Bildbearbeitung und Preis
Ein POST, ein Poll, ein Download: ein Nano-Banana-Pro-Skript, das läuft.

Auf dieser Seite
- Kurze Antwort
- Modell-ID und was du brauchst
- Das Python-Skript
- Ein vorhandenes Bild bearbeiten
- 1K, 2K und 4K: was jedes Format bringt
- Fehler, die dir begegnen
- Häufige Fragen
- Welche Modell-ID hat die Nano Banana Pro API?
- Was kostet ein Bild mit Nano Banana Pro?
- Kann Nano Banana Pro chinesischen Text zeichnen?
- Soll ich 1K, 2K oder 4K anfordern?
- Warum kam meine Bearbeitung mit 400 invalid_request zurück?
- Geprüfte Quellen
- Änderungsverlauf
Nano Banana Pro ist Googles gemini-3-pro-image, und in OmniaKey rufst du es mit einem einzigen POST /v1/media/tasks auf. Unsere drei Tests im Format 3:4 kamen mit 896x1200, 1792x2400 und 3584x4800 zurück, und jedes Wort auf dem Poster war richtig geschrieben.
Kurze Antwort
- Modell:
gemini-3-pro-imageist Googles GA-Modell-ID. Die Vertex-Modellkarte nennt als Veröffentlichungsdatum den 28. Mai 2026. - Aufruf: Schicke
POST https://api.omniakey.com/v1/media/tasksmit einemIdempotency-Key, frageGET /v1/media/tasks/{id}ab, bis der Status succeeded ist, und lade dannassets[0].urlherunter. - Parameter:
parameters.aspect_ratioundparameters.image_size; die Größenwerte sind 1K, 2K und 4K, mit großem K. - Limit pro Anfrage: 1 MiB für den ganzen Body, inklusive der Base64-Bilddaten darin.
- Googles Preis: $0.134 pro 1K/2K-Bild und $0.24 pro 4K-Bild, von der Preisseite der Gemini-API.
- Unsere Token-Zahlen: Die drei Aufgaben meldeten 1,133, 1,225 und 2,480 Ausgabe-Token. Bei $120 pro Million Bild-Token sind das $0.136, $0.147 und $0.298.
- Bearbeiten: Nutze
operation: "edit"und lege das Ausgangsbild ininput.imageals{data, mime_type}ab.
Die Modellseite von Nano Banana Pro bei OmniaKey nimmt auch gemini-3-pro-image-preview an, die ältere Snapshot-ID, zum gleichen Preis.
Modell-ID und was du brauchst
In deinen Code gehört gemini-3-pro-image. Googles Vertex-Modellkarte führt es mit Launch-Phase GA und dem Datum 28. Mai 2026. Unterstützt werden Ausgaben in 1K, 2K und 4K.
Die -preview-ID zeigt auf dasselbe Modell. Die Tabelle der Bildmodelle bei OmniaKey beschreibt gemini-3-pro-image-preview als "Same model, -preview snapshot id", zum gleichen Preis pro Aufruf.
Du brauchst zwei Dinge:
- Einen OmniaKey-API-Key, exportiert, damit das Skript ihn lesen kann:
export OMNIAKEY_API_KEY="your-key". - Python 3. Das Skript unten nutzt nur die Standardbibliothek: urllib, json, time, uuid, base64 und pathlib. Es ist kein SDK zu installieren.
Das Python-Skript
Drei Schritte: Aufgabe anlegen, abfragen, Bild herunterladen. Speichere das Ganze als nano_banana.py und starte es mit python3 nano_banana.py.
import base64
import json
import os
import time
import urllib.request
import uuid
from pathlib import Path
API = "https://api.omniakey.com/v1/media/tasks"
HEADERS = {
"Authorization": f"Bearer {os.environ['OMNIAKEY_API_KEY']}",
"Content-Type": "application/json",
}
def call(url, payload=None, headers=None, method=None):
body = json.dumps(payload).encode() if payload is not None else None
req = urllib.request.Request(url, data=body, headers=headers or HEADERS, method=method)
with urllib.request.urlopen(req, timeout=60) as resp:
return resp.status, json.loads(resp.read())
def create_task(prompt, aspect_ratio="3:4", image_size="2K", image_path=None):
body = {
"model": "gemini-3-pro-image",
"type": "image",
"operation": "generate" if image_path is None else "edit",
"input": {"prompt": prompt},
"parameters": {"aspect_ratio": aspect_ratio, "image_size": image_size},
}
if image_path:
encoded = base64.b64encode(Path(image_path).read_bytes()).decode("utf-8")
body["input"]["image"] = {"data": encoded, "mime_type": "image/png"}
headers = {**HEADERS, "Idempotency-Key": str(uuid.uuid4())}
status, task = call(API, body, headers, "POST")
print("created", task["id"], "HTTP", status)
return task
def wait(task_id, interval=3, timeout=300):
deadline = time.time() + timeout
while time.time() < deadline:
_, task = call(f"{API}/{task_id}")
print(task["status"], task["progress"]["percent"])
if task["status"] in ("succeeded", "failed", "canceled"):
return task
time.sleep(interval)
# A timeout is not a failure: keep the task id and poll it again.
raise TimeoutError(f"task {task_id} is still running")
def download(task, out_path):
asset = task["assets"][0]
with urllib.request.urlopen(asset["url"], timeout=120) as resp:
Path(out_path).write_bytes(resp.read())
print("saved", out_path, asset["mime_type"], asset["byte_size"], "bytes")
if __name__ == "__main__":
task = create_task(
"A vintage travel poster for the Night Train from Zürich to Milano, "
"departing 21:40 from platform 7. A steam train crosses a stone arch "
"bridge below snowy mountains under a deep blue night sky, with a cream "
"border. Spell every word exactly as written.",
aspect_ratio="3:4",
image_size="2K",
)
task = wait(task["id"])
if task["status"] != "succeeded":
raise SystemExit(f"{task['status']}: {task.get('error')}")
download(task, "night-train.jpg")
image_size akzeptiert 1K, 2K oder 4K. Googles Bildleitfaden ist eindeutig: "You must use an uppercase 'K' … Lowercase parameters (e.g., 1k) will be rejected." Schicke 2K, nicht 2k.
Idempotency-Key ist Pflicht. Ein frisches UUID pro Anfrage ist die einfache Regel; verwende einen Key nur wieder, wenn du genau denselben Body erneut sendest. OmniaKey gibt dann die ursprüngliche Aufgabe mit HTTP 200 zurück, statt doppelt abzurechnen, und antwortet mit 409, wenn derselbe Key mit einem anderen Body ankommt.
Der Aufruf zum Anlegen liefert 202 mit einer id. Die Doku zu Media-Tasks bei OmniaKey beschreibt den ganzen Ablauf; die fertige Aufgabe trägt diese Felder:
{
"id": "task_AbMRVqzSnVh0VwBj0S7NuMUxy5sZtfHP",
"status": "succeeded",
"progress": {"percent": 100, "stage": "completed"},
"usage": {"total_tokens": 1133},
"assets": [
{
"kind": "image",
"mime_type": "…",
"url": "https://…signed-url…"
}
]
}
Lies assets[0].url und lade sofort herunter: Der signierte Link gilt etwa eine Stunde, der Task-Datensatz bleibt 24 Stunden. Das Feld mime_type nennt das Format; Gemini-Modelle liefern meist JPEG.
Dasselbe Skript mit 1:1 und 2K und einem chinesischen Schild als Prompt lieferte das:

Ein vorhandenes Bild bearbeiten
Setze operation: "edit" und übergib das Ausgangsbild in input.image als {data, mime_type}. Das Skript oben macht das schon, sobald du ihm einen image_path gibst:
task = create_task(
"Hang this poster in a thin black frame on a warm white wall, with a brass "
"picture light above it, a low wooden cabinet below and a trailing plant on "
"the right. Keep the poster exactly as it is.",
aspect_ratio="1:1",
image_size="2K",
image_path="night-train-2k.png",
)
Der Body, der dabei rausgeht, sieht so aus:
{
"model": "gemini-3-pro-image",
"type": "image",
"operation": "edit",
"input": {
"prompt": "Hang this poster in a thin black frame on a warm white wall…",
"image": {"data": "…base64…", "mime_type": "image/png"}
},
"parameters": {"aspect_ratio": "1:1", "image_size": "2K"}
}
Die Vorlage im Beispiel ist ein PNG, deshalb schreibt das Skript image/png; bei einem JPEG änderst du dieses Label. Für mehrere Vorlagen nutzt du input.images und gibst jedem Eintrag dieselbe Form {data, mime_type}. Googles Leitfaden nennt 14 Referenzbilder als Obergrenze; bei gemini-3-pro-image verteilt sich das auf 6 Objektbilder, 5 Charakterbilder und 3 Stilreferenzen.
Halte den Body unter 1 MiB. Base64 macht die Datei etwa ein Drittel größer, also verkleinere oder komprimiere die Vorlage vor dem Kodieren. Unsere Bearbeitung nutzte das 2K-Poster und behielt jedes Wort und das Layout:

1K, 2K und 4K: was jedes Format bringt
Wir haben denselben 3:4-Prompt in allen drei Größen laufen lassen. Die Pixelmaße passten exakt zu Googles Tabelle für 3:4: 896x1200 bei 1K, 1792x2400 bei 2K und 3584x4800 bei 4K. Der Postertext war in jeder Größe korrekt.



Mit der Größe ändert sich das Detail, nicht die Rechtschreibung:
- 1K: Die Zugfront ist gedrängt: Lampen, Räder und Treibstangen sitzen dicht beieinander.
- 2K: Am rechten Hang erscheinen das Dorf und seine zwei Türmchen, der Schornstein bekommt einen blassen Rauchfaden, die Brücke zeigt sieben Bögen.
- 4K: Die drei Wagen und der Tender sind getrennt, und das Mauerwerk zeigt Fugen unterschiedlicher Dicke. Die Mechanik unter der Lokomotive bleibt vereinfacht.
Die Zeit wuchs mit der Größe: 28.4 s, 48.2 s und 66.9 s. Jede Größe lief einmal, lies diese Sekunden also als einen einzelnen Durchlauf.
Google rechnet Bildausgabe mit $120 pro Million Token ab, und seine Tabelle nennt 1,120 Token für 1K und 2K sowie 2,000 Token für 4K. Daraus folgt Googles eigene Schätzung:
1,120 × $120 ÷ 1,000,000 = $0.134 per 1K image
1,120 × $120 ÷ 1,000,000 = $0.134 per 2K image
2,000 × $120 ÷ 1,000,000 = $0.24 per 4K image
Unsere Aufgaben meldeten mehr Token als Googles Beispiele. Hier dieselbe Rechnung mit unseren Zahlen:
1,133 × $120 ÷ 1,000,000 = $0.136 per 1K image
1,225 × $120 ÷ 1,000,000 = $0.147 per 2K image
2,480 × $120 ÷ 1,000,000 = $0.298 per 4K image
| Größe | Pixel, 3:4 | Unsere Zeit | Unsere Token | Googles Schätzung |
|---|---|---|---|---|
| 1K | 896x1200 | 28.4 s | 1,133 | $0.134 |
| 2K | 1792x2400 | 48.2 s | 1,225 | $0.134 |
| 4K | 3584x4800 | 66.9 s | 2,480 | $0.24 |
OmniaKey rechnet einen Bildaufruf pauschal ab, nicht nach Token, deshalb bewegt sich der Betrag nicht mit diesen Zahlen; die aktuelle Rate pro Aufruf steht auf der Modellseite, und eine fehlgeschlagene Aufgabe wird erstattet. Googles Schätzung nach Token-Rate liegt für dieselben drei Bilder bei $0.134, $0.134 und $0.24.
Fehler, die dir begegnen
Die Fehlschläge hier laufen fast immer auf einen Feldnamen oder eine Dateigröße hinaus, nicht aufs Modell. Diese listet die Media-Doku von OmniaKey für diesen Endpunkt:
| HTTP | Code oder Status | Was er bedeutet | Was zu tun ist |
|---|---|---|---|
| 400 | invalid_request | Fehlerhafter Body, nicht unterstützte Operation oder falscher Parameter | JSON und die Feldnamen unten prüfen |
| 503 | no_available_channel | Kein Kanal bedient dieses Modell gerade | Modell wechseln; erneutes Senden hilft nicht |
| — | failed | Die Aufgabe endete ohne Ergebnis | error.code und error.message lesen |
Eine fehlgeschlagene Aufgabe ist kein HTTP-Fehler: Der Aufruf zum Anlegen war erfolgreich, also fragst du die Aufgabe ab und liest ihr error-Objekt. Fehlgeschlagene und abgebrochene Aufgaben werden automatisch erstattet.
Eine Vorlage in voller Auflösung als Base64 kann den Body über 1 MiB schieben. Verkleinere zuerst und prüfe die kodierte Länge, nicht nur die Dateigröße.
Googles Leitfaden lehnt ein kleines 1k ab. Nutze 1K, 2K oder 4K.
Die Bild-Doku von OmniaKey lehnt bei Gemini-Modellen außerdem size und ein mime_type auf oberster Ebene ab, weil das keine Gemini-Parameter sind. Nutze stattdessen parameters.aspect_ratio und parameters.image_size und lies das Ausgabeformat aus dem Feld mime_type der Antwort.
Häufige Fragen
Welche Modell-ID hat die Nano Banana Pro API?
gemini-3-pro-image. Googles Vertex-Modellkarte führt es als GA mit Veröffentlichungsdatum 28. Mai 2026, und OmniaKey nimmt dieselbe ID an. Die ältere ID gemini-3-pro-image-preview funktioniert bei OmniaKey weiter und zeigt auf dasselbe Modell.
Was kostet ein Bild mit Nano Banana Pro?
Google schätzt $0.134 für ein 1K- oder 2K-Bild und $0.24 für ein 4K-Bild, bei $120 pro Million Bild-Token. Unsere Aufgaben meldeten 1,133, 1,225 und 2,480 Token, das sind zu dieser Rate $0.136, $0.147 und $0.298. OmniaKey nennt auf der Modellseite seine eigene Rate pro Aufruf.
Kann Nano Banana Pro chinesischen Text zeichnen?
Ja. Unser 2K-Schild kam mit drei korrekten chinesischen Zeilen zurück — 同福客栈, 住宿 餐饮 茶水 und 010-6789 4321 — samt aller 11 Ziffern und dem Bindestrich.
Soll ich 1K, 2K oder 4K anfordern?
Für ein Poster wie unseres ist 2K die brauchbare Mitte. Alle drei Größen schrieben unser Poster richtig, 4K kauft also feinere Details — getrennte Wagen, sichtbare Ziegelfugen — statt besserem Text. Für Entwürfe, bei denen 896x1200 reicht, nimm 1K.
Warum kam meine Bearbeitung mit 400 invalid_request zurück?
Die üblichen Ursachen sind ein Body über 1 MiB, die Vorlage im falschen Feld oder ein Gemini-Modell, das size oder ein mime_type auf oberster Ebene bekommt. Lege das Bild in input.image als {data, mime_type} ab, halte den kodierten Body unter 1 MiB und nutze aspect_ratio und image_size.
Geprüfte Quellen
- Google Cloud: Modellkarte Gemini 3 Pro Image — geprüft am 3. November 2026.
- Google: Leitfaden zur Bildgenerierung mit der Gemini API — geprüft am 3. November 2026.
- Google: Preise der Gemini API — geprüft am 3. November 2026.
- Google: Ankündigung von Nano Banana Pro — geprüft am 3. November 2026.
Änderungsverlauf
- 2026-11-03: Erste Fassung; fünf Testaufrufe an dem Tag über OmniaKey.
Modelle in diesem Artikel
Verwandte Artikel
Nano Banana 2.1 im Test: API-Zugriff, Preise und Umstieg
Nano Banana 2.1 mit Nano Banana 2 vergleichen und unterstützte Bildjobs direkt über OmniaKey erstellen.
Nano Banana Produktfotos: 8 Prompts im Test
Acht Prompts, 22 Bearbeitungen, zwei Modelle: welche Aufnahmen das Label behielten, wo der Schuh gespiegelt wurde und welches Modell zu welcher Aufgabe passt.
Seedream 5.0 Pro vs Nano Banana Pro: Test mit gleichem Prompt und Preis
Fünf gleiche Prompts, zwei Modelle, gemessene Zeiten und der Preis pro 2K-Bild.
