Bilder automatisch generieren: Templates, Jobs und Webhooks
Die meisten Antworten auf diese Frage sind ein Screenshot von einem Textfeld. Prompt tippen, Knopf drücken, warten, herunterladen, wiederholen. Das ist keine Automatisierung. Das sind Sie, in Handarbeit, nur schneller.
Automatisch heißt: kein Mensch in der Schleife. Eine Datenzeile kommt an, ein Bild kommt heraus, niemand hat zugesehen. Dafür braucht es vier Teile: ein Prompt-Template mit Löchern darin, Daten, die die Löcher füllen, eine Queue, die Arbeit annimmt, ohne zu blockieren, und einen dauerhaften Ort für das Ergebnis. Wir betreiben die API in der Mitte davon und sehen deshalb die Pipelines, die Leute bauen — und die, die drei Wochen nach dem Launch still kaputtgehen.

Der Teil, den Ihnen niemand zuerst sagt: es ist inzwischen günstig
Fangen wir mit der Zahl an, denn sie verändert, was Sie zu bauen bereit sind.
Tausend Bilder über Nano Banana 2 Lite kosten $23.80. Das sind 1.000 × $0.0238, zu unserem Preis vom 26. August 2026. Hunderttausend Produktaufnahmen — ein echter Katalog, jede SKU, jede Farbvariante — sind $2,380.
Dieselben Volumina über die Stufen, zwischen denen Sie wählen würden:
| Bilder | Nano Banana 2 Lite | Nano Banana 2 | Nano Banana Pro |
|---|---|---|---|
| 100 | $2.38 | $4.00 | $7.50 |
| 1.000 | $23.80 | $40.00 | $75.00 |
| 10.000 | $238.00 | $400.00 | $750.00 |
| 100.000 | $2,380.00 | $4,000.00 | $7,500.00 |
Preise und Produktbedingungen können sich ändern. Prüfen Sie vor einer Kaufentscheidung die aktuellen Preise des jeweiligen Anbieters. Die Batch- oder Flex-Preise von Google sind einem standardmäßigen On-Demand-API-Request nicht direkt gleichwertig, da Zeitplanung, Verfügbarkeit und Verarbeitungsbedingungen abweichen; sie sind deshalb von diesem Vergleich ausgenommen. Dies ist ein Vergleich mit klar umrissenem Rahmen und keine Behauptung, dass E2X in jeder Konfiguration die weltweit günstigste Option ist.
Die meisten, die fragen, wie man Bildgenerierung automatisiert, haben sie im Stillen mit „zu teuer zum Ausprobieren“ bepreist. Es ist eine $23.80-Frage. Bauen Sie das Ding.
Schritt 1: Hören Sie auf, Prompts zu schreiben, schreiben Sie ein Template
Ein Prompt, den Sie einmal tippen, ist ein Satz. Ein Prompt, den eine Maschine zehntausendmal ausführt, ist ein Template mit Slots, und dieser Unterschied ist die ganze Aufgabe.
Die Regel: Alles, was variiert, kommt in einen Slot, alles, was identisch bleiben muss, kommt in den festen Text. Ziehen Sie diese Grenze falsch, driftet der Satz — die Hälfte der Bilder auf Weiß, die Hälfte auf Grau, weil „Hintergrund“ in den variablen Teil gesickert ist.
TEMPLATE = (
"Studio-Produktfoto einer {product_name} in {colour}, "
"zentriert vor einem schlichten warmgrauen Hintergrund, weiches gerichtetes Führungslicht "
"von oben links, geringe Schärfentiefe, redaktionelles Katalog-Styling, "
"kein Text, keine Logos, keine Personen"
)
Zwei Slots. Licht, Hintergrund, Bildausschnitt und Ausschlüsse sind eingefroren. Diese eingefrorene Hälfte ist es, die 400 Bilder wie ein einziges Fotoshooting aussehen lässt statt wie 400 Zufälle.
Halten Sie vier Dinge aus der variablen Hälfte heraus: das Medium, die Lichtrichtung, den Hintergrund und die negativen Anweisungen. Das ist Ihre visuelle Identität. Wandert sie pro Zeile, haben Sie keine.

