Nano Banana Pro API'si Nasıl Çağrılır: Baştan Sona Anlatım
Bu, E2X API'sinde Nano Banana Pro için entegrasyonun tamamı, baştan sona. Bir key alın, bir job gönderin, response'u okuyun, düzgün biçimde bekleyin, patlama biçimlerini karşılayın ve byte'ları yarın da orada olacak bir yere koyun.
İnsanları yakalayan son adım. Zaten görsel üretiyorsanız ve yalnızca sizinkilerin neden kaybolduğunu öğrenmek istiyorsanız oraya atlayın.

Pro'nun sizin işiniz için doğru katman olup olmadığı ayrı bir soru ve onu ayrıca fiyat ve hız yazısında cevapladık. Kısa hâli: request başına $0.075, kabaca 30 saniye; görselleriniz okunabilir metin taşıyorsa ya da farklı roller oynayan referansları birleştiriyorsa değer. Bu sayfa karar verdiğinizi varsayıyor.
İlk request'ten önce gerekenler
Dört şey ve üçü birer satır.
- Bir API key. E2X hesabınızdan bir tane oluşturun. Aşağıdaki her şey onu
Authorization: Bearer $E2X_API_KEYolarak gönderiyor. Sunucu tarafında tutun. Tarayıcı JavaScript'indeki bir key, artık başkasının harcadığı bir key demektir. - Base URL, ki katalogdaki her model için
https://api.e2x.ai/v1. - Doğru slug. Üretim
google/nano-banana-pro/text-to-image. Düzenlemegoogle/nano-banana-pro/edit-image. O string'ler request gövdesine harfi harfine giriyor ve üzerlerinde bulanık eşleştirme yok. - Göndermeye değer bir prompt. Pro, üzerine hareket edecek daha çok alanı olduğu için spesifikliği flash katmanlarından fazla ödüllendiriyor. "Bir kedi ama sinematik"ten daha derine inmek isterseniz ayrı bir prompt rehberimiz var.
Kontrat asenkron. Bir job gönderiyorsunuz, bir ID alıyorsunuz ve görsel sonra geliyor. Pikseller hazır olana kadar bloklayan senkron bir endpoint yok; Pro'nun kabaca 30 saniye sürdüğü düşünülürse zaten istemezdiniz.
İlk text-to-image request'iniz
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-pro/text-to-image",
"input": {
"prompt": "Mermer bir kahve tezgâhının arkasında elle yazılmış tebeşir tahtası menü, soldaki pencereden sıcak öğleden sonra ışığı, sığ alan derinliği",
"aspect_ratio": "16:9",
"resolution": "2k"
}
}'
Aynısının Python hâli:
import os
import requests
BASE = "https://api.e2x.ai/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['E2X_API_KEY']}"}
def submit(prompt, aspect_ratio="16:9", resolution="2k"):
r = requests.post(
f"{BASE}/jobs/submit",
headers=HEADERS,
json={
"model": "google/nano-banana-pro/text-to-image",
"input": {
"prompt": prompt,
"aspect_ratio": aspect_ratio,
"resolution": resolution,
},
},
timeout=30,
)
r.raise_for_status()
return r.json()["data"]["jobId"]
İki örnek de aspect_ratio ve resolution'ı bilerek sabitliyor ve onları düşürmeden önce iki varsayılanı da anlamakta fayda var.
aspect_ratio varsayılanı 9:16. 1:1 değil. Onu dışarıda bırakırsanız ürettiğiniz her görsel sonsuza kadar portre olur ve bunu, düzeninizdeki geniş bir alan yanlış görünene kadar fark etmezsiniz. API'mizde bu alan diğer bütün alanlardan fazla entegrasyonu tökezletiyor. Sabitleyin.
resolution değerleri küçük harfli. 1k, 2k, 4k. Büyük harfli 2K aynı string değil ve API bunu size söyleyecek.
Bu slug'da 1k'yı ölü bir değer sayın. İlk iki ayar tek bir düz ücrette duruyor — ikisi için de $0.075, 26 Ağustos 2026'da kontrol edildi — dolayısıyla küçük olan aynı fatura satırına karşılık daha az piksel döndürüyor. Rakamı yalnızca 4k oynatıyor: $0.15, tavan 4096×4096.

