HiAPI
Blog

Tutorial

So verwendest du seedream-5.0-lite Image-to-Image über die hiapi API

Jul 7, 2026
So verwendest du seedream-5.0-lite Image-to-Image über die hiapi API

Dieses Tutorial zeigt dir, wie du über die einheitliche Task-API von hiapi den Image-to-Image-Modus von seedream-5.0-lite aufrufst: die genaue Request-Struktur, direkt ausführbare curl-Befehle, ein Python-Skript für dein Backend und die Validierungsfallen, die dieses Modell erzwingt und andere Modelle nicht.

Nach dem Lesen dieses Artikels hast du ein Skript, das eine oder mehrere Referenzbild-URLs und einen Bearbeitungsprompt entgegennimmt und eine sofort herunterladbare URL des generierten Bildes zurückgibt.

Was du vorbereiten musst

  • Ein hiapi-Konto und einen API-Schlüssel. Du findest ihn in der hiapi-Konsole.
  • Ein oder mehrere Referenzbilder, die unter einer öffentlichen HTTPS-URL gehostet werden. Dieses Modell akzeptiert bis zu 14 Referenzbilder pro Anfrage — genau das macht es für Multi-Referenz-Workflows nützlich: das Motiv aus einem Bild mit Stil oder Szene eines anderen Bildes zu verschmelzen.
  • Einen Textprompt, der die Bearbeitung oder Transformation beschreibt (mindestens 3 Zeichen — ja, die API validiert das).

Alle Requests gehen an den einheitlichen Task-Endpunkt, der Schlüssel kommt in den Authorization-Header:

POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json

Request-Struktur (und die Anforderungen dieses Modells)

Die Modell-ID lautet seedream-5.0-lite/image-to-image — übergebe sie genau so, wie sie in /v1/models aufgeführt ist. Das input-Schema ist streng: alle vier Felder sind Pflichtfelder:

Feld Typ Beschreibung
prompt string Bearbeitungsanweisung. Minimale Länge 3.
image_urls string[] 1–14 Referenzbild-URLs.
aspect_ratio string Einer der Werte 1:1, 4:3, 3:4, 16:9, 9:16, 2:3, 3:2, 21:9.
resolution string Nur 2K oder 4K. Dieses Modell hat keine 1K-Stufe.

Wer von anderen Modellen der Plattform migriert, tappt oft in zwei Fallen:

  1. resolution akzeptiert nur 2K oder 4K. Wenn dein gemeinsamer Task-Submit-Code standardmäßig "1K" einträgt (was bei vielen anderen Bildmodellen funktioniert), lehnt dieses Modell mit 400 ab.
  2. Überflüssige Felder werden abgelehnt, nicht ignoriert. Wenn du size, n oder irgendetwas außerhalb des Schemas sendest, kommt 400 INVALID_REQUEST mit additional properties '<field>' not allowed zurück. Die Task-API validiert input pro Modell — verwende nicht blind das Payload eines anderen Modells erneut.

Minimales lauffähiges Beispiel: curl

Task erstellen:

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-5.0-lite/image-to-image",
    "input": {
      "prompt": "Replace the background with a sunlit Tokyo street at golden hour, keep the subject unchanged",
      "image_urls": ["https://your-cdn.example.com/subject.png"],
      "aspect_ratio": "3:2",
      "resolution": "2K"
    }
  }'

Nach erfolgreicher Übermittlung wird in data eine Task-ID zurückgegeben:

{"code": 200, "data": {"taskId": "task_abc123..."}}

Ergebnis abfragen:

curl https://api.hiapi.ai/v1/tasks/task_abc123 \
  -H "Authorization: Bearer sk-<your-key>"

Während der Ausführung ist data.status pending/processing. Nach Abschluss wird es zu "success", und das Bild erscheint in data.output:

{
  "code": 200,
  "data": {
    "status": "success",
    "output": [{"url": "https://.../result.png", "expireAt": "..."}]
  }
}

Ausgabe-URLs sind kurzlebig (beachte expireAt). Lade die Bytes sofort herunter und speichere sie selbst — kein Hotlinking und keine Persistenz der Original-URL.

Mehrere Referenzbilder: mehrere Bilder übergeben

Um mehrere Referenzbilder zu verschmelzen — etwa ein Produktbild plus ein Stil-Referenzbild — fügst du einfach weitere URLs zu image_urls hinzu und erklärst im Prompt, welchen Beitrag jedes Bild leistet:

