Nano Banana Pro API: tutorial Python, modifica delle immagini e prezzo
Un POST, un polling, un download: uno script per Nano Banana Pro che funziona.

In questa pagina
- Risposta breve
- L'id del modello e cosa serve
- Lo script Python
- Modificare un'immagine esistente
- 1K, 2K e 4K: cosa dà ciascuno
- Errori che incontrerai
- Domande frequenti
- Qual è l'id del modello dell'API Nano Banana Pro?
- Quanto costa un'immagine di Nano Banana Pro?
- Nano Banana Pro sa disegnare testo cinese?
- Meglio chiedere 1K, 2K o 4K?
- Perché la mia modifica ha restituito 400 invalid_request?
- Fonti verificate
- Registro aggiornamenti
Nano Banana Pro è gemini-3-pro-image di Google, e su OmniaKey lo chiami con un solo POST /v1/media/tasks. I nostri tre test in 3:4 sono tornati a 896x1200, 1792x2400 e 3584x4800, e ogni parola del poster era scritta correttamente.
Risposta breve
- Modello:
gemini-3-pro-imageè l'id GA di Google. La scheda del modello su Vertex indica una data di uscita al 28 maggio 2026. - Chiamata: invia
POST https://api.omniakey.com/v1/media/taskscon unaIdempotency-Key, interrogaGET /v1/media/tasks/{id}finché lo stato è succeeded, poi scaricaassets[0].url. - Parametri:
parameters.aspect_ratioeparameters.image_size; i valori di dimensione sono 1K, 2K e 4K, con la K maiuscola. - Limite della richiesta: 1 MiB per tutto il corpo, compresi i dati dell'immagine in Base64.
- Prezzo di Google: $0.134 per immagine 1K/2K e $0.24 per immagine 4K, dalla pagina dei prezzi della Gemini API.
- I nostri token: le tre attività hanno riportato 1,133, 1,225 e 2,480 token di output. A $120 per milione di token immagine sono $0.136, $0.147 e $0.298.
- Modifica: usa
operation: "edit"e metti l'immagine di partenza ininput.imagecome{data, mime_type}.
La pagina del modello Nano Banana Pro su OmniaKey accetta anche gemini-3-pro-image-preview, l'id dello snapshot precedente, allo stesso prezzo.
L'id del modello e cosa serve
L'id da scrivere nel codice è gemini-3-pro-image. La scheda del modello su Vertex lo elenca come GA con data di uscita 28 maggio 2026. Supporta output in 1K, 2K e 4K.
L'id -preview punta allo stesso modello. La tabella dei modelli di immagine di OmniaKey descrive gemini-3-pro-image-preview come "Same model, -preview snapshot id", con la stessa tariffa per chiamata.
Servono due cose:
- Una chiave API OmniaKey, esportata perché lo script la legga:
export OMNIAKEY_API_KEY="your-key". - Python 3. Lo script qui sotto usa solo la libreria standard: urllib, json, time, uuid, base64 e pathlib. Nessun SDK da installare.
Lo script Python
Tre passaggi: crea l'attività, interrogala, scarica l'immagine. Salvalo come nano_banana.py ed eseguilo con 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 accetta 1K, 2K o 4K. La guida immagini di Google è esplicita: "You must use an uppercase 'K' … Lowercase parameters (e.g., 1k) will be rejected." Invia 2K, non 2k.
Idempotency-Key è obbligatoria. Un UUID nuovo a ogni richiesta è la regola semplice; riusa una chiave solo quando rimandi esattamente lo stesso corpo. OmniaKey restituisce l'attività originale con HTTP 200 invece di addebitare due volte, e risponde 409 se la stessa chiave arriva con un corpo diverso.
La chiamata di creazione restituisce 202 con un id. La documentazione delle attività media di OmniaKey descrive l'intero ciclo; l'attività completata porta questi campi:
{
"id": "task_AbMRVqzSnVh0VwBj0S7NuMUxy5sZtfHP",
"status": "succeeded",
"progress": {"percent": 100, "stage": "completed"},
"usage": {"total_tokens": 1133},
"assets": [
{
"kind": "image",
"mime_type": "…",
"url": "https://…signed-url…"
}
]
}
Leggi assets[0].url e scarica subito: il link firmato dura circa un'ora e il record dell'attività resta 24 ore. Il campo mime_type dice il formato; i modelli Gemini di solito restituiscono JPEG.
Lo stesso script in 1:1 e 2K, con un'insegna in cinese come prompt, ha restituito questo:

Modificare un'immagine esistente
Imposta operation: "edit" e passa l'immagine di partenza in input.image come {data, mime_type}. Lo script qui sopra lo fa già quando gli dai un image_path:
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",
)
Il corpo che invia è questo:
{
"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"}
}
L'immagine di partenza dell'esempio è un PNG, quindi lo script la etichetta image/png; per un JPEG cambia quell'etichetta. Per più riferimenti usa input.images e dai a ogni voce la stessa forma {data, mime_type}. La guida di Google fissa il limite a 14 immagini di riferimento; per gemini-3-pro-image la ripartizione è 6 immagini di oggetto, 5 di personaggio e 3 di stile.
Tieni il corpo sotto 1 MiB. Il Base64 rende il file circa un terzo più grande, quindi riduci o comprimi la partenza prima di codificarla. La nostra modifica ha usato il poster 2K e ha conservato ogni parola e l'impaginazione:

1K, 2K e 4K: cosa dà ciascuno
Abbiamo eseguito lo stesso prompt del poster in 3:4 con tutte e tre le dimensioni. I pixel corrispondevano esattamente alla tabella di Google per il 3:4: 896x1200 a 1K, 1792x2400 a 2K e 3584x4800 a 4K. Il testo del poster era corretto a ogni dimensione.