Geri gelen ne
Submit çağrısı anında bir job zarfıyla dönüyor. İhtiyacınız olan alan data.jobId:
{
"success": true,
"data": {
"jobId": "job_8Kd2mQvXpL",
"status": "pending"
}
}
Status pending → processing → completed şeklinde ilerliyor ya da iki nihai hatadan birine iniyor: failed ve cancelled. Tamamlanmış bir job sonucunu data.outputs[0].url içinde taşıyor, patlamış olan ise gerekçesini data.error.message içinde.
Herhangi bir faturalama kodu yazmadan önce içselleştirilecek bir detay: API'nin döndürdüğü her parasal değer mikro-cent cinsinden. Bir milyon, bir dolar ediyor. Dolayısıyla bir Nano Banana Pro request'i 0.075 olarak değil, 75000 olarak geri geliyor. Görüntüleme katmanında 1.000.000'a bölün, başka hiçbir yerde bölmeyin ve bölünmüş rakamı asla saklamayın.
Dövmeden poll etmek
Kaba versiyon çalışıyor:
curl https://api.e2x.ai/v1/jobs/job_8Kd2mQvXpL \
-H "Authorization: Bearer $E2X_API_KEY"
Bunu sabit iki saniyelik bir uykuyla bir döngüye sarın, çalışan bir entegrasyonunuz olsun. Özellikle Nano Banana Pro için sabit bir aralık gerçekten kabul edilebilir — bir request kabaca 30 saniye sürüyor, dolayısıyla yaklaşık on beş status çağrısı yapıp duruyorsunuz. Bu, kimseyi rahatsız edecek kadar trafik değil.
Yine de backoff daha iyi ve sebebinin nezaketle hiç ilgisi yok. Sabit aralıklar varyansı gizliyor. Bir job 30 saniye yerine 90 saniye sürerse, sabit bir döngü aynı hızda çağırmaya devam ediyor ve loglarınız sağlıklı bir koşuyla birebir aynı görünüyor. Büyüyen bir backoff ise yavaş bir job'ı görünür biçimde yavaş yapıyor.
import time
TERMINAL = {"completed", "failed", "cancelled"}
def wait_for(job_id, timeout=300):
delay = 2.0
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
r = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()["data"]
if data["status"] in TERMINAL:
return data
time.sleep(delay)
delay = min(delay * 1.4, 10.0)
raise TimeoutError(f"{job_id} still running after {timeout}s")
O döngünün, naif bir döngünün genelde yapmadığı iki şeyi var. Sert bir son teslim tarihi var, dolayısıyla takılmış bir job süreç öldürülene kadar dönmek yerine hata fırlatıyor. Ve üç nihai durumun üçünü de taşıma katmanında aynı şekilde ele alıyor: payload'ı döndürüyor ve bir hatanın ne anlama geldiğine çağıranın karar vermesine izin veriyor. Retry mantığı bu fonksiyonun içine değil, üstüne ait.

