# Nano Banana Pro API: Python-Tutorial, Bildbearbeitung und Preis

> Nano Banana Pro aus Python aufrufen: Modell-ID, Felder für image_size und input.image, die 4K-Option, Googles Preis pro Bild und das JSON jeder Antwort.

- Canonical HTML: https://omniakey.com/de/blog/nano-banana-pro-api
- Markdown: https://omniakey.com/de/blog/nano-banana-pro-api.md
- Published: 2026-11-03 (updated 2026-11-03)
- Author: Kiki, COO at OmniaKey
- Language: de
- Category: API setup
- Reading time: 9 min
- All posts: https://omniakey.com/blog/llms.txt

---

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-image` ist Googles GA-Modell-ID. Die Vertex-Modellkarte nennt als Veröffentlichungsdatum den 28. Mai 2026.
- **Aufruf:** Schicke `POST https://api.omniakey.com/v1/media/tasks` mit einem `Idempotency-Key`, frage `GET /v1/media/tasks/{id}` ab, bis der Status succeeded ist, und lade dann `assets[0].url` herunter.
- **Parameter:** `parameters.aspect_ratio` und `parameters.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 in `input.image` als `{data, mime_type}` ab.

Die [Modellseite von Nano Banana Pro](https://omniakey.com/de/gemini-3-pro-image) 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](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image) 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](https://docs.omniakey.com/en/media/image) bei OmniaKey beschreibt `gemini-3-pro-image-preview` als "Same model, -preview snapshot id", zum gleichen Preis pro Aufruf.

Du brauchst zwei Dinge:

1. Einen OmniaKey-API-Key, exportiert, damit das Skript ihn lesen kann: `export OMNIAKEY_API_KEY="your-key"`.
2. 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`.

```python
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](https://docs.omniakey.com/en/media/overview) bei OmniaKey beschreibt den ganzen Ablauf; die fertige Aufgabe trägt diese Felder:

```json
{
  "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 dunkles Metallschild an einer Ziegelwand mit drei Zeilen chinesischem Text und einer Telefonnummer](https://omniakey.com/_img/blog/nano-banana-pro-api/g2-sign.7e3e8e4d.1600.webp)

_2K, 1:1: 2048x2048 in 47.2 s. Alle drei chinesischen Zeilen und 010-6789 4321 kamen korrekt zurück; Rost verdeckt einen Teil der ersten 0._

## 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:

```python
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:

```json
{
  "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:

![Das Nachtzug-Poster in einem schwarzen Rahmen an einer Wand, mit Bildlampe darüber und einer Pflanze rechts](https://omniakey.com/_img/blog/nano-banana-pro-api/g3-edit.98011b5c.1600.webp)

_2K, Bearbeitung 1:1: 2048x2048 in 49.9 s. Text und Design des Posters blieben erhalten; der Rahmen ist ein sauberes Rechteck._

## 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.

![Das Nachtzug-Poster in 1K: Dampfzug auf einer Steinbrücke, verschneite Berge und ein tiefblauer Himmel](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-1k.12bc0ed0.896.webp)

_1K, 3:4: 896x1200 in 28.4 s. Alle vier Posterzeilen stimmen; Lampen und Treibstangen der Lokomotive drängen sich._

![Dasselbe Nachtzug-Poster in 2K, mit einem Dorf und zwei Kirchtürmen am rechten Hang](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-2k.38a932bb.1600.webp)

_2K, 3:4: 1792x2400 in 48.2 s. Gleicher Text, dazu ein Dorf und zwei Türmchen am rechten Hang._

![Dasselbe Nachtzug-Poster in 4K, mit drei Wagen und Tender hinter der Lokomotive](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-4k.6c8048ad.1600.webp)

_4K, 3:4: 3584x4800 in 66.9 s. Drei Wagen und der Tender sind gezeichnet; die Ziegelfugen fallen unterschiedlich dick aus._

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:

```text
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:

```text
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](https://omniakey.com/de/gemini-3-pro-image), 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](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image) — geprüft am 3. November 2026.
- [Google: Leitfaden zur Bildgenerierung mit der Gemini API](https://ai.google.dev/gemini-api/docs/image-generation) — geprüft am 3. November 2026.
- [Google: Preise der Gemini API](https://ai.google.dev/gemini-api/docs/pricing) — geprüft am 3. November 2026.
- [Google: Ankündigung von Nano Banana Pro](https://blog.google/technology/ai/nano-banana-pro/) — geprüft am 3. November 2026.

## Änderungsverlauf

- 2026-11-03: Erste Fassung; fünf Testaufrufe an dem Tag über OmniaKey.
