HiAPI
Blog

Tutorial

So nutzt du 851-labs/background-remover über die hiapi API: curl, Python und lauffähige Requests

Sep 5, 2026
So nutzt du 851-labs/background-remover über die hiapi API: curl, Python und lauffähige Requests

851-labs/background-remover verwandelt Produkt-, Porträt- oder Tierfotos mit nur einem API-Aufruf in transparente PNGs – ohne Prompt, ohne Maske, ohne Seitenverhältnis-Einstellung. Dieser Artikel beschreibt die genaue Request-Struktur, einen lauffähigen curl-Befehl, ein Python-Skript, das du direkt ins Backend übernehmen kannst, und einen Schema-Fehler, in den fast jeder einmal tappt.

Vorbereitung

  • Ein hiapi-Konto und ein API-Key aus der Konsole.
  • Ein Bild, das unter einer öffentlichen HTTPS-URL gehostet wird. Die Task-API nimmt URLs entgegen, keine Datei-Uploads – wenn dein Quellbild nur lokal vorliegt, lade es zuerst auf ein beliebiges CDN oder einen Objektspeicher hoch.

Alle Requests gehen an den einheitlichen Task-Endpunkt:

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

Die Request-Struktur (und die einzige Regel, die du dir merken musst)

Die Modell-ID lautet 851-labs/background-remover und wird unverändert übergeben. Das input-Schema hat nur ein einziges Feld:

Feld Typ Erforderlich Beschreibung
image_url string ja Muss ^https?://[^\s]+$ entsprechen – eine direkt erreichbare http(s)-URL.

Das ist das gesamte Schema. Bevor du eine Zeile Code schreibst, solltest du zwei Dinge wissen:

  1. Es gibt kein prompt-, mask-, background-color- oder aspect-ratio-Feld. Dieser Endpunkt macht genau eine Sache – Vordergrund-/Hintergrundtrennung – und sonst nichts. Wenn du später neu einfärben oder skalieren musst, ist dafür ein weiterer Aufruf eines anderen Modells nötig.
  2. Überflüssige Felder werden abgelehnt, nicht ignoriert. Wenn du aus dem Payload eines anderen Modells ein format- oder size-Feld mitbringst, gibt der Task noch vor dem Start 400 INVALID_REQUEST: <root>: additional properties 'format' not allowed zurück.

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": "851-labs/background-remover",
    "input": {
      "image_url": "https://your-cdn.example.com/product-shot.jpg"
    }
  }'

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

{"code": 200, "data": {"taskId": "tk-hiapi-..."}}

Ergebnis abfragen:

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

Während der Ausführung durchläuft data.status nacheinander queued → handling → archiving. Nach Abschluss wird daraus "success", und das transparente PNG erscheint in data.output:

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

Die Ausgabe-URL ist nur kurzzeitig gültig (beachte expireAt). Lade die Dateibytes sofort nach Erfolg des Tasks herunter – nicht hotlinken und die Original-URL nicht dauerhaft speichern.