Das Handwerk des Promptens selbst ist ein eigener Text. Für die Automatisierung zählt die Form: fester Rahmen, benannte Löcher, keine Überraschungen.
Schritt 2: Die Daten sind das eigentliche Produkt
Das Template ist trivial. In den Daten steckt die Arbeit, und meistens haben Sie sie bereits.
- Eine Produktkatalog-Tabelle. Eine Zeile pro SKU, Spalten für Name, Farbe, Material, Kategorie.
- Ein CMS-Export von Blogbeiträgen, bei dem Titel und Thema zu den Slots für ein Headerbild pro Artikel werden.
- Zeilen in Ihrer Anwendungsdatenbank — nutzergenerierte Inserate, Event-Seiten, Rezepte.
- Eine Tabelle mit Anzeigenvarianten: sechs Headlines mal vier Hintergründe sind vierundzwanzig Bilder, und die briefft niemand von Hand.
Normalisieren Sie die Quelle, was immer sie ist, in eine Liste von Dictionaries, bevor sie die API berührt, und behalten Sie eine stabile ID auf jeder Zeile. Sie brauchen sie, um Ergebnisse wieder Datensätzen zuzuordnen, und ihr Fehlen schmerzt genau in dem Moment, in dem ein Webhook feuert.
Schritt 3: Einreichen, nicht warten
Unsere API ist mit Absicht asynchron. Sie schicken einen POST, bekommen sofort eine Job-ID zurück, und die Generierung passiert auf unserer Seite.
curl -X POST https://api.e2x.ai/v1/jobs/submit \
-H "Authorization: Bearer $E2X_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google/nano-banana-2-lite/text-to-image",
"input": {
"prompt": "Studio-Produktfoto einer Nussbaum-Schreibtischlampe in Mattschwarz...",
"aspect_ratio": "1:1"
},
"webhookUrl": "https://your-app.example.com/hooks/e2x"
}'
Der Walker, der aus einer Tabelle Jobs macht, ist ungefähr dreißig Zeilen lang. Er liest ein CSV, formatiert das Template pro Zeile, reicht ein und notiert die Job-ID zur Zeilen-ID, damit nichts verwaist.
import csv
import os
import time
import requests
API = "https://api.e2x.ai/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['E2X_API_KEY']}",
"Content-Type": "application/json",
}
TEMPLATE = (
"Studio-Produktfoto einer {product_name} in {colour}, "
"zentriert vor einem schlichten warmgrauen Hintergrund, weiches gerichtetes Führungslicht "
"von oben links, geringe Schärfentiefe, redaktionelles Katalog-Styling, "
"kein Text, keine Logos, keine Personen"
)
MAX_IMAGES = 500 # harte Obergrenze, siehe Kostenabschnitt
UNIT_COST = 0.0238 # Nano Banana 2 Lite, geprüft am 26. August 2026
def submit(row):
body = {
"model": "google/nano-banana-2-lite/text-to-image",
"input": {
"prompt": TEMPLATE.format(**row),
"aspect_ratio": "1:1",
},
"webhookUrl": "https://your-app.example.com/hooks/e2x",
}
for attempt in range(4):
r = requests.post(f"{API}/jobs/submit", json=body, headers=HEADERS, timeout=30)
if r.status_code < 300:
return r.json()["data"]["jobId"]
if r.status_code == 429 or r.status_code >= 500:
time.sleep(2 ** attempt)
continue
raise RuntimeError(f"row {row['id']} rejected: {r.status_code} {r.text}")
raise RuntimeError(f"row {row['id']} still failing after 4 attempts")
with open("catalog.csv") as fh:
rows = list(csv.DictReader(fh))[:MAX_IMAGES]
print(f"submitting {len(rows)} jobs, budget ${len(rows) * UNIT_COST:.2f}")
submitted = {}
for row in rows:
try:
submitted[row["id"]] = submit(row)
except RuntimeError as err:
print(f"skipped: {err}")
print(f"{len(submitted)}/{len(rows)} accepted")
Achten Sie darauf, was diese Schleife nicht tut: aufhören, wenn eine Zeile scheitert. Ein Batch von 500, in dem Zeile 212 eine leere Farbe hat, sollte Ihnen 499 Bilder und einen protokollierten Übersprung liefern — keinen Stacktrace um drei Uhr nachts und null Bilder.
Der Slug zählt mehr, als er aussieht. google/nano-banana-2-lite/text-to-image trägt das Capability-Suffix; der Text-Slug von Nano Banana 2 ist das nackte google/nano-banana-2 ganz ohne. Raten kostet Sie ein 404 auf einer Pipeline, die sonst fertig aussieht. Jedes Modell veröffentlicht seine Parameterliste in einer maschinenlesbaren Spec-Datei.
Schritt 4: Webhook statt Polling, und das ist der Grund
Sie können pollen. GET /v1/jobs/{JOB_ID} liefert pending, processing, completed, failed oder cancelled zurück, und für ein einmaliges Skript ist das in Ordnung.
Für eine Pipeline ist es die falsche Wahl, und der Grund ist keine Eleganzfrage. Polling koppelt die Lebensdauer Ihres Prozesses an den langsamsten Job im Batch. Eine Lite-Generierung läuft bei uns rund 60 Sekunden. Reichen Sie 500 ein, muss der Poller am Leben bleiben und Zustand halten, solange der Nachzügler braucht — durch ein Deployment, einen Container-Neustart, das 15-Minuten-Timeout der Serverless-Plattform, auf der Sie sitzen. Wenn er stirbt, stirbt er mit dem einzigen Verzeichnis darüber, welche Jobs unterwegs waren.
Ein Webhook dreht das um. Sie reichen ein und beenden. Später kommt ein POST mit einem fertigen Job an, und Sie behandeln genau diesen einen Job, zustandslos.
// Express-Handler. Idempotent: dieselbe jobId kann zweimal ankommen.
app.post("/hooks/e2x", express.json(), async (req, res) => {
res.status(200).end(); // erst bestätigen, dann arbeiten
const job = req.body.data;
if (job.status !== "completed") {
await markFailed(job.jobId, job.error?.message ?? "unknown");
return;
}
const already = await findAsset(job.jobId);
if (already) return;
await storeImage(job.jobId, job.outputs[0].url);
});
Pollen Sie, wenn Sie ein Skript von Hand starten und dabei zusehen. Nehmen Sie den Webhook, wenn niemand zusieht — was die Definition von Automatisierung ist.
Schritt 5: Die Output-URL ist temporär, und daran gehen Pipelines kaputt
Das ist der Punkt. Wenn Sie alles andere überfliegen, lesen Sie diesen Abschnitt zweimal.
data.outputs[0].url ist eine Auslieferungs-URL, kein Speicher. Sie funktioniert jetzt. Sie funktioniert nicht für immer. Alles, was sie als dauerhaft behandelt — eine Spalte product_image_url, ein CMS-Feld, ein Link in einer Mail an den Kunden — rendert in Staging tadellos und zeigt vierzehn Tage später kaputte Bildsymbole.
Der Fehler ist gemein, weil er verzögert eintritt. Beim Schreiben knallt es nicht. Tests laufen durch. Der Batch meldet 500 Erfolge. Dann verschwinden Bilder, angefangen bei den ältesten Datensätzen, und wenn es jemand merkt, können Sie sie nicht neu erzeugen, ohne den ganzen Job noch einmal zu fahren — denn die Prompts wurden auch nie gespeichert.
Laden Sie die Bytes herunter. Legen Sie sie in Ihren eigenen Bucket. Speichern Sie Ihre URL.