{
  "model": "seedream-5.0-lite/image-to-image",
  "input": {
    "prompt": "Place the product from the first image into the scene from the second image, matching its lighting and color grade",
    "image_urls": [
      "https://your-cdn.example.com/product.png",
      "https://your-cdn.example.com/scene-reference.jpg"
    ],
    "aspect_ratio": "1:1",
    "resolution": "2K"
  }
}

Die harte Obergrenze sind 14 URLs; die 15. führt zu 400 INVALID_REQUEST: image_urls: maxItems: got 15, want 14. In der Praxis ergeben 2–4 sorgfältig ausgewählte Referenzbilder mit einem Prompt, der jedem Bild explizit eine Rolle zuweist („Behalte das Motiv aus Bild 1 bei, übernimm die Farbpalette von Bild 2“), deutlich kontrollierbarere Bearbeitungen als ein Haufen lose zusammenhängender Bilder.

Für präzise, gezielte Bearbeitungen eines einzelnen Bildes — Hintergrund wechseln, Kleidung ändern, Objekte entfernen — verwende eine Referenz-URL und gib sowohl an, was geändert als auch was beibehalten werden soll („Gesicht und Pose unverändert lassen“). Seedream-Modelle befolgen Beibehaltungsanweisungen gut; explizite Angaben sind der Schlüssel zur Unterscheidung zwischen präziser Bearbeitung und vollständiger Neuinterpretation.

Produktionsreifes Python: Senden, Abfragen, Herunterladen

import time
import requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}


def edit_image(prompt: str, image_urls: list[str],
               aspect_ratio: str = "1:1", resolution: str = "2K") -> bytes:
    # 1. Task erstellen
    resp = requests.post(API_BASE, headers=HEADERS, json={
        "model": "seedream-5.0-lite/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,
            "aspect_ratio": aspect_ratio,
            "resolution": resolution,  # dieses Modell: nur "2K" oder "4K"
        },
    }, timeout=60)
    body = resp.json()
    if resp.status_code != 200 or not (body.get("data") or {}).get("taskId"):
        raise RuntimeError(f"create failed [{resp.status_code}]: {body}")
    task_id = body["data"]["taskId"]

    # 2. Abfragen bis zum Endzustand
    deadline = time.time() + 600
    while time.time() < deadline:
        task = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS,
                            timeout=30).json().get("data") or {}
        if task.get("status") == "success":
            outputs = task.get("output") or []
            if not outputs or not outputs[0].get("url"):
                raise RuntimeError(f"task {task_id} succeeded but returned no output URL")
            # 3. Sofort herunterladen — die URL läuft ab
            img = requests.get(outputs[0]["url"], timeout=120)
            img.raise_for_status()
            return img.content
        if task.get("status") == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(5)
    raise TimeoutError(f"task {task_id} still running after 600s")


if __name__ == "__main__":
    png = edit_image(
        "Replace the background with a minimalist studio backdrop, keep the subject unchanged",
        ["https://your-cdn.example.com/subject.png"],
        aspect_ratio="3:2",
    )
    with open("edited.png", "wb") as f:
        f.write(png)
    print(f"saved edited.png ({len(png)} bytes)")

Callbacks statt Polling verwenden

Polling ist für Skripte und Worker-Queues in Ordnung. Für Web-Backends registriere beim Erstellen des Tasks einen Callback, damit hiapi dir den Endzustand zustößt — das callback-Objekt liegt auf der obersten Request-Ebene direkt neben model:

{
  "model": "seedream-5.0-lite/image-to-image",
  "input": { "...": "..." },
  "callback": {
    "url": "https://your-app.example.com/hooks/hiapi",
    "when": "final"
  }
}

Mit "when": "final" erhältst du nur ein einziges POST, wenn der Task success oder fail erreicht. Für den Handler gelten zwei Regeln:

  • Mach ihn idempotent. Verwende die Task-ID als Verarbeitungsschlüssel, damit doppelt zugestellte Webhooks keine doppelte Verarbeitung auslösen. Speichere die Task-ID beim Senden und behandle den Callback als Benachrichtigung „jetzt abholen und abschließen“, nicht als einzige Wahrheitsquelle.
  • Behalte den Abgleichpfad bei. Wenn dein Endpunkt beim Auslösen des Callbacks down ist, kannst du verpasste Fälle durch regelmäßiges Scannen unvollständiger IDs und GET /v1/tasks/<id> abfangen.

