Bildgenerierung

POST /v1/images/generations — OpenAI-kompatible Text-zu-Bild-Generierung. In dieser Phase ohne PII-Maskierung.

Überblick

Der Endpunkt POST /v1/images/generations erzeugt Bilder aus einem Text-Prompt — OpenAI-kompatibel, über dieselbe Base-URL https://api.noirdoc.de/v1 und denselben px--Key wie alle anderen Proxy-Endpunkte. Als model verwenden Sie die Modell-ID aus dem Katalog (GET /v1/models oder Portal); das Modell muss ein Bildmodell sein.

Bildbearbeitung (/v1/images/edits) wird derzeit nicht unterstützt.

Keine Maskierung in dieser Phase

Bildanfragen werden nicht maskiert. Der Prompt erreicht den Modell-Provider unverändert im Klartext. Details unter Keine PII-Maskierung.

Anfrage

curl -X POST https://api.noirdoc.de/v1/images/generations \
  -H "Authorization: Bearer px-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<model-id>",
    "prompt": "Ein Leuchtturm an der Nordseeküste bei Sonnenaufgang",
    "size": "1024x1024",
    "n": 1
  }'

Mit dem OpenAI-SDK genügt es wie gewohnt, base_url und api_key zu tauschen:

import base64

from openai import OpenAI

client = OpenAI(base_url="https://api.noirdoc.de/v1", api_key="px-...")

response = client.images.generate(
    model="<model-id>",
    prompt="Ein Leuchtturm an der Nordseeküste bei Sonnenaufgang",
    size="1024x1024",
    n=1,
)

with open("bild.png", "wb") as f:
    f.write(base64.b64decode(response.data[0].b64_json))

Request-Body:

FeldTypErforderlichBeschreibung
modelstringJaModell-ID aus dem Katalog — muss ein Bildmodell sein
promptstringJaDie Bildbeschreibung — darf nicht leer sein
nintNeinAnzahl der Bilder, 1–10 (Standard 1). Viele Modelle erlauben nur n: 1
sizestringNeinFormat BREITExHÖHE, jede Dimension 1–2048, z. B. 1024x1024

Die Grenzen für n und size prüft Noirdoc vor der Weiterleitung und lehnt Verstöße mit HTTP 400 und dem Code invalid_image_request ab. Der Wert "size": "auto" wird dabei ebenfalls abgelehnt — geben Sie eine konkrete Auflösung an oder lassen Sie das Feld weg.

Welche Werte ein Modell tatsächlich akzeptiert, ist enger als diese Grenzen und hängt vom Modell ab: manche Modelle erzeugen nur ein Bild pro Anfrage, andere erlauben nur bestimmte Auflösungen oder Vielfache von 16. Lehnt der Provider die Kombination ab, erhalten Sie dessen Fehler als provider_error zurück.

Weitere OpenAI-Felder sowie providerspezifische Erweiterungen (z. B. negative_prompt, quality, output_format) reicht der Proxy unverändert an den Provider durch; ob sie unterstützt werden, hängt vom jeweiligen Modell und Provider ab.

Hinweis: Das Feld stream wird für die Bildgenerierung nicht unterstützt; eine Anfrage mit "stream": true wird mit HTTP 400 und dem Code streaming_not_supported_for_endpoint abgelehnt.

Antwort

Die Antwort ist das OpenAI-kompatible Image-Objekt, wie es der Upstream-Provider liefert — Noirdoc reicht sie unverändert durch. Die Bilddaten stehen Base64-kodiert in data[].b64_json:

{
  "created": 1735689600,
  "data": [{ "b64_json": "iVBORw0KGgoAAAANSUhEUg..." }]
}

Ein usage-Objekt liefern die Bildmodelle nicht zuverlässig; einige lassen es weg, andere melden Nullwerte. Die Abrechnung erfolgt deshalb nicht über Token, sondern je erzeugtem Bild bzw. je Megapixel — abhängig vom Modell. Ihren Bildverbrauch sehen Sie in der Nutzungsübersicht im Portal.

Keine PII-Maskierung in dieser Phase

Die Maskierung gilt in dieser Phase nicht für /v1/images/generations. Konkret bedeutet das:

  • Der Prompt erreicht den Modell-Provider im Klartext. Die PII-Pipeline (Erkennung, Pseudonymisierung, Wiederherstellung) wird für Bildanfragen vollständig übersprungen. Ein expliziter X-Noirdoc-Mask: on-Header wird stattdessen mit HTTP 403 abgelehnt, um zu verhindern, dass Maskierung still übersprungen wird.
  • Das Audit-Log bleibt aktiv und vermerkt für jede Bildanfrage mask_applied=false.
  • Organisationen mit der Richtlinie enforced können den Endpunkt nicht nutzen. Statt eine Anfrage unmaskiert weiterzuleiten, blockiert der Proxy sie mit HTTP 403:
{
  "error": {
    "type": "proxy_error",
    "code": "masking_not_supported_for_endpoint",
    "message": "Masking is not available on '/v1/images/generations', and this tenant's mask policy requires masking on all traffic. Contact your administrator."
  }
}

Anders als bei Text ist Maskierung hier nicht nur eine Frage der Erkennung: ein Pseudonym wie <<PERSON_1>> müsste im erzeugten Bild dargestellt und anschließend wieder ersetzt werden — dafür gibt es keine sinnvolle Rückabbildung. Bis auf Weiteres gilt daher: Senden Sie keine personenbezogenen Daten in Bild-Prompts.

Modell und Endpunkt müssen zusammenpassen

Jedes Katalog-Modell gehört zu genau einer Endpunkt-Familie — etwa chat, embeddings oder Bildgenerierung. Passen Modell und Endpunkt nicht zusammen, gibt die API 400 mit dem Code wrong_endpoint_for_model zurück. Das gilt in beide Richtungen:

  • ein Chat-Modell auf /v1/images/generations400
  • ein Bildmodell auf /v1/chat/completions oder /v1/responses400
{
  "error": {
    "type": "proxy_error",
    "code": "wrong_endpoint_for_model",
    "message": "Model '<model-id>' cannot be called from this endpoint; use the endpoint matching its provider's API format."
  }
}

Welche Modelle Bildmodelle sind, zeigt der Katalog-Endpunkt GET /v1/models bzw. das Portal.

Nächste Schritte

  • Proxy-Endpunkte — alle unterstützten Pfade
  • Fehlercodes — alle Fehlercodes der API
  • Maskierung — wie die Pseudonymisierung bei Chat-Anfragen funktioniert und wie Sie sie steuern