HiAPI
Blog

Tutorial

So verwendest du grok-imagine-quality/image-to-image über die hiapi API: curl, Python und verfügbare Anfragen

Jul 11, 2026
So verwendest du grok-imagine-quality/image-to-image über die hiapi API: curl, Python und verfügbare Anfragen

Dieser Leitfaden zeigt dir, wie du mit der einheitlichen Task-API von hiapi vorhandene Bilder mithilfe von grok-imagine-quality/image-to-image (der höher auflösenden Stufe der Grok-Imagine-Reihe) umwandelst. Du reichst ein Quellbild und einen Text-Prompt ein, fragst das Ergebnis per Polling ab und lädst das erzeugte Bild herunter. Jede unten aufgeführte Anfrage- und Antwortstruktur wurde gegen die Live-API verifiziert.

Was du brauchst

  • Einen hiapi-API-Schlüssel — erstelle einen im Dashboard.
  • Ein bis drei öffentlich erreichbare Bild-URLs als Quelle. Die Plattform ruft deine Eingabemedien serverseitig ab und normalisiert sie, daher funktionieren lokale Dateipfade und Base64-Payloads nicht — hoste die Bilder zuerst an einem für die API erreichbaren Ort.

Das ist alles. Kein SDK nötig; die Task-API ist reines HTTPS + JSON.

Anfragemodus

grok-imagine-quality/image-to-image läuft auf dem asynchronen Task-Endpunkt: Du erstellst eine Aufgabe über POST /v1/tasks und fragst dann GET /v1/tasks/<taskId> per Polling ab (oder registrierst einen Callback), bis sie abgeschlossen ist.

Das Eingabeschema ist strikt — unbekannte Felder werden mit 400 abgelehnt:

Feld Typ Erforderlich Beschreibung
prompt string ✅ Was mit dem Quellbild geschehen soll
image_urls string[] ✅ Öffentliche URLs von 1–3 Quell-/Referenzbildern
aspect_ratio string – Eines von: auto, 2:1, 20:9, 19.5:9, 16:9, 4:3, 3:2, 1:1, 2:3, 3:4, 9:16, 9:19.5, 9:20, 1:2
resolution string – 1k oder 2k — kleingeschrieben (1K gibt 400 zurück)
output_format string – jpeg, png oder webp

Beachte, was fehlt: kein size, kein n, kein seed, keine strength- oder consistency-Regler. Wie stark die Ausgabe dem Quellbild folgt, steuerst du über deinen Prompt und die übergebenen Referenzbilder — siehe FAQ unten.

Minimales funktionierendes Beispiel (curl)

Aufgabe erstellen:

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-quality/image-to-image",
    "input": {
      "prompt": "Turn this product photo into a clean studio shot on a light gray background with soft shadows",
      "image_urls": ["https://your-cdn.example.com/source.jpg"],
      "aspect_ratio": "1:1",
      "resolution": "2k",
      "output_format": "png"
    }
  }'

Eine erfolgreiche Erstellung gibt eine Task-ID zurück:

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx"
  }
}

Frage per Polling ab, bis die Aufgabe einen Endzustand erreicht:

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

Während der Ausführung ist data.status in Bearbeitung; nach Abschluss wird es success und das Bild befindet sich in data.output:

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx",
    "status": "success",
    "output": [
      {
        "url": "https://.../result.png?...&expireAt=...",
        "expireAt": 1760000000
      }
    ]
  }
}

⚠️ Ausgabe-URLs sind temporär (beachte expireAt). Lade die Bytes sofort nach erfolgreichem Abschluss der Aufgabe herunter und speichere sie in deinem eigenen Speicher — verlinke die Ergebnis-URL nicht per Hotlink.

Wenn eine Aufgabe fehlschlägt, ist data.status fail und data.error enthält code und message.

Python: Erstellen, Polling, Herunterladen

Ein vollständiges Skript, das nur requests verwendet:

import time
import requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def create_task(prompt: str, image_urls: list[str]) -> str:
    payload = {
        "model": "grok-imagine-quality/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,   # 1-3 public URLs
            "aspect_ratio": "1:1",
            "resolution": "2k",         # lowercase: "1k" or "2k"
            "output_format": "png",
        },
    }
    r = requests.post(API_BASE, headers=HEADERS, json=payload, timeout=60)
    data = r.json()
    task_id = (data.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"create failed: {data}")
    return task_id