import requests
import boto3
s3 = boto3.client("s3")
def store_image(job_id, row_id, source_url):
img = requests.get(source_url, timeout=60)
img.raise_for_status()
key = f"products/{row_id}.jpg"
s3.put_object(
Bucket="my-assets",
Key=key,
Body=img.content,
ContentType=img.headers.get("content-type", "image/jpeg"),
)
return f"https://cdn.example.com/{key}"
Wenn Sie schon dabei sind: Speichern Sie den Prompt neben dem Bild. Eine Textspalte, und sie ist der Unterschied zwischen „generiere diese Variante neu“ und „fang von vorn an“.
Zwei weitere Gewohnheiten, die sich ab Tag eins lohnen. Prüfen Sie, ob der Download tatsächlich Bild-Bytes geliefert hat und keine Fehlerseite, denn ein 200 mit HTML darin schreibt sich bereitwillig in Ihren Bucket. Und schlüsseln Sie die Ablage nach Ihrer Zeilen-ID, nicht nach unserer Job-ID, damit eine Neugenerierung das richtige Objekt überschreibt, statt es zu verwaisen.
Schritt 6: Was bei Volumen tatsächlich schiefgeht
Kleine Batches verbergen alles. Was ab ein paar hundert auftaucht:
Unvollständige Batches sind normal. Ein Bruchteil jedes großen Laufs scheitert — ein Prompt, der über einen Content-Filter stolpert, eine kaputte Zeile, ein vorübergehender Upstream-Fehler. Behandeln Sie 497 von 500 als Erfolgsfall und geben Sie sich einen Ein-Befehl-Retry über genau diese drei Zeilen.
Retries brauchen eine Ausgabendecke. Eine Retry-Schleife ohne Deckel ist ein Bug, der Rechnungen schreibt. $0.0238 pro Schuss klingt harmlos, bis eine festhängende Schleife ihn vierzigtausendmal auslöst. Setzen Sie eine harte Obergrenze in den Code — die Zeile MAX_IMAGES oben ist hier die billigste Versicherung.
Idempotenz ist nicht optional. Webhooks können mehr als einmal zugestellt werden. Ein Handler, der nicht gefahrlos zweimal auf derselben Job-ID laufen kann, liefert Ihnen doppelte Assets und doppelte Zeilen, und Sie merken es in der vollsten Woche.
Kosten brauchen einen laufenden Zähler, keine Monatsrechnung. Geldbeträge kommen in unserer API in Mikro-Cent zurück — 1.000.000 sind $1. Summieren Sie sie pro Batch und protokollieren Sie die Summe beim Abschluss. Eine Pipeline, die jede Nacht „412 Bilder, $9.81“ meldet, ist eine, die niemand prüfen muss.
Die Defaults für Aspect Ratio werden Sie überraschen. Lite steht per Default auf 1:1, Nano Banana 2 und Pro dagegen auf 9:16. Pinnen Sie ihn im Template, sonst wird Ihr halber Katalog stillschweigend hochkant.
Das Watermark reist mit der Datei. Google stempelt SynthID in alles, was seine Bildmodelle produzieren. Es ist unsichtbar, es ist kein Flag, und es überlebt, was Ihre Pipeline danach mit den Bytes anstellt. Wer bei Ihnen Marke oder Recht verantwortet, sollte KI-generierte Assets abnehmen, bevor die Pipeline existiert — und nicht, nachdem sie 20.000 Objekte in einen Bucket geschrieben hat.