Wenn dein Callback scheinbar nie ankommt, arbeite die häufigen Fehlermuster in Warum dein hiapi-Task-Callback nicht ausgelöst wird nach Wahrscheinlichkeit geordnet durch.

Fehlerbehandlung: die drei wirklich wichtigen Fehler

401 permission_denied beim Erstellen — dein Schlüssel kann dieses Modell nicht verwenden. Der Response-Body sieht so aus:

{"error": {"code": "permission_denied", "message": "This API key cannot use the selected model...", "type": "hiapi_error"}}

Prüfe die Modellberechtigungen des Schlüssels in der Konsole oder verwende einen Schlüssel, der Bildmodelle freigeschaltet hat.

400 INVALID_REQUEST beim Erstellen — dein input passt nicht zum Schema dieses Modells. Die Meldung listet alle fehlerhaften Felder auf einmal auf (z. B. resolution: value must be one of '2K', '4K'; <root>: additional properties 'size' not allowed), lies sie also vollständig und korrigiere alle Felder auf einmal. Das sind dauerhafte Fehler — das erneute Senden desselben Payloads wird immer fehlschlagen.

status: "fail" am Task — die Erstellung war erfolgreich, aber die Generierung ist fehlgeschlagen (vom Backend nicht abrufbare Referenz-URL, Inhaltsrichtlinien, Upstream-Kapazität). Die Felder error.code und error.message des Tasks nennen den Grund. Anders als bei 400 sind einige davon vorübergehend und es lohnt sich, einmal mit Backoff erneut zu versuchen.

Ebenfalls wissenswert: Ein GET auf eine nicht existierende oder abgelaufene Task-ID gibt 404 task not found zurück — das solltest du bei Abgleich-Scans als Endzustand behandeln, nicht als „wartet noch“.

Wo du als Nächstes weitermachen kannst

FAQ

Wie viele Referenzbilder kann ich an seedream-5.0-lite Image-to-Image übergeben? Das image_urls-Array akzeptiert maximal 14 Bilder. Mindestens eines — das Feld ist Pflicht, daher solltest du für reine Text-to-Image-Aufrufe seedream-5.0-lite/text-to-image verwenden.

Warum bekomme ich „value must be one of '2K', '4K'“, obwohl andere Modelle 1K können? Das input-Schema der Task-API wird pro Modell definiert. Der Image-to-Image-Modus von seedream-5.0-lite bietet nur 2K- und 4K-Ausgaben; andere Modelle bieten eine 1K-Stufe. Verwende nicht ohne Prüfung das Payload eines anderen Modells erneut.

Kann ich Referenzbilder als Base64 statt als URL senden? Das Schema dieses Modells akzeptiert image_urls — ein Array von URLs. Hoste die Bilder unter einer erreichbaren HTTPS-URL (jedes CDN, jeder Object-Storage-Bucket oder eine vorab signierte URL funktioniert) und übergib diese URL.

Wie lange dauert eine Generierung und wie lange ist die Ausgabe-URL gültig? In der Regel weit unter dem 600-Sekunden-Polling-Budget des obigen Python-Beispiels. Die Ausgabe-URL trägt einen expireAt-Zeitstempel — lade die Bytes sofort nach erfolgreichem Task herunter und speichere sie in deinem eigenen Speicher.

Funktioniert derselbe Code für seedream-5.0-lite Text-to-Image? Endpunkt und Ablauf sind gleich, aber Text-to-Image hat ein eigenes input-Schema (ohne image_urls). Wechsle die Modell-ID auf seedream-5.0-lite/text-to-image und entferne die Referenzbilder — validiere das dann mit einem Testaufruf, da sich die Pflichtfelder je Modus unterscheiden.

Was kostet ein Bild? Die Preisgestaltung richtet sich nach dem Nutzungsvolumen pro Generierung und variiert je nach Auflösung. Die aktuellen Tarife findest du auf der Preisseite.

Ähnliche Artikel

Alle Artikel ansehen →

Starte mit persistenten KI-Artefakten

Hol dir deinen API-Key und rufe Bild-, Video- und Audiomodelle über eine einzige task-basierte API auf.

API-Dokumentation lesen