GPT Image API zur Bildbearbeitung
Bearbeite GPT-Image-Referenzen über BetterTokens OpenAI-kompatible API. Richte multipart und Masken ein, speichere Ergebnisse und prüfe Abrechnung und Fehler.
POST /v1/images/edits
Der Bild-zu-Bild-Endpunkt verwendet einen Request-Body im Format multipart/form-data. Lade ein oder mehrere Referenzbilder hoch und übermittle Prompt- und Parameterfelder als Formularfelder.
Empfohlene Werte
Dies sind empfohlene Startwerte, keine festen Anforderungen. Beginne mit n=1; der Endpunkt akzeptiert 1 bis 10, kann aber weniger Bilder zurückgeben.
model=gpt-image-2n=1response_format=b64_jsonoutput_format=pngVerwende image für ein Referenzbild oder wiederholte image[]-Felder für mehrere. Für normale Referenzbildbearbeitung ist keine mask nötig. quality ist optional: gpt-image-2 akzeptiert auto, low, medium, high; die zwei 2.5-Modelle akzeptieren auch xhigh und max. Bei Multipart muss der Wert eine nicht leere Zeichenfolge sein. Die Annahme garantiert weder die Verfügbarkeit für die Kombination aus Modell, Größe und Bearbeitung noch bessere Bildqualität durch eine höhere Stufe. Lass das Feld weg, wenn du keine Präferenz festlegen willst. size ist ebenfalls optional, darf aber keine leere Zeichenfolge sein.
Ein Referenzbild
Bereite reference.png vor und ersetze YOUR_API_KEY durch deinen BetterToken API Key. Ein Key funktioniert mit allen verfügbaren Modellen. Lass curl -F oder Python files die Content-Type-Boundary erzeugen.
| Formularfeld | Beispielwert |
|---|---|
model | gpt-image-2 |
prompt | Using this reference image, create a more polished square product key visual while preserving the subject style. |
n | 1 |
size | 1024x1024 |
response_format | b64_json |
output_format | png |
image | Lokale Datei reference.png auswählen |
curl --max-time 300 'https://bettertoken.ai/v1/images/edits' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -F 'model=gpt-image-2' \ -F 'prompt=Using this reference image, create a more polished square product key visual while preserving the subject style.' \ -F 'n=1' \ -F 'size=1024x1024' \ -F 'response_format=b64_json' \ -F 'output_format=png' \ -F 'image=@reference.png'Mehrere Referenzbilder
Sende diese Formularfelder:
| Formularfeld | Beispielwert |
|---|---|
model | gpt-image-2 |
prompt | Combine these reference images into a promotional poster with a consistent style. |
n | 1 |
size | 1024x1024 |
response_format | b64_json |
output_format | png |
image[] | reference-1.png auswählen |
image[] | reference-2.jpg auswählen |
image[] | reference-3.png auswählen |
curl --max-time 300 'https://bettertoken.ai/v1/images/edits' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -F 'model=gpt-image-2' \ -F 'prompt=Combine these reference images into a promotional poster with a consistent style.' \ -F 'n=1' \ -F 'size=1024x1024' \ -F 'response_format=b64_json' \ -F 'output_format=png' \ -F 'image[]=@reference-1.png' \ -F 'image[]=@reference-2.jpg' \ -F 'image[]=@reference-3.png'Einen ausgewählten Bereich mit Maske bearbeiten
Füge das optionale Dateifeld mask hinzu, wenn du die Bearbeitung auf einen ausgewählten Bereich lenken möchtest. Der aktuelle BetterToken-Endpunkt liest eine einzelne Datei im Feld mask. Sende keine wiederholten mask[]-Felder.
- Originalbild und Maske müssen dasselbe Dateiformat und dieselben Pixelabmessungen haben. Jede Datei muss kleiner als 50 MB sein. Verwende für maximale Kompatibilität PNG mit Alpha-Kanal für beide Dateien.
- Die Maske muss einen Alpha-Kanal enthalten. Vollständig transparente Pixel (
Alpha 0) markieren den Bereich, den das Modell neu zeichnen darf. Vollständig deckende Pixel (Alpha 255) weisen das Modell an, diesen Bereich beizubehalten. - Ein normales RGB-Schwarzweißbild ist keine gültige Maske, wenn es nicht tatsächlich einen Alpha-Kanal enthält.
- Wenn du mehrere
image[]-Felder sendest, wird die Maske auf das erste Eingabebild angewendet. - Die Maske dient dem Modell als Orientierung. Sie garantiert nicht, dass Pixel außerhalb des transparenten Bereichs absolut identisch bleiben.
- Die Verfügbarkeit der Maske hängt von der Kombination aus Modell und Größe ab. Tests mit GPT Image 2 und Flare zeigten sichtbare Änderungen außerhalb des Zielbereichs; die lokale Steuerung mit Sunburst wurde nicht verifiziert. Prüfe das Ergebnis vor dem Einsatz für Produkte, Logos oder präzise Retuschen.
curl --max-time 300 'https://bettertoken.ai/v1/images/edits' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -F 'model=gpt-image-2' \ -F 'prompt=Replace only the masked area with a blue circle. Preserve everything else.' \ -F 'n=1' \ -F 'size=1024x1024' \ -F 'response_format=b64_json' \ -F 'output_format=png' \ -F 'image=@original.png' \ -F 'mask=@mask.png'Maskierte Bearbeitung mit Python
Öffne beide Dateien in einer einzigen with-Anweisung, damit Python sie nach der Anfrage schließt:
import requests
url = "https://bettertoken.ai/v1/images/edits"headers = {"Authorization": "Bearer YOUR_API_KEY"}data = { "model": "gpt-image-2", "prompt": "Replace only the masked area with a blue circle. Preserve everything else.", "n": "1", "size": "1024x1024", "response_format": "b64_json", "output_format": "png",}
with open("original.png", "rb") as image_file, open("mask.png", "rb") as mask_file: files = { "image": ("original.png", image_file, "image/png"), "mask": ("mask.png", mask_file, "image/png"), } response = requests.post(url, headers=headers, data=data, files=files, timeout=300)
response.raise_for_status()result = response.json()Dateien vor dem Upload prüfen
Diese minimale Pillow-Prüfung kontrolliert die erforderlichen Angaben zu Format, Abmessungen und Alpha-Kanal. Bei einer typischen lokalen Maske gibt sie außerdem eine Warnung aus, wenn der Alpha-Kanal nicht sowohl vollständig transparente als auch vollständig deckende Bereiche enthält:
from pathlib import Pathfrom PIL import Image
image_path = Path("original.png")mask_path = Path("mask.png")
if image_path.stat().st_size >= 50 * 1024 * 1024 or mask_path.stat().st_size >= 50 * 1024 * 1024: raise ValueError("Each file must be smaller than 50 MB")
with Image.open(image_path) as image, Image.open(mask_path) as mask: if image.format != mask.format: raise ValueError("The image and mask formats must match") if image.size != mask.size: raise ValueError("The image and mask dimensions must match") if "A" not in mask.getbands(): raise ValueError("The mask must contain an Alpha channel") alpha_min, alpha_max = mask.getchannel("A").getextrema() if alpha_min > 0 or alpha_max < 255: print("Warning: for a typical local mask, include fully transparent and fully opaque areas")Python-Beispiel
import base64from pathlib import Path
import requests
url = "https://bettertoken.ai/v1/images/edits"headers = { "Authorization": "Bearer YOUR_API_KEY",}
data = { "model": "gpt-image-2", "prompt": "Using this reference image, create a more polished square product key visual while preserving the subject style.", "n": "1", "size": "1024x1024", "response_format": "b64_json", "output_format": "png",}
with open("reference.png", "rb") as image_file: files = { "image": ("reference.png", image_file, "image/png"), } response = requests.post(url, headers=headers, data=data, files=files, timeout=300)
response.raise_for_status()result = response.json()for index, item in enumerate(result["data"], start=1): encoded = item["b64_json"] if "," in encoded and "base64" in encoded.split(",", 1)[0]: encoded = encoded.split(",", 1)[1] image_bytes = base64.b64decode(encoded) if image_bytes.startswith(b"\x89PNG\r\n\x1a\n"): extension = "png" elif image_bytes.startswith(b"\xff\xd8\xff"): extension = "jpg" elif image_bytes.startswith(b"RIFF") and image_bytes[8:12] == b"WEBP": extension = "webp" else: raise ValueError("Unsupported image signature") Path(f"output-{index}.{extension}").write_bytes(image_bytes)Empfohlene Größen
size | Verhältnis | Anwendungsfall |
|---|---|---|
auto | Auto | Automatische Größenauswahl |
1024x1024 | 1:1 | Quadratische Bilder, Avatare, Cover, Assets |
1536x1024 | 3:2 | Querformat-Poster, Banner, Szenen |
1024x1536 | 2:3 | Mobile Cover und Poster im Hochformat |
1536x1152 | 4:3 | Standardbilder im Querformat, Produktbilder, Inhaltsgrafiken |
1152x1536 | 3:4 | Standardbilder im Hochformat, mobile Cover, vertikale Poster |
2048x2048 | 1:1 | Quadratische Bilder mit hoher Auflösung |
2048x1152 | 16:9 | Querformatbilder mit hoher Auflösung |
3840x2160 | 16:9 | 4K-Querformatbilder |
2160x3840 | 9:16 | 4K-Hochformatbilder |
Die Tabellenwerte sind Beispiele, keine abschließende Liste. Du kannst size weglassen oder auto verwenden; JSON null aktiviert ebenfalls die automatische Auswahl. Explizite Breite und Höhe müssen positiv und durch 16 teilbar sein, jeweils höchstens 3840; das Seitenverhältnis darf 3:1 und die Gesamtpixelzahl muss 655360 bis 8294400 betragen. Auch 2080x2080 ist gültig. Die tatsächlichen Abmessungen können abweichen: Prüfe das Bild und schneide es nicht erzwungen zu.
Bild speichern
Eine erfolgreiche Antwort folgt dem OpenAI-kompatiblen Bildantwortformat. Die folgenden Beträge veranschaulichen das Belegformat und sind keine Festpreise:
{ "created": 1710000000, "data": [ { "b64_json": "iVBORw0KGgoAAAANSUhEUgAA...(truncated)", "revised_prompt": "Optional revised prompt" } ], "bettertoken_image_billing": { "currency": "CNY", "settled_amount": "0.15", "outputs": [ { "index": 0, "width": 1254, "height": 1254, "billing_resolution": "2K", "currency": "CNY", "amount": "0.15" } ] }}Lies jedes data[].b64_json und berücksichtige zusätzliche Antwortfelder wie revised_prompt. output_format fordert ein Format an, garantiert aber keine Kodierung oder Konvertierung. Prüfe die Bildbytes und speichere die Datei mit der passenden Endung. Die Seite Text zu Bild enthält Beispiele, die jedes Ergebnis anhand der PNG-, JPEG- oder WebP-Signatur speichern.
Tatsächliche Kosten prüfen
bettertoken_image_billing wird mit dem Ergebnis zurückgegeben; eine separate Kostenabfrage ist nicht nötig.
| Feld | Bedeutung |
|---|---|
currency | Abrechnungswährung; nicht immer USD oder CNY. |
settled_amount | Gesamtabrechnung der Anfrage als Dezimalzeichenfolge. |
requested_resolution | Aus der Anfrage ermittelte Auflösungsstufe. |
outputs[].index | Bei 0 beginnender Bildindex passend zu data[]. |
outputs[].width, height | Tatsächliche Breite und Höhe in Pixeln. |
outputs[].billing_resolution | Endgültige Abrechnungsstufe des Bildes. |
outputs[].currency, amount | Abrechnungswährung und Betrag pro Bild. |
Angeforderte Größe und Abrechnungsstufe können abweichen: Eine Anfrage mit 1024x1024 lieferte 1254x1254 und wurde als 2K abgerechnet. Verwende den Belegbetrag und prüfe aktuelle Preise in der model plaza. Zeige Beträge als Zeichenfolgen an und rechne dezimal. Ein fehlender Beleg bedeutet nicht null Kosten.
from decimal import Decimal
billing = result.get("bettertoken_image_billing")if billing is None: print("Billing receipt unavailable; check your usage records.")else: total = Decimal(billing["settled_amount"]) print(f"Total: {billing['currency']} {total}") for output in billing.get("outputs", []): print( f"Image {output['index'] + 1}: " f"{output['width']}x{output['height']}, " f"{output['billing_resolution']}, " f"{output['currency']} {output['amount']}" )Antwortablauf
Dieser Endpunkt ist synchron. Halte nach dem Senden von POST /images/edits den aktuellen HTTP-Request offen, bis der Server antwortet. Bei Erfolg werden alle Bilder in data[].b64_json zurückgegeben.
Der Endpunkt gibt keine task_id zurück; es gibt keinen separaten Endpunkt für Statusabfragen oder das Herunterladen von Ergebnissen.
Timeouts, Wiederholungen und Abrechnung
Setze den HTTP-Client-Timeout auf mehrere Minuten. Ein Timeout, Verbindungsabbruch oder mehrdeutiger 5xx zeigt nicht, ob die Bearbeitung ausgeführt oder berechnet wurde; die Verbindung kann nach der Abrechnung beim Schreiben des Ergebnisses abbrechen. Sende den POST nicht automatisch erneut. Prüfe zuerst Verbrauchsdaten oder Request-Protokolle und sichere die zurückgegebene Request-ID sowie, falls vorhanden, die Header X-BetterToken-Image-Receipt und X-BetterToken-Billing-State. Eine clientseitig erzeugte Request-ID macht den Request nicht idempotent; einen Status-Endpunkt gibt es nicht.
Behebe abgelehnte Eingaben, Authentifizierungs- oder Kontingentprobleme vor einem erneuten Senden. Wiederhole 429 mit Backoff nur, wenn die Ablehnung bestätigt ist. BetterToken kann den höchsten anwendbaren Stückpreis multipliziert mit n vorautorisieren. Das Guthaben kann für das gelieferte 1K-Bild reichen, aber nicht für die Reservierung; dann folgt 403 mit error.code=insufficient_user_quota. Der endgültige Betrag richtet sich nach den gelieferten Bildern.
Integrationscheckliste
- Die Base URL ist
https://bettertoken.ai/v1. - Der Header enthält
Authorization: Bearer sk-.... - Die Anfrage verwendet
multipart/form-data. - Wähle eine für diese Anfrage verfügbare Model ID:
gpt-image-2,gpt-image-2.5-flareodergpt-image-2.5-sunburst. - Nutze
imagefür eine Referenz oder wiederholteimage[]-Felder für mehrere. - Sende für Maskenbearbeitung eine
maskmit demselben Format und denselben Abmessungen wie das Original sowie einem Alpha-Kanal. - Verwende
response_format=b64_json.output_formatist ein angeforderter Wert; erkenne vor dem Speichern das tatsächliche Format anhand der Bytes. nakzeptiert Ganzzahlen von1bis10. Beginne mit1; es können weniger Bilder zurückkommen.- Lasse
sizeweg, nutzeautooder Abmessungen, die die Vorgaben erfüllen. - Der HTTP-Client erlaubt mehrere Minuten Wartezeit für die Generierung.
- Protokolle und Fehler-Screenshots legen weder den API Key noch den vollständigen Base64-Bildinhalt offen.
Verwandte Dokumentation
/v1/images/editsAutorisierungen
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body multipart/form-data
GPT Image Model ID. One BetterToken API Key works with all available models.
"gpt-image-2"Instructions for editing the image or generating from reference images.
"Use this reference image to create a more polished square product hero image while preserving the main style."The reference image field for a single input image.
Repeat this field for each input when sending multiple reference images.
An optional single mask file. The mask and original image must have the same format and dimensions, each file must be smaller than 50 MB, and the mask must contain an Alpha channel. For maximum compatibility, use PNG with an Alpha channel for both files. With multiple image[] inputs, the mask applies to the first image. Availability depends on the model and size combination. Ordinary reference-image edits do not require a mask. A mask guides generation but does not guarantee that pixels outside the target area remain unchanged; review the result.
Allowed range: 1–10; start with 1. Fewer images may be delivered than requested. Iterate data[] and use actual-delivery billing.
"1"Omit or use auto for automatic sizing. For WxH, both dimensions must be positive multiples of 16, each at most 3840, aspect ratio at most 3:1, total pixels 655360–8294400. Examples are not an exhaustive enum; 2080x2080 also meets the geometry rules. Inspect actual decoded dimensions. Valid parameters do not guarantee an available service.
"1024x1024"["auto","1024x1024","2048x2048","2080x2080","3840x2160"]Requested output format; png is recommended, but the response is not guaranteed to have been transcoded to PNG. Detect PNG, JPEG, or WebP from actual bytes before choosing an extension. Convert locally if a specific format is required.
"png"gpt-image-2 accepts auto, low, medium, high. The two 2.5 models also accept xhigh and max. Omit for the model default; JSON null is treated as omitted, while multipart requires a nonempty string. Valid values do not guarantee an available service for every model, size, and editing combination. Acceptance does not guarantee that a higher setting improves image quality.
"auto"Antwort
200BetterToken billing extension. Settlement follows the actual delivered pixels and billing tier, which can differ from the requested tier. Amounts are decimal strings; use the returned values.
OpenAI-compatible image response. Iterate data[] and read each image from b64_json. Fewer images may be delivered than requested.
1710000000Show child attributes
An optional revised prompt.
BetterToken billing extension. Settlement follows the actual delivered pixels and billing tier, which can differ from the requested tier. Amounts are decimal strings; use the returned values.
Show child attributes
Settlement currency; do not assume a fixed currency.
Final request amount as a decimal string; use decimal arithmetic for calculations.
Delivered image indices, actual dimensions, billing tiers, and per-image amounts. index is zero-based and corresponds to data[].
Settled amount for this image as a decimal string.
Resolution tier inferred from the request; it may differ from the actual billing tier.
{
"created": 1710000000,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA...(truncated)",
"revised_prompt": "<string>"
}
],
"bettertoken_image_billing": {
"currency": "<string>",
"settled_amount": "<string>",
"outputs": [
{
"index": 0,
"width": 1,
"height": 1,
"billing_resolution": "1K",
"currency": "<string>",
"amount": "<string>"
}
],
"partial": false,
"requested_resolution": "<string>"
}
}400Invalid request format, missing parameters, malformed JSON or multipart data, or invalid dimensions.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}401The BetterToken API Key is missing or invalid.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}402The account has insufficient credit or balance.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}403Insufficient balance or token quota: error.code is insufficient_user_quota. Funds must also cover the reservation of the highest-tier unit price times the image-count upper bound, before actual-delivery settlement. Inspect error.code rather than treating every 403 as an authorization error.
{
"error": {
"code": "insufficient_user_quota",
"message": "Insufficient balance or token quota."
}
}429A rate or concurrency limit was reached, or the upstream service is busy.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}500The gateway or upstream service returned an error.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}