def wait_task(task_id: str, timeout_s: int = 600, poll_interval: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(poll_interval)
    raise TimeoutError(f"task {task_id} still running after {timeout_s}s")

if __name__ == "__main__":
    task_id = create_task(
        prompt="Turn this product photo into a clean studio shot on a light gray background",
        image_urls=["https://your-cdn.example.com/source.jpg"],
    )
    print("task:", task_id)

    task = wait_task(task_id)
    url = task["output"][0]["url"]

    # The output URL expires -- download immediately and persist yourself
    img = requests.get(url, timeout=120).content
    with open("result.png", "wb") as f:
        f.write(img)
    print(f"saved result.png ({len(img)} bytes)")

Hinweise für den Produktivbetrieb

Callbacks statt Polling verwenden

Für alles, was über ein Wegwerf-Skript hinausgeht, registriere einen Callback und überspringe die Polling-Schleife. Füge ein Objekt callback auf oberster Ebene hinzu (auf derselben Ebene wie model und input):

{
  "model": "grok-imagine-quality/image-to-image",
  "input": { "...": "..." },
  "callback": {
    "url": "https://your-app.example.com/hooks/hiapi",
    "when": "final"
  }
}

when unterstützt nur "final" — wenn die Aufgabe einen Endzustand erreicht (success oder fail), erhältst du genau einen POST. Faustregeln:

  • Polling eignet sich für CLIs, Notebooks und Batch-Jobs, bei denen der Prozess ohnehin am Leben bleibt. Frage alle 3–5 Sekunden ab; hämmere nicht mit Subsekunden-Intervallen.
  • Callbacks sind besser für Web-Backends geeignet: keine hängenden Verbindungen, keine Worker-Threads, die während der Generierung belegt sind. Hole GET /v1/tasks/<taskId> serverseitig erneut ab, um die Payload zu verifizieren, statt dem Webhook-Body blind zu vertrauen.

Idempotenz

Die Task-Erstellung selbst ist nicht idempotent — wenn dein Prozess nach POST /v1/tasks, aber vor dem Persistieren der taskId abstürzt, erstellt ein erneuter Versuch eine zweite Aufgabe (und berechnet sie). Persistiere die taskId in deinem eigenen Speicher, bevor du mit dem Warten beginst, und stelle sie beim Neustart wieder her, indem du die gespeicherte taskId abfragst, statt neu zu erstellen.

Fehlerbehandlung

Fehler, die dir tatsächlich begegnen werden:

  • 401 permission_denied — API-Schlüssel ungültig oder ohne Zugriff auf dieses Modell. Der Antwort-Body enthält eine request_id, die du dem Support-Team senden kannst:

    {
      "error": {
        "code": "permission_denied",
        "message": "This API key cannot use the selected model. ...",
        "request_id": "2026...",
        "type": "hiapi_error"
      }
    }
    
  • 400 INVALID_REQUEST — Schema-Verstoß mit präziser Meldung. Echte Beispiele für dieses Modell:

    • prompt: missing required field "prompt" — du hast ein erforderliches Feld vergessen.
    • image_urls: maxItems: got 12, want 3 — zu viele Referenzbilder (maximal 3).
    • resolution: value must be one of '1k', '2k' — du hast 1K/4K gesendet.
    • additional properties 'seed' not allowed — du hast ein Feld übergeben, das dieses Modell nicht akzeptiert.
  • Endzustand fail — die Aufgabe wurde angenommen, aber die Generierung ist fehlgeschlagen (z. B. Quell-URL nicht abrufbar). Prüfe data.error.message, korrigiere die Eingabe und erstelle eine neue Aufgabe.

Verwende Backoff-Wiederholungen für 5xx und Netzwerkfehler; wiederhole 400 nicht — sie schlagen auf dieselbe Weise fehl, bis du die Payload korrigierst.

Qualitätsstufe wählen (und was ist mit „Konsistenz“?)

Die Grok-Imagine-Reihe auf hiapi ist in separate Modell-IDs nach Stufe und Modalität unterteilt. Für Bild-zu-Bild kannst du wählen:

Die Stufe ist die Modell-ID — innerhalb von input gibt es keinen quality-Parameter (wird er gesendet, gibt er 400 additional properties 'quality' not allowed zurück). Die Preise pro Bild für beide Stufen findest du auf der Preisseite.

Weiterführende Lektüre

Häufige Fragen

Gibt es einen Konsistenz- oder Stärke-Parameter? Nein. Das Eingabeschema akzeptiert nur prompt, image_urls, aspect_ratio, resolution und output_format; alles andere wird mit 400 abgelehnt. Um zu steuern, wie stark die Ausgabe dem Quellbild folgt, gib im Prompt explizit an, was erhalten bleiben muss („Behalte das Produkt und das Etikett exakt bei, ändere nur den Hintergrund“) und übergib über image_urls bis zu 3 Referenzbilder.

Kann ich lokale Dateien hochladen oder Base64 senden? Nicht direkt — image_urls akzeptiert URLs, die die Plattform serverseitig abruft. Lade die Dateien in einen beliebigen öffentlich erreichbaren Speicher (S3, R2, CDN) hoch und übergib diese URL.

Wie viele Quellbilder kann ich übergeben? 1 bis 3. Ein leeres Array schlägt mit minItems: got 0, want 1 fehl; mehr als 3 schlagen mit maxItems fehl.

Welche Auflösungen und Seitenverhältnisse werden unterstützt? resolution ist 1k oder 2k (nur kleingeschrieben). aspect_ratio unterstützt 14 Werte von 2:1 bis 1:2, einschließlich auto, 16:9, 1:1, 9:16 sowie der mobilfreundlichen 9:19.5/9:20.

Wie lange sind Ausgabe-URLs gültig? Jede Ausgabe enthält einen expireAt-Zeitstempel. Betrachte Ergebnisse als kurzlebig: Lade die Bytes sofort nach erfolgreichem Abschluss der Aufgabe herunter und speichere sie selbst.

Wie erzeuge ich mehrere Varianten? Es gibt keinen n-Parameter — erstelle für jede Variante eine Aufgabe. Aufgaben laufen unabhängig, du kannst also mehrere parallel einreichen.

Was bedeutet 401 permission_denied, wenn mein Schlüssel korrekt ist? Der Schlüssel existiert, kann dieses Modell aber nicht verwenden (Tarif oder Berechtigungsumfang). Prüfe die Modellberechtigungen des Schlüssels im Dashboard oder wende dich mit der request_id aus dem Fehler-Antwort-Body an den Support.

Ä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