Webhook'lar ve neden onlara geçmelisiniz
Submit gövdesinde webhookUrl geçin, job nihai bir duruma ulaştığında sizi arayalım. Hiç polling döngüsü yok.
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-pro/text-to-image",
"input": {
"prompt": "Bir teknik çizim masasında yaya köprüsünün mimari maketi, kuzey ışığı",
"aspect_ratio": "3:2",
"resolution": "2k"
},
"webhookUrl": "https://your-app.example.com/hooks/e2x"
}'
Polling doğru ilk hamle, çünkü onu bir terminalden on saniyede test edebiliyorsunuz. Yanlış kalıcı durum ve sebebi aritmetik. Tek seferde tek görselde polling size bir döngüye mal oluyor. Bir batch'te iki yüz görselde ise iki yüz eşzamanlı döngüye mal oluyor; her biri yarım dakika boyunca bir bağlantı tutuyor ve bu, artık havadaki her job'ın izini kaybetmeden yeniden başlatılamayan bir süreçte gerçekleşiyor.
Webhook'lar işi yeniden başlatılabilir kılıyor. Gönderdiğinizde job ID veritabanınıza giriyor, biz aradığımızda handler satırı güncelliyor ve ortada yapılan bir deploy hiçbir şeyi değiştirmiyor. Bir script değil bir üretim pipeline'ı kuruyorsanız kurulacak versiyon bu ve görsel üretimini uçtan uca otomatikleştirmek yazımızdaki örüntülerle eşleşiyor.
İki operasyonel not. Endpoint'inizin genel internetten erişilebilir olması gerekiyor, dolayısıyla bir localhost URL'i geliştirme sırasında sessizce hiç tetiklenmeyecek — bir tünel kullanın. Ve webhook'u doğruluğun kaynağı değil, bir bildirim olarak ele alın: harekete geçmeden önce handler'ın içinde job'ı ID'siyle çekin.
Üretmek yerine bir görseli düzenlemek
Aynı zarf, farklı slug, bir fazladan alan. Edit endpoint'i prompt'un yanında image_urls alıyor ve aynı $0.075'i tutuyor.
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-pro/edit-image",
"input": {
"prompt": "Arka planı yumuşak gri bir stüdyo fonuyla değiştir, ürün ışığını olduğu gibi koru",
"image_urls": ["https://your-cdn.example.com/source/bottle.jpg"],
"aspect_ratio": "1:1",
"resolution": "2k"
}
}'
Geçtiğiniz URL'lerin herkese açık biçimde çekilebilir olması gerekiyor. Kendi depolamanızdan imzalı bir URL çalışıyor; dizüstünüzdeki bir yol çalışmıyor.
Nano Banana Pro on dört referans görsele kadar kabul ediyor ve diğer katmanların aksine onları role göre ayırıyor — karakter kimliği için 5'e, nesne sadakati için 6'ya, stil için 3'e kadar. Bu katmanda olmanın sebebi zaten o rol ayrımı ve role kapsamlı referansların tam alan adları model başına makine tarafından okunabilir spec dosyasında belgeleniyor; dokümanlarımızla bu yazı bir gün çelişirse yetkili odur. Özellikle karakter tutarlılığı iş akışına tutarlı üretim rehberinde daha derinlemesine giriyoruz.
Her parametre ve varsayılanı
| Alan | Nereye gidiyor | Kabul edilen değerler | Varsayılan |
|---|---|---|---|
model | gövde kökü | google/nano-banana-pro/text-to-image ya da google/nano-banana-pro/edit-image | zorunlu |
input.prompt | input içinde | string | zorunlu |
input.aspect_ratio | input içinde | 9:16, 16:9, 1:1, 2:3, 3:2, 21:9, 3:4, 4:3, 4:5, 5:4 | 9:16 |
input.resolution | input içinde | 1k, 2k, 4k | açıkça sabitleyin |
input.image_urls | input içinde, yalnızca edit slug'ında | herkese açık erişilebilir URL dizisi | edit'te zorunlu |
webhookUrl | gövde kökü | herkese açık bir HTTPS endpoint'i | yok, onun yerine poll edin |
İnsanlara para kaybettiren iki satır aspect_ratio ve resolution. Geri kalan her şey tahmin edeceğiniz gibi davranıyor.
Job tamamlanmadığında
Üç hata yüzeyi ve farklı ele alış gerektiriyorlar.
Submit çağrısının kendisi patlıyor. Bu, henüz hiçbir job yokken alınan bir HTTP hatası — hatalı key, bozuk gövde, bilinmeyen model slug'ı. Hiçbir şey kuyruğa girmedi ve hiçbir şey ücretlendirilmedi. Request'i düzeltin; değiştirmeden yeniden denemek birebir aynı şekilde patlayacak.
Job failed durumuna ulaşıyor. Job vardı ve model bir görsel üretmedi. Gerekçe için data.error.message'ı okuyun; genelde bir içerik politikası reddi ya da image_urls içinde erişilemeyen bir URL gibi bozuk bir input oluyor. Bir politika reddinin körlemesine yeniden denenmesi aynı şekilde patlıyor; geçici bir upstream hatasından sonraki yeniden deneme ise genelde başarılı oluyor. Yalnızca status'ü değil, mesajı loglayın.
Job cancelled durumuna ulaşıyor. Nihai ve bir bug değil. Kod seviyesinde tam olarak failed gibi ele alın — satır kapandı, gelen bir çıktı yok.
Bekleme döngünüz timeout'a düşüyor. Bu bir job durumu değil. Job'ın hâlâ çalıştığı ve sizin sabrınızın tükendiği anlamına geliyor. Job ID hâlâ geçerli, dolayısıyla aynı görsel için iki kez ücretlendirileceğiniz bir yeniden gönderim yerine onu kaydedin ve sonra tekrar bakın.
def generate(prompt, **kw):
job_id = submit(prompt, **kw)
job = wait_for(job_id)
if job["status"] != "completed":
reason = (job.get("error") or {}).get("message", "no reason given")
raise RuntimeError(f"{job_id} ended as {job['status']}: {reason}")
return job["outputs"][0]["url"]
Çıktıyı süresi dolmadan indirin
Lansmandan bir hafta sonra kırık görselleri yayına veren kısım bu, dolayısıyla kendi bölümünü hak ediyor.
data.outputs[0].url adresindeki URL geçici. Bu bir teslimat URL'i, barındırma değil. O string'i image_url adlı bir veritabanı sütununa yazıp bir ürün sayfasında render ederseniz, sayfa staging'de çalışır, incelemede çalışır, lansman günü çalışır ve sonra nesne yaşlandığında sessizce kırık görsel ikonlarına dönüşür.
Çözüm tek adım ve opsiyonel değil. Byte'ları çekin, kendi depolamanıza koyun, kendi URL'inizi saklayın.
import pathlib
def download(url, dest):
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
pathlib.Path(dest).parent.mkdir(parents=True, exist_ok=True)
with open(dest, "wb") as f:
for chunk in r.iter_content(chunk_size=1 << 16):
f.write(chunk)
return dest
Ya da kabuktan:
curl -sL "$OUTPUT_URL" -o ./out/menu-board.jpg
İndirmeyi, tamamlanmayı ele alan aynı iş biriminin içinde yapın. Bir saat sonra bir cron'da değil, ilk sayfa görüntülemesinde tembel biçimde değil. Pencere, testte bir gecikmeyi kurtaracak kadar cömert ve yük altında kurtarmayacak kadar dar.

