Felo API PlatformFelo API Platform

Leitfäden

Bildgenerierung

Generieren und bearbeiten Sie Bilder asynchron: Reichen Sie eine Aufgabe ein, fragen Sie den Abschluss ab und laden Sie signierte Ausgabe-URLs herunter.

Die Felo-Bild-API erzeugt und bearbeitet Bilder mit Modellen aus dem Felo-Modellkatalog. Sie arbeitet asynchron: Die Übermittlung gibt sofort eine Aufgaben-ID zurück, und Sie fragen die Aufgabe ab, bis sie einen Endzustand erreicht.

Diese Seite behandelt den bildspezifischen Vertrag. Den gemeinsamen Aufgaben-Lebenszyklus finden Sie unter Asynchrone Aufgaben.

Bevor Sie beginnen

Unterschiede zur OpenAI Images API

Der Pfad ähnelt der Images API von OpenAI. Die Antwort nicht:

OpenAI Images APIFelo Image API
Antwort auf das Senden200 mit den Bilddaten202 mit task_id, status: "queued"
Wann das Bild vorliegtIn der Antwort auf das SendenNachdem die Abfrage succeeded erreicht
Bild-Payloadb64_json oder urlEine zeitlich begrenzte signierte url
AnfragefehlerHTTP-Fehler beim SendenNormalerweise status: "failed" bei der Aufgabe

Senden Sie openai.images.generate() nicht an diesen Endpoint. Das SDK erwartet ein synchrones data-Array und kann eine Aufgabe nicht abfragen. Rufen Sie den Endpoint über HTTP auf und fragen Sie die Aufgabe ab, oder schreiben Sie einen kleinen Wrapper für beide Schritte.

Aufgabe senden

curl -X POST "https://openapi.felo.ai/api/v1/images/generations" \
  -H "Authorization: Bearer ${FELO_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3-pro-image",
    "prompt": "A studio product photo of a ceramic coffee cup on warm linen, soft morning light",
    "resolution": "2K",
    "aspect_ratio": "4:3"
  }'

Eine erfolgreiche Übermittlung gibt HTTP 202 zurück:

{
  "task_id": "6d1f0c9a-...",
  "status": "queued",
  "kind": "image",
  "outputs": []
}

202 bedeutet, dass die Plattform die Aufgabe angenommen hat. Es bedeutet nicht, dass der Prompt, die Parameter oder die Referenzbilder gültig sind. Der Upstream-Aufruf läuft nach der Antwort, daher erscheinen die meisten Anfrageprobleme später als fehlgeschlagene Aufgabe. Eine Ausnahme ist das Modell-Routing: Ein Chat- oder Videomodell wird bereits beim Senden abgelehnt.

Abfragen, bis die Aufgabe einen Endstatus erreicht

curl "https://openapi.felo.ai/api/v1/images/generations/${TASK_ID}" \
  -H "Authorization: Bearer ${FELO_API_KEY}"
StatusBedeutungWas Sie tun sollten
queuedAngenommen; wartet auf den StartWeiter abfragen
runningDas Modell generiertWeiter abfragen
succeededEndstatus; outputs ist gefülltDie Ausgaben herunterladen
failedEndstatus; lesen Sie error.messageKorrigieren Sie die Anfrage; wiederholen Sie sie nicht unverändert
interruptedEndstatus; das Ergebnis konnte nicht wiederhergestellt werdenAufgabe erneut senden

Fehler einer Aufgabe behalten den HTTP-Status 200. Prüfen Sie status im Textkörper, nicht nur den HTTP-Status.

Beginnen Sie mit einem Intervall von 2–5 Sekunden und erhöhen Sie die Wartezeit. Die meisten Bilder sind innerhalb einer Minute fertig; 4K-Ausgaben und Bearbeitungen mit vielen Referenzbildern dauern länger. Legen Sie immer eine eigene Frist fest.

import os
import time

import requests

