Dokumentation
Bildgenerierung
Zwei Endpunkte: Text-zu-Bild und Bildbearbeitung bzw. Bild-zu-Bild. Beide geben dauerhafte Ergebnis-URLs zurück: Kunavo archiviert jedes Bild auf seinem eigenen CDN.
Kunavo stellt /v1/images/generations (Text-zu-Bild) und /v1/images/edits (Bild-zu-Bild/Bearbeitung) bereit. Beide sind standardmäßig synchron — der Aufruf wartet, bis der Upstream fertig ist, und gibt dann Ergebnis-URLs zurück — oder nutzen Sie asynchron mit "async": true oder einem webhook_url.
Text-zu-Bild
Endpunkt: POST /v1/images/generations. Verwenden Sie die Methode images.generate des OpenAI SDK oder direkt curl.
img = client.images.generate(
model="nano-banana-pro",
prompt="a red origami crane on a white desk, soft window light",
size="1024x1024",
)
print(img.data[0].url)Gängige Parameter
| Parameter | Typ | Hinweise |
|---|---|---|
model | string | Beliebiger Bildmodell-Slug aus /v1/models. |
prompt | string | Text-Prompt. Immer erforderlich. |
size | string | OpenAI-Format „1024x1024“. Wird dem Upstream-Seitenverhältnis zugeordnet. |
quality | standard|hd | Sofern unterstützt (gpt-image). |
resolution | 1K|2K|4K | Auflösungsstufe für Modelle mit Stufen — siehe unten Resolution tiers. Abrechnung nach Stufe. |
n | int | Anzahl der Bilder. Die meisten Modelle geben unabhängig davon 1 zurück. |
input | object | Ausweichmöglichkeit — siehe unten Raw input. |
files.kunavo.com-Links: Kunavo archiviert jedes Bild auf seinem eigenen CDN, sodass sie im Gegensatz zu rohen Upstream-URLs nie ablaufen. Kann ein Bild nicht archiviert werden, ist seine URL die temporäre URL des Upstream-Anbieters auf einem anderen Host: Laden Sie dieses Bild herunter und hosten Sie es selbst.Auflösungsstufen
Bei mehreren Bildmodellen richtet sich der Preis nach der Ausgabeauflösung und steigt stufenweise. Übergeben Sie resolution, um eine Stufe auszuwählen; lassen Sie den Parameter weg, wird die Standardstufe verwendet. Abgerechnet wird die tatsächlich erzeugte Stufe.
| Modell (sowie dessen -edit-Variante) | Stufen — Preis pro Stufe | Standard |
|---|---|---|
| nano-banana-2 | 1K $0.0469 · 2K $0.0707 · 4K $0.1057 | 1K |
| nano-banana-pro | 1K / 2K $0.067 · 4K $0.12 | 2K |
| gpt-image-2 | 1K / 2K / 4K — $0.0633 (Pauschalpreis) | 1K |
Auch für die veo-3-Familie gelten Auflösungsstufen — die Preise pro Stufe finden Sie auf der Seite /models des jeweiligen Modells.
resolution = 4K mit quadratischer Größe anfordern, wird der Aufruf automatisch auf 2K heruntergestuft und zum 2K-Preis abgerechnet.Bildbearbeitung / Bild-zu-Bild
Endpunkt: POST /v1/images/edits. Übergeben Sie das Quellbild als URL (HTTPS oder data:-Base64) über image für die Bearbeitung eines einzelnen Bildes oder über image_urls für mehrere Referenzbilder.
# Image edit / image-to-image: pass the source image URL
import requests
resp = requests.post(
"https://api.kunavo.com/v1/images/edits",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "gpt-image-2-edit",
"prompt": "recolor the crane to bright blue, keep composition",
"image": "https://your-cdn.com/source.png",
},
)
print(resp.json()["data"][0]["url"])Mehrere Referenzbilder
Einige Modelle (Nano Banana Edit, GPT-Image-2 Edit) akzeptieren mehrere Referenzbilder.
# nano-banana-edit accepts multiple reference images
resp = requests.post(
"https://api.kunavo.com/v1/images/edits",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "nano-banana-edit",
"prompt": "merge subject from img1 with background from img2",
"image_urls": [
"https://your-cdn.com/subject.png",
"https://your-cdn.com/background.png",
],
},
)Unterstützte Bearbeitungsmodelle
nano-banana-edit— Google Nano Banana-Bearbeitunggpt-image-2-edit— OpenAI-Bild-zu-Bild
Ein Quellbild bereitstellen
Bildbearbeitung und Bild-zu-Video benötigen beide ein Quellbild, das das Modell abrufen kann. Sie haben drei Möglichkeiten — wählen Sie die passende für Ihre Anwendung:
- Sie haben bereits eine öffentliche URL — übergeben Sie sie direkt als
image(oder alsimage_urlfür Video). Fertig. - Sie haben eine lokale Datei — laden Sie sie einmal über
POST /v1/fileshoch und verwenden Sie dann die zurückgegebene dauerhafte URL erneut. - Sie haben Rohdaten im Code — fügen Sie sie als
data:-Base64-URI direkt ein; Kunavo stellt sie transparent bereit.
Option A — über POST /v1/files hochladen
Senden Sie multipart/form-data mit einem file-Feld (oder als JSON-{ "file": "data:..." }). Sie erhalten eine dauerhafte files.kunavo.com-URL zurück — für Dateien bis zu 25 MB.
# Upload a local file → get a permanent Kunavo URL
import requests
with open("source.png", "rb") as f:
up = requests.post(
"https://api.kunavo.com/v1/files",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": f},
).json()
# up["url"] is now a permanent https://files.kunavo.com/... URL
edit = requests.post(
"https://api.kunavo.com/v1/images/edits",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "gpt-image-2-edit",
"prompt": "recolor the crane to bright blue",
"image": up["url"],
},
).json()
print(edit["data"][0]["url"])Option B — Base64 direkt einbetten
Überspringen Sie den separaten Upload vollständig: Fügen Sie im Feld image / image_url eine data:-URI ein. Kunavo dekodiert sie, hostet sie auf seinem CDN und übergibt dem Modell die gehostete URL.
# Or skip the upload step — pass base64 inline, we host it for you.
import base64, requests
with open("source.png", "rb") as f:
b64 = base64.b64encode(f.read()).decode()
resp = requests.post(
"https://api.kunavo.com/v1/images/edits",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "gpt-image-2-edit",
"prompt": "recolor the crane to bright blue",
"image": f"data:image/png;base64,{b64}",
},
)POST /v1/video/generations — image_url akzeptiert für Bild-zu-Video-Modelle wie Veo eine HTTPS-URL oder eine data:-Base64-URI.Antwortformat
Beide Endpunkte geben die standardmäßige Images-Antwort von OpenAI zurück:
{
"created": 1779360636,
"data": [
{ "url": "https://files.kunavo.com/image/.../result.png" }
]
}Latenz & Zeitüberschreitungen
Die Bildgenerierung dauert je nach Modell üblicherweise 5–60 Sekunden. Im standardmäßigen synchronen Modus hält Kunavo die Verbindung offen und fragt den Upstream bis zu 540 Sekunden lang ab, bevor eine 504 zurückgegeben wird. Legen Sie das clientseitige Timeout entsprechend fest — oder verwenden Sie die asynchrone API, um innerhalb von Sekunden einen Auftrag einzureichen und nach Ihrem eigenen Zeitplan abzufragen:
- Nano Banana / Nano Banana 2: normalerweise unter 10 Sekunden.
- Nano Banana Pro / GPT-Image-2: 15–60 Sekunden.
- Mehrere Referenzen und Premium-Stufe: bis zu etwa 2 Minuten.
Asynchrone API (Einreichung + Abruf / Webhook)
Beide Bildendpunkte sind standardmäßig synchron — der Aufruf hält die Verbindung offen, bis der Upstream das Bild erstellt hat, und gibt dann die standardmäßige OpenAI-Images-Antwort zurück. Für Batch-Aufträge, langsame Premium-Stufen oder serverlose Aufrufer, die keine lange Anfrage offen halten können, fügen Sie "async": true (oder eine webhook_url) zu /v1/images/generations oder /v1/images/edits hinzu.
Die Einreichung gibt sofort eine img_*-ID zurück; fragen Sie GET /v1/images/{id} so lange ab, bis status den Wert completed oder failed hat — oder registrieren Sie einen Webhook und überspringen Sie die Abfrage vollständig.
# Async: add "async": true (or a webhook_url) to either image endpoint.
# The call returns instantly with an img_ id instead of holding the connection.
import requests, time
API = "https://api.kunavo.com/v1"
H = {"Authorization": f"Bearer {API_KEY}"}
submit = requests.post(
f"{API}/images/generations",
headers=H,
json={"model": "gpt-image-2", "prompt": "a red panda", "async": True},
).json()
task_id = submit["id"] # "img_abc..."
status = submit["status"] # "queued"
# Poll GET /v1/images/{id} until terminal — or skip polling and use a webhook.
while status not in ("completed", "failed"):
time.sleep(3)
r = requests.get(f"{API}/images/{task_id}", headers=H).json()
status = r["status"]
if status == "completed":
print(r["output"]["url"])
else:
print("failed:", r["error"])Aufgabenobjekt
| Feld | Typ | Hinweise |
|---|---|---|
id | string | img_* Aufgaben-ID — an GET /v1/ |
status | string | queued | in_progress | completed | failed. |
output | object|null | Nach Abschluss: { url, urls, archived }. archived ist false, wenn ein Bild nicht archiviert werden konnte und seine URL die temporäre URL des Upstream-Anbieters ist. |
error | object|null | Bei Fehler: { code, message }. |
expires_at | int|null | Unix-Sekunden, 30 Tage nach dem Absenden: Mindestens bis dahin lässt sich die Aufgabe abfragen. Die Ergebnis-URLs der Aufgabe laufen nicht ab. |
GET /v1/images/{id} ist auf den jeweiligen Eigentümer beschränkt: Wird eine ID abgefragt, die Ihnen nicht gehört, wird 404 zurückgegeben; die Antwort ist nicht von einer nie vergebenen ID zu unterscheiden. Empfohlener Abfrageabstand: 3 Sekunden, mit exponentiellem Backoff bis auf etwa 30 Sekunden.Webhooks
Übergeben Sie beim Einreichen webhook_url (https), und Kunavo sendet beim Abschluss der Aufgabe ein signiertes image.completed-/image.failed-Ereignis per POST — mit derselben Hülle und Signatur wie bei Video- und Musik-Webhooks:
X-Kunavo-Webhook-Id— stabile Ereignis-ID, bei Wiederholungen identisch (zur Deduplizierung verwenden).X-Kunavo-Webhook-Timestamp— Unix-Zeit in Sekunden, zu der die Signatur berechnet wurde.X-Kunavo-Webhook-Signature—sha256=HMAC-SHA256 über{timestamp}.{rawBody}, mit Ihrem Webhook-Geheimnis als Schlüssel.
Direkte Übergabe von Rohparametern
Für modellspezifische Parameter, die Kunavo nicht zuordnet (Seed, negativer Prompt, Ausgabeformat), übergeben Sie input. Es wird unverändert an den Upstream gesendet und ersetzt die Eingabe, die unser Adapter erstellen würde.
Eine Ausnahme ist das Feld, das die Preisstufe eines Modells auswählt: resolution oder bei Ideogram rendering_speed. Bei einem Modell mit Stufen wird es stets als eine der Stufen des Modells gesendet, und diese Stufe wird Ihnen berechnet. Wenn input das Feld nicht enthält oder einen Wert angibt, der keiner der Stufen des Modells entspricht, wird die Standardstufe gesendet und berechnet. Dasselbe Feld auf der obersten Ebene der Anfrage wird nicht ausgelesen, wenn input gesetzt ist.
# Raw upstream 'input': sent as written, in place of what our adapter builds.
# "resolution" sets the billed tier: 2K here, the default tier when left out.
resp = client.images.generate(
model="nano-banana-2",
prompt="", # ignored when input is set
extra_body={"input": {
"prompt": "a futuristic cyberpunk skyline at dusk",
"aspect_ratio": "16:9",
"resolution": "2K",
"output_format": "png",
}},
)input übergeben, umgehen Sie die Validierung von Kunavo. Lehnt der Upstream Ihre Felder ab, erhalten Sie von uns einen 422-Fehler — lesen Sie die Fehlerdokumentation und die Upstream-Dokumentation des Modells.