Bütünü, tek bir script olarak
Yukarıdaki her şey, bir araya getirilmiş. E2X_API_KEY'i ayarlayın ve çalıştırın.
#!/usr/bin/env python3
"""Nano Banana Pro ile tek bir görsel üret ve yerel diske sakla."""
import os
import pathlib
import time
import requests
BASE = "https://api.e2x.ai/v1"
MODEL = "google/nano-banana-pro/text-to-image"
HEADERS = {"Authorization": f"Bearer {os.environ['E2X_API_KEY']}"}
TERMINAL = {"completed", "failed", "cancelled"}
def submit(prompt, aspect_ratio="16:9", resolution="2k"):
r = requests.post(
f"{BASE}/jobs/submit",
headers=HEADERS,
json={
"model": MODEL,
"input": {
"prompt": prompt,
"aspect_ratio": aspect_ratio,
"resolution": resolution,
},
},
timeout=30,
)
r.raise_for_status()
return r.json()["data"]["jobId"]
def wait_for(job_id, timeout=300):
delay = 2.0
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
r = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()["data"]
if data["status"] in TERMINAL:
return data
time.sleep(delay)
delay = min(delay * 1.4, 10.0)
raise TimeoutError(f"{job_id} still running after {timeout}s")
def download(url, dest):
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
pathlib.Path(dest).parent.mkdir(parents=True, exist_ok=True)
with open(dest, "wb") as f:
for chunk in r.iter_content(chunk_size=1 << 16):
f.write(chunk)
return dest
def main():
job_id = submit(
"Mermer bir kahve tezgâhının arkasında elle yazılmış tebeşir tahtası menü, "
"soldaki pencereden sıcak öğleden sonra ışığı, sığ alan derinliği"
)
print("submitted", job_id)
job = wait_for(job_id)
if job["status"] != "completed":
reason = (job.get("error") or {}).get("message", "no reason given")
raise SystemExit(f"{job_id} ended as {job['status']}: {reason}")
path = download(job["outputs"][0]["url"], "out/menu-board.jpg")
print("saved", path)
if __name__ == "__main__":
main()
Slug'ı google/nano-banana-pro/edit-image ile değiştirip image_urls ekleyin, aynı script üretmek yerine düzenlesin. Onu Nano Banana 2 ya da Nano Banana 2 Lite ile değiştirin, yine çalışsın; çünkü zarf, text-to-image kategorisindeki her şey ve image-to-image'daki her şey boyunca birebir aynı. Yalnızca input alanları farklı ve onu hangi modele yönelteceğinizi model karşılaştırma yazısı kapsıyor.
Kod olmayan son bir şey. Her Google modelinden çıkan her görsel bir SynthID watermark'ı taşıyor ve hiçbir sağlayıcı onu kapatamıyor. Bunun üstüne bir şey kurmadan önce sözleşmeyi imzalayan kimse onunla çözün.
Sıkça sorulan sorular
Nano Banana Pro API'sini nasıl çağırırım?
https://api.e2x.ai/v1/jobs/submit adresine bir bearer token, google/nano-banana-pro/text-to-image model slug'ı ve prompt'unuzu içeren bir input nesnesiyle POST gönderin. Response data.jobId döndürüyor. https://api.e2x.ai/v1/jobs/{id} adresini poll edin ya da submit gövdesinde bir webhookUrl geçin, sonra biten görseli data.outputs[0].url adresinden okuyun.
Nano Banana Pro'nun varsayılan aspect ratio'su ne?
Portre olan 9:16. Bu neredeyse herkesi şaşırtıyor, çünkü çoğu görsel API'si varsayılan olarak kare veriyor. aspect_ratio'yu açıkça ayarlamazsanız her görsel dikey çıkıyor. Model 9:16, 16:9, 1:1, 2:3, 3:2, 21:9, 3:4, 4:3, 4:5 ve 5:4 kabul ediyor.
Nano Banana Pro görsel URL'im neden kırık?
Çünkü döndürdüğümüz çıktı URL'i kalıcı barındırma değil, geçici teslimat. URL'imizi bir veritabanına kaydedip sonradan render eden her pipeline, nesnenin süresi dolduğunda kırık görseller gösterecek. Byte'ları job tamamlanmasını ele alan aynı adımda indirin ve kendi bucket'ınızda saklayın.
E2X API'siyle polling mi kullanmalıyım, webhook mu?
Kurarken poll edin, çünkü onu bir terminalden test edebiliyorsunuz. Üretimde çalışan her şey için webhook'lara geçin. Bir Nano Banana Pro job'ı kabaca 30 saniye sürüyor, dolayısıyla iki yüzlük bir batch demek, sonraki deploy'da hepsi state'ini kaybeden iki yüz eşzamanlı polling döngüsü demek. webhookUrl ile job ID gönderim anında veritabanınıza giriyor ve handler onu sonra alıyor.
Nano Banana Pro ile var olan bir görseli nasıl düzenlerim?
google/nano-banana-pro/edit-image slug'ını kullanın ve prompt'unuzun yanında input nesnesine bir image_urls dizisi ekleyin. URL'lerin herkese açık biçimde çekilebilir olması gerekiyor, dolayısıyla depolamanızdan imzalı bir URL çalışıyor ama yerel bir yol çalışmıyor. Düzenleme, üretimle aynı $0.075'i tutuyor.
Nano Banana Pro'dan hangi çözünürlüğü istemeliyim?
2k gönderin. Bu slug'da ilk iki ayar tek bir düz ücreti paylaşıyor, dolayısıyla 1k kesin biçimde eziliyor — daha az piksel, birebir aynı fatura satırı. 4k'ya yalnızca gerçekten 4096×4096 tavanına ihtiyacınız olduğunda uzanın, çünkü ücreti $0.15'e ikiye katlıyor. Üç değer de küçük harfli.
E2X API'si neden 75000 gibi fiyatlar döndürüyor?
API'deki her parasal değer mikro-cent cinsinden ifade ediliyor; 1.000.000, bir ABD dolarına eşit. Bir Nano Banana Pro job'ındaki 75000, $0.075 demek. Tam sayıyı depolamada tutun ve yalnızca bir insanın okuduğu noktada bölün ki yuvarlama bir faturalama dönemi boyunca hiç birikmesin.