Quello che cambia con la dimensione è il dettaglio, non l'ortografia:
- 1K: la parte anteriore del treno è affollata: fanali, ruote e bielle stanno vicinissimi.
- 2K: il villaggio e i suoi due campanili compaiono sul versante destro, il camino emette un filo di fumo chiaro e il ponte mostra sette arcate.
- 4K: le tre carrozze e il tender sono separati, e la muratura mostra giunti di spessore diverso. Il meccanismo sotto la locomotiva resta semplificato.
La velocità è salita con la dimensione: 28.4 s, 48.2 s e 66.9 s. Abbiamo eseguito ogni dimensione una volta, quindi leggi quei secondi come una singola esecuzione.
Google fattura l'output delle immagini a $120 per milione di token, e la sua tabella dà 1,120 token sia per 1K sia per 2K e 2,000 token per 4K. Da lì esce la sua stima:
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
Le nostre attività hanno riportato più token degli esempi di Google. Ecco la stessa aritmetica con i nostri numeri:
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
| Dimensione | Pixel, 3:4 | Il nostro tempo | I nostri token | Stima di Google |
|---|---|---|---|---|
| 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 fattura la chiamata immagine a forfait, non a token, quindi il suo importo non si muove con quei conteggi; la tariffa attuale per chiamata è sulla pagina del modello, e un'attività fallita viene rimborsata. La stima di Google alla tariffa token per le stesse tre immagini è $0.134, $0.134 e $0.24.
Errori che incontrerai
I guasti elencati qui si riducono quasi sempre a un nome di campo o a una dimensione di file, non al modello. Questi sono quelli che la documentazione media di OmniaKey indica per questo endpoint:
| HTTP | Codice o stato | Cosa significa | Cosa fare |
|---|---|---|---|
| 400 | invalid_request | Corpo malformato, operazione non supportata o parametro errato | Controlla il JSON e i nomi dei campi qui sotto |
| 503 | no_available_channel | Nessun canale serve questo modello adesso | Cambia modello; riprovare non risolve |
| — | failed | L'attività è finita senza risultato | Leggi error.code e error.message |
Un'attività failed non è un errore HTTP: la chiamata di creazione è riuscita, quindi interroga l'attività e leggi il suo oggetto error. Le attività fallite e annullate vengono rimborsate automaticamente.
Un'immagine a piena risoluzione inviata in Base64 può spingere il corpo oltre 1 MiB. Riducila prima e controlla la lunghezza codificata, non solo la dimensione del file.
La guida di Google rifiuta un 1k minuscolo. Usa 1K, 2K o 4K.
La documentazione immagini di OmniaKey rifiuta anche size e un mime_type di primo livello sui modelli Gemini, perché non sono parametri Gemini. Usa parameters.aspect_ratio e parameters.image_size, e leggi il formato di output dal campo mime_type della risposta.
Domande frequenti
Qual è l'id del modello dell'API Nano Banana Pro?
gemini-3-pro-image. La scheda Vertex di Google lo indica come GA con data di uscita 28 maggio 2026, e OmniaKey accetta lo stesso id. L'id precedente gemini-3-pro-image-preview funziona ancora su OmniaKey e punta allo stesso modello.
Quanto costa un'immagine di Nano Banana Pro?
Google stima $0.134 per un'immagine 1K o 2K e $0.24 per una 4K, alla tariffa di $120 per milione di token immagine. Le nostre attività hanno riportato 1,133, 1,225 e 2,480 token, che a quella tariffa sono $0.136, $0.147 e $0.298. La pagina del modello su OmniaKey indica la propria tariffa per chiamata.
Nano Banana Pro sa disegnare testo cinese?
Sì. La nostra insegna in 2K è tornata con tre righe cinesi corrette — 同福客栈, 住宿 餐饮 茶水 e 010-6789 4321 — comprese le 11 cifre e il trattino.
Meglio chiedere 1K, 2K o 4K?
Per un poster come il nostro, 2K è il punto medio utile. Tutte e tre le dimensioni hanno scritto bene il poster, quindi 4K compra dettaglio più fine — carrozze separate, giunti dei mattoni — e non testo migliore. Usa 1K per le bozze in cui 896x1200 basta.
Perché la mia modifica ha restituito 400 invalid_request?
Le cause abituali sono un corpo oltre 1 MiB, la partenza nel campo sbagliato o un modello Gemini che riceve size o un mime_type di primo livello. Metti l'immagine in input.image come {data, mime_type}, tieni il corpo codificato sotto 1 MiB e usa aspect_ratio e image_size.
Fonti verificate
- Google Cloud: scheda del modello Gemini 3 Pro Image — verificata il 3 novembre 2026.
- Google: guida alla generazione di immagini della Gemini API — verificata il 3 novembre 2026.
- Google: prezzi della Gemini API — verificati il 3 novembre 2026.
- Google: annuncio di Nano Banana Pro — verificato il 3 novembre 2026.
Registro aggiornamenti
- 2026-11-03: prima versione; cinque chiamate di prova fatte quel giorno tramite OmniaKey.
Modelli citati in questo articolo
Articoli correlati
Nano Banana 2.1: recensione, accesso API, prezzi e migrazione
Confronta Nano Banana 2.1 con Nano Banana 2 e crea task immagine supportati direttamente tramite OmniaKey.
Foto prodotto con Nano Banana: 8 prompt testati
Otto prompt, 22 modifiche, due modelli: quali scatti hanno tenuto l'etichetta, dove la scarpa è uscita specchiata e quale modello scegliere per ogni lavoro.
Seedream 5.0 Pro vs Nano Banana Pro: test con lo stesso prompt e prezzo
Cinque prompt condivisi, due modelli, tempi misurati e prezzo per immagine 2K.