BASE = "https://openapi.felo.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['FELO_API_KEY']}"}


def generate_image(prompt: str, **params) -> list[dict]:
    response = requests.post(
        f"{BASE}/api/v1/images/generations",
        headers=HEADERS,
        json={"model": "gemini-3-pro-image", "prompt": prompt, **params},
        timeout=30,
    )
    response.raise_for_status()
    task = response.json()

    deadline = time.monotonic() + 300
    delay = 2.0
    while time.monotonic() < deadline:
        time.sleep(delay)
        delay = min(delay * 1.5, 10.0)

        poll = requests.get(
            f"{BASE}/api/v1/images/generations/{task['task_id']}",
            headers=HEADERS,
            timeout=30,
        )
        poll.raise_for_status()
        task = poll.json()

        if task["status"] == "succeeded":
            return task["outputs"]
        if task["status"] in {"failed", "interrupted"}:
            message = task.get("error", {}).get("message", task["status"])
            raise RuntimeError(message)

    raise TimeoutError(f"image task {task['task_id']} did not finish")

Ausgaben lesen und speichern

Wenn die Aufgabe erfolgreich ist, enthält outputs einen Eintrag pro erzeugtem Bild:

{
  "task_id": "6d1f0c9a-...",
  "status": "succeeded",
  "kind": "image",
  "outputs": [
    {
      "media_type": "image/png",
      "url": "https://openapi.felo.ai/api/v1/media/...?exp=...&sig=..."
    }
  ]
}
  • outputs ist leer, bis die Aufgabe erfolgreich ist.
  • url ist eine signierte URL. Sie lässt sich ohne API-Schlüssel herunterladen; behandeln Sie sie daher wie einen Bearer-Link.
  • Die URL ist zeitlich begrenzt. Der Query-Parameter exp ist ihr Ablaufzeitpunkt. Laden Sie die Datei herunter und speichern Sie sie in Ihrem eigenen Bucket oder Dateisystem; die Aufgabe ist kein dauerhafter Speicher.
  • Eine erneute Abfrage nach Ablauf der URL gibt dieselbe abgelaufene URL zurück. Sie stellt keine frische URL aus.
  • Die Antwort enthält keine Base64-Bilddaten.
for index, output in enumerate(outputs):
    image = requests.get(output["url"], timeout=60)
    image.raise_for_status()
    with open(f"image-{index}.png", "wb") as file:
        file.write(image.content)

Bild bearbeiten

Übergeben Sie Referenzbilder in input_references. Das Modell verwendet sie als Kontext; der Prompt beschreibt weiterhin die Änderung.

curl -X POST "https://openapi.felo.ai/api/v1/images/generations" \
  -H "Authorization: Bearer ${FELO_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3-pro-image",
    "prompt": "Keep the product and framing. Replace the background with a sunlit marble countertop.",
    "resolution": "2K",
    "aspect_ratio": "4:3",
    "input_references": [
      {
        "type": "image_url",
        "image_url": {"url": "https://example.com/product.png"}
      }
    ]
  }'

Jede Referenz ist eine HTTP(S)-URL oder eine Base64-Daten-URL. Die Reihenfolge der Referenzen bleibt erhalten; beziehen Sie sich im Prompt anhand der Position auf Bilder, wenn dies wichtig ist. Die aktuellen Modelle akzeptieren bis zu 14 Referenzen.

Anfragefelder

FeldErforderlichBeschreibung
modelJaModell-ID aus dem Katalog, zum Beispiel gemini-3-pro-image. Verwenden Sie nicht die Upstream-ID google/...
promptJaTextanweisung. Beschreiben Sie bei einer Bearbeitung die Änderung und was gleich bleiben soll
resolutionNeinAusgabestufe. Aktuelle Modelle akzeptieren 1K, 2K oder 4K
aspect_ratioNeinAusgabeverhältnis. Die akzeptierten Werte hängen vom Modell ab
nNeinAnzahl der Bilder. Aktuelle Modelle akzeptieren 1
input_referencesNeinReferenzbilder für Bearbeitung oder Komposition