Auf welches Modell die Pipeline zeigen sollte
Per Default auf Nano Banana 2 Lite, und weg davon nur, wenn etwas Konkretes Sie dazu zwingt.
Das ist Arithmetik, keine Ausflucht. Zu $0.0238 ist es das günstigste, was wir verkaufen, das ein Bild macht, eine ganze Generation neuer als das ursprüngliche Nano Banana, das es ersetzt hat, und bei Pipeline-Volumen wächst die Preislücke zu der einen Zahl an, auf die die Buchhaltung schaut. Dazu trägt es vier Aspect Ratios, die sonst nichts hat — 1:4, 4:1, 1:8 und 8:1 — genau das, was Sie wollen, wenn am Ende Banner und vertikale Leisten stehen. Eine Eigenheit: überhaupt kein resolution-Parameter, und einen zu schicken ist ein Fehler, kein stiller No-op.
Routen Sie in diesen vier Fällen daran vorbei, und sonst nicht:
- Ausgabe über 1K. Lite kann nur 1K. Nano Banana 2 reicht bis 4K bei $0.04 Basis, mit ×1,5 für 2K und ×2 für 4K.
- Lesbarer Text im Bild. Produktkarten mit Preisen, lokalisierte Infografiken. Das wohnt auf Nano Banana Pro zu $0.075, wo 1K und 2K dasselbe kosten — nehmen Sie die 2K, sie sind geschenkt.
- Transparente Hintergründe. Freisteller und Stickerbögen brauchen
background: transparent, und GPT Image 2 ist das einzige Modell in unserem Katalog, das das in einem Call kann. Kalkulieren Sie $0.0525 bei 1K, nicht die rohe Katalogzahl —qualitymultipliziert auf jeder Stufe mit 7. - Dasselbe Gesicht oder dieselbe Flasche über viele Frames. Ein Referenzbild-Problem, kein Volumenproblem, mit einem eigenen Text zur Konsistenz.
Bei gemischten Workloads fahren Sie die Masse auf Lite und zweigen die 2 %, die Text oder Detailtreue brauchen, über eine Spalte in Ihren Daten auf Pro ab. Eine Pipeline, zwei Modelle, Pro-Preise nur dort, wo sie etwas einbringen.
Den Parameter-für-Parameter-Durchgang durch den Submit- und Poll-Vertrag finden Sie im Tutorial zur Nano Banana Pro API, die Aufschlüsselung Stufe für Stufe im Modellvergleich. Beide setzen voraus, dass Sie ein Modell schon gewählt haben. Falls nicht: die text-to-image-Modelle sind mit ihren Preisen gelistet, und der Katalog nimmt die Videoseite dazu.
Das Ganze, der Reihe nach
Template mit Slots. Daten mit stabilen IDs. Als Jobs einreichen, unter einer harten Obergrenze. Webhook nehmen. Die Bytes in den eigenen Speicher laden. Fehler und Ausgaben protokollieren. Sechs Schritte, keiner davon schwer, und übersprungen wird immer Schritt fünf.
Häufig gestellte Fragen
Wie generiert man ein Bild automatisch?
Schreiben Sie Ihren Prompt als Template mit benannten Slots, füllen Sie diese Slots aus einer Datenquelle wie einem Produktkatalog oder einem CSV, und reichen Sie jeden gefüllten Prompt als asynchronen Job bei einer Bild-API ein. Nehmen Sie das Ergebnis über einen Webhook statt über Polling und laden Sie die Bild-Bytes anschließend in Ihren eigenen Speicher. Nichts in dieser Schleife braucht einen Menschen — genau das macht sie automatisch statt nur zu schneller Handarbeit.
Was kostet es, 1.000 Bilder automatisch zu generieren?
Zu E2X-Preisen vom 26. August 2026 sind 1.000 Bilder über Nano Banana 2 Lite $23.80, denn jeder Request kostet $0.0238. Dasselbe Volumen sind $40.00 auf Nano Banana 2 und $75.00 auf Nano Banana Pro. Höhere Auflösungen multiplizieren obendrauf, aber für Standard-1K-Ausgabe ist die Zahl pro Bild die ganze Rechnung.
Sollte ich für Bildgenerierungs-Jobs einen Webhook nehmen oder pollen?
Nehmen Sie einen Webhook für alles, was unbeaufsichtigt läuft. Polling bindet die Lebensdauer Ihres Prozesses an den langsamsten Job im Batch, ein Deployment oder ein Serverless-Timeout tötet also den Poller, während er das einzige Verzeichnis der noch laufenden Jobs hält. Ein Webhook lässt Sie einreichen und beenden und dann jeden fertigen Job zustandslos behandeln. Polling ist in Ordnung für ein Skript, bei dem Sie zusehen.
Warum laden meine generierten Bilder nach einer Weile nicht mehr?
Weil Sie die Output-URL der API gespeichert haben statt des Bildes. Diese URL ist temporäre Auslieferung, kein Speicher, eine Spalte, die sie hält, rendert also anfangs korrekt und bricht später. Laden Sie die Bytes herunter, sobald der Job fertig ist, schreiben Sie sie in Ihren eigenen Bucket und speichern Sie Ihre eigene URL. Das ist der häufigste Weg, auf dem eine Bild-Pipeline kaputt in Produktion geht.
Auf welches Modell sollte eine automatisierte Bild-Pipeline per Default zeigen?
Auf Nano Banana 2 Lite, zu $0.0238 pro Bild. Es ist das günstigste Bildmodell in unserem Katalog und eine Generation neuer als das ursprüngliche Nano Banana, und bei Batch-Volumen dominiert der Preis jede andere Erwägung. Wechseln Sie auf Nano Banana 2 nur für Ausgabe über 1K, auf Nano Banana Pro nur für lesbaren Text im Bild und auf GPT Image 2 nur für transparente Hintergründe.
Was passiert, wenn einzelne Bilder in einem Batch scheitern?
Ein paar tun es immer, und die Pipeline sollte das als normal behandeln und nicht als fatal. Reichen Sie nach einer abgelehnten Zeile weiter ein, protokollieren Sie gescheiterte IDs samt Fehler und bauen Sie einen Retry-Pfad, der nur die Fehlschläge fährt. Deckeln Sie die Versuche, denn jeder einzelne ist eine echte Abbuchung.