Produktionsreifes Python: übermitteln, 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 remove_background(image_url: str) -> bytes:
    # 1. Task erstellen
    resp = requests.post(API_BASE, headers=HEADERS, json={
        "model": "851-labs/background-remover",
        "input": {"image_url": image_url},
    }, 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() + 300
    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
            png = requests.get(outputs[0]["url"], timeout=120)
            png.raise_for_status()
            return png.content
        if task.get("status") == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(3)
    raise TimeoutError(f"task {task_id} still running after 300s")


if __name__ == "__main__":
    png = remove_background("https://your-cdn.example.com/product-shot.jpg")
    with open("cutout.png", "wb") as f:
        f.write(png)
    print(f"saved cutout.png ({len(png)} bytes)")

Hintergrundentfernung ist eine leichte Bildaufgabe und ist normalerweise weit vor der 300-Sekunden-Frist abgeschlossen – dieser Timeout ist nur ein Sicherheitsnetz, keine erwartete Laufzeit.

Callbacks statt Polling

Für ein Web-Backend empfiehlt es sich, beim Erstellen des Tasks einen Callback zu registrieren, statt im Request-Handler zu pollen. Das callback-Objekt liegt auf oberster Ebene, gleichrangig zu model:

{
  "model": "851-labs/background-remover",
  "input": { "image_url": "https://your-cdn.example.com/product-shot.jpg" },
  "callback": {
    "url": "https://your-app.example.com/hooks/hiapi",
    "when": "final"
  }
}

callback.when unterstützt nur "final" – du erhältst genau ein POST, wenn der Task success oder fail erreicht, und keine Fortschrittsereignisse. Der Handler sollte taskId als Schlüssel verwenden, damit doppelt zugestellte Webhooks nicht doppelt verarbeitet werden, und regelmäßig GET /v1/tasks/<id> durchgehen, um IDs zu prüfen, die dein Endpunkt nie bestätigt hat.

Fehlerbehandlung: die Fehler, die wirklich zählen

400 INVALID_REQUEST beim Erstellen – die Fehlermeldung nennt das genaue Feld:

Meldung Ursache
invalid input: image_url: missing required field "image_url" input ist leer oder der Schlüsselname ist falsch geschrieben
image_url: 'not-a-url' does not match pattern '^https?://[^\s]+$' Der Wert ist keine wohlgeformte http(s)-URL
<root>: additional properties 'format' not allowed Du hast ein Feld gesendet, das dieses Modell nicht akzeptiert

Diese Fehler sind dauerhaft – denselben Payload erneut zu senden wird für immer fehlschlagen. Korrigiere das Feld und sende erneut.

401 permission_denied beim Erstellen – das Problem liegt am Key selbst, nicht am Request-Body:

{"error": {"code": "permission_denied", "message": "...", "request_id": "...", "type": "hiapi_error"}}

Prüfe die Modellberechtigungen des Keys in der Konsole.

Task gibt status: "fail" zurück – die Erstellung war erfolgreich, aber die Ausführung selbst ist fehlgeschlagen (meist weil das Backend die image_url nicht abrufen konnte). Lies data.error.code / message; solche Fehler lassen sich mit Backoff einmal sicher erneut versuchen.

Ein GET auf eine unbekannte oder abgelaufene Task-ID gibt 404 mit {"code": 404, "data": null, "message": "task not found"} zurück – das solltest du in jedem Abgleich-Scan als Endzustand behandeln, nicht als „wartet noch“.

Nächste Schritte

Häufige Fragen

Brauche ich einen Prompt? Nein. Gib einfach eine image_url an, und das Modell trennt Vordergrund und Hintergrund selbst.

Ist die Ausgabe wirklich transparent? Ja – das Ergebnis ist ein PNG mit Alpha-Kanal, das direkt auf beliebige Hintergründe komponiert werden kann.

Kann ich im selben Aufruf Seitenverhältnis, Farbe oder Hintergrund ändern? Nein. Dieser Endpunkt entfernt nur den Hintergrund. Für Neufärbung, Skalierung oder Hintergrundaustausch verwende dieses transparente PNG als Eingabe und rufe in einer Kette ein Bildbearbeitungsmodell auf.

Warum bekomme ich „additional properties '...' not allowed“? Das Schema akzeptiert nur ein Feld: image_url. Jedes Feld, das aus dem Payload anderer Modelle mitgebracht wird – format, size, background_color, egal welches – wird direkt abgelehnt statt stillschweigend ignoriert.

Wie sollte ich das Ergebnis speichern? Lade es sofort herunter, nachdem der Task status: "success" erreicht hat. Die Ausgabe-URL ist eine signierte URL mit expireAt; sie eignet sich nicht zum langfristigen Hotlinken.

Was kostet es? Die Abrechnung erfolgt nach Nutzung pro Bild. 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