Aktuelle Bildmodelle:

Modell-IDAuflösungenSeitenverhältnisseBilder pro AufgabeReferenzen
gemini-3-pro-image1K, 2K, 4K1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:91Bis zu 14
gemini-nano-banana-2.11K, 2K, 4K1:1, 1:4, 1:8, 2:3, 3:2, 3:4, 4:1, 4:3, 4:5, 5:4, 8:1, 9:16, 16:9, 21:91Bis zu 14

Um einen Anbieter zu binden, senden Sie den Header X-Felo-Channel mit einem Kanalcode aus der channels-Liste des Modells. Siehe Kanäle und Anbieter-Routing.

Bildmodell finden

Es gibt keinen eigenen Listen-Endpoint für Bildmodelle. Fragen Sie den allgemeinen Katalog ab und filtern Sie nach model_kind:

curl "https://openapi.felo.ai/api/v1/models" \
  -H "Authorization: Bearer ${FELO_API_KEY}" \
  | jq '.data[] | select(.model_kind == "image_generation") | {id, name}'

GET /api/v1/models/{model_id} gibt die Kanäle und veröffentlichten Tarife des Modells zurück.

supported_parameters im allgemeinen Katalog ist eine Liste auf Protokollebene. Bei Bildmodellen zählt sie die oben genannten Bildfelder nicht zuverlässig auf; bauen Sie Ihre Anfrage daher nicht darauf auf. Verwenden Sie die Feldtabelle in dieser Anleitung und bestätigen Sie die Modell-ID anhand des Katalogs.

Preise

Die Bildgenerierung wird nach den veröffentlichten Tarifen des Modells abgerechnet. Der Katalog stellt input_image und output_image neben den Text-Tarifen prompt und completion bereit. Die Bild-Tarife sind Token-Tarife: resolution beeinflusst, wie viele Ausgabe-Bild-Token ein Bild verbraucht, sodass ein 4K-Bild mehr kostet als ein 1K-Bild. Referenzbilder fügen Eingabe-Bild-Token hinzu.

Die Aufgabenantwort enthält kein usage-Objekt. Prüfen Sie die Berechnung in Console Billing.

Eine Aufgabe, die mit failed oder interrupted endet, erzeugt keine Ausgabe und wird nicht abgerechnet. Eine mit 402 abgelehnte Übermittlung hat keine Aufgabe erstellt.

Fehler

Fehler auf Endpoint-Ebene aus der Bildroute verwenden das OpenAI-Fehlerformat:

{
  "error": {
    "message": "Model kind does not match this generation endpoint",
    "type": "invalid_request_error",
    "param": null,
    "code": "model_kind_mismatch"
  }
}

Die Request-ID steht im Antwort-Header X-Request-Id. Protokollieren Sie sie zusammen mit der Aufgaben-ID.

HTTPerror.codeBedeutung
400invalid_request_errormodel fehlt, oder der Textkörper ist kein JSON-Objekt
400model_not_configuredDie Modell-ID ist nicht im aktivierten Katalog
400chat_model_not_allowedEin Chat-Modell wurde an den Bild-Endpoint gesendet
400model_kind_mismatchEin Video- oder anderes Nicht-Bildmodell wurde gesendet
402insufficient_balanceNicht genügend Guthaben; es wurde keine Aufgabe erstellt
404generation_task_not_foundDie Aufgaben-ID ist unbekannt oder gehört zu einem anderen Konto
429daily_spend_limit_exceededDas tägliche Ausgabenlimit des Kontos wurde erreicht
503generation_unavailableDie Generierung ist vorübergehend nicht verfügbar; versuchen Sie es später erneut

Authentifizierungsfehler werden unter Fehler, Limits und Wiederholungen beschrieben.

Verwandte Themen