> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aihubmix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Asynchrone Aufgaben

> Asynchrone-Aufgaben-API von AIHubMix: Bilder mit `async`, Video, LLM-Wiederherstellung nach Abbruch, Status und Ergebnisse über /ai/v1/tasks, Webhook.

Anfragen wie Videogenerierung oder Bildgenerierung im Stapel dauern in der Regel länger, als eine einzelne HTTP-Verbindung sinnvoll warten kann. Trennt der Client während einer langen Textgenerierung die Verbindung, lässt sich die bereits erzeugte Antwort nicht mehr abrufen.

**Asynchrone Aufgaben** (Async Tasks) führen diese drei Szenarien in einem gemeinsamen Aufgabenobjekt zusammen: Bild- und Videoanfragen erstellen über die Generierungsendpunkte eine Aufgabe und geben sofort eine `task_id` zurück; abgebrochene LLM-Anfragen führt die Plattform weiter aus und speichert die finale Antwort. Alle drei nutzen dieselben Aufgabenstatus, denselben Abfrageendpunkt und denselben Ablauf zum Herunterladen der Ergebnisse.

<Note>
  Bitte verwenden Sie zum Abfragen der Aufgabe und zum Herunterladen der Ergebnisse denselben API Key, mit dem die Aufgabe erstellt wurde. Aufgaben sind nach API Key isoliert. Auch zwei Keys desselben Kontos können die Aufgaben des jeweils anderen nicht lesen.
</Note>

<Card title="Asynchrone Aufgaben in der Konsole aktivieren" icon="list-check" href="https://console.aihubmix.com/support" horizontal>
  Aktivieren Sie die Funktion für asynchrone Aufgaben für Ihr Konto, bevor Sie asynchrone Bild- oder Videoaufgaben erstellen. Zeigt die Konsole diesen Eintrag noch nicht an, wenden Sie sich an den technischen Support von AIHubMix.
</Card>

<Warning>
  Ist die Funktion für asynchrone Aufgaben nicht aktiviert, geben Anfragen zum Erstellen von Medienaufgaben `403 async_not_enabled` zurück. LLM-Anfragen schlagen deshalb nicht fehl, jedoch lässt sich die finale Antwort nach einem Abbruch des Clients nicht abrufen.
</Warning>

***

<h2 id="quickstart">
  Schnellstart
</h2>

Der vollständige Ablauf asynchroner Bild- und Videoaufgaben besteht aus drei Schritten:

```text theme={null}
1. Aufgabe übermitteln -> task_id erhalten
2. Status abfragen -> auf den Abschluss der Aufgabe warten
3. Ergebnis abrufen -> Datei herunterladen oder Antwortinhalt lesen
```

<CodeGroup>
  ```shell curl theme={null}
  # Schritt 1: Asynchrone Videoaufgabe übermitteln
  curl -X POST https://aihubmix.com/ai/v1/videos \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "wan2.6-t2v",
      "prompt": "A cat playing jazz on a piano, warm lighting, cinematic shot",
      "seconds": "5",
      "size": "1280x720"
    }'

  # Schritt 2: Alle 15 Sekunden abfragen, bis die Aufgabe abgeschlossen, fehlgeschlagen oder abgebrochen ist
  curl https://aihubmix.com/ai/v1/tasks/{task_id} \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY"

  # Schritt 3: Einzelnes Ergebnis herunterladen
  curl https://aihubmix.com/ai/v1/tasks/{task_id}/content \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    --output result.mp4
  ```

  ```json Antwort bei der Erstellung theme={null}
  {
    "id": "task_01K0...",
    "object": "video",
    "model": "wan2.6-t2v",
    "status": "in_progress",
    "output": [],
    "error": null,
    "created_at": 1784707200,
    "completed_at": null,
    "expires_at": null
  }
  ```
</CodeGroup>

***

<h2 id="sync-vs-async">
  Synchroner Aufruf und asynchrone Aufgabe im Vergleich
</h2>

| Anfragetyp          | Standardmäßige Rückgabe              | Asynchroner Weg                                                                                              |
| ------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| Bildgenerierung     | Ergebnis wird synchron zurückgegeben | Nach Übergabe von `async: true` im Request-Body wird sofort eine `task_id` zurückgegeben                     |
| Videogenerierung    | Immer asynchron                      | Nach dem Erstellen wird eine `task_id` zurückgegeben, das Ergebnis wird über den Aufgabenendpunkt abgerufen  |
| LLM-Textgenerierung | Synchrone oder Streaming-Rückgabe    | Bricht der Client ab und sind die Bedingungen erfüllt, wird die finale Antwort als `llm`-Aufgabe gespeichert |

Ein synchroner Aufruf liefert das Ergebnis innerhalb einer HTTP-Antwort; nach einem Verbindungsabbruch ist das Ergebnis nicht mehr abrufbar. Asynchrone Aufgaben speichern das Ergebnis auf der Plattform. Die `task_id` lässt sich vor Ablauf des Ergebnisses mit demselben API Key erneut abfragen und herunterladen. Das eignet sich für länger laufende Generierungsanfragen sowie für lange Textausgaben, deren finale Antwort nach einem Abbruch abgerufen werden soll.

***

<h2 id="api-overview">
  Überblick über die Endpunkte
</h2>

| Aktion                      | Methode | Pfad                                         | Beschreibung                                                   |
| --------------------------- | ------- | -------------------------------------------- | -------------------------------------------------------------- |
| Asynchrones Bild erstellen  | POST    | `/ai/v1/images/generations`                  | Im Request-Body `async: true` ergänzen                         |
| Asynchrones Video erstellen | POST    | `/ai/v1/videos`                              | Videoaufgaben sind standardmäßig asynchron                     |
| Aufgabenliste abfragen      | GET     | `/ai/v1/tasks`                               | Aufgaben suchen, die mit dem aktuellen API Key erstellt wurden |
| Aufgabendetails abfragen    | GET     | `/ai/v1/tasks/{task_id}`                     | Einheitlichen Aufgabenstatus und Ausgabe abfragen              |
| Einzelnes Ergebnis abrufen  | GET     | `/ai/v1/tasks/{task_id}/content`             | Für Aufgaben mit einem Ergebnis oder für LLM-Aufgaben          |
| Bestimmtes Ergebnis abrufen | GET     | `/ai/v1/tasks/{task_id}/content/{result_id}` | Für Aufgaben mit mehreren Ergebnissen                          |

Base URL: `https://aihubmix.com`, die Authentifizierung erfolgt per Bearer Token:

```bash theme={null}
Authorization: Bearer $AIHUBMIX_API_KEY
```

<Note>
  `/ai/v1/tasks` ist ein rein lesender, einheitlicher Abfrageendpunkt; `POST /ai/v1/tasks` wird nicht angeboten. Bilder und Videos werden jeweils über den zugehörigen Generierungsendpunkt erstellt. Anfragen, die die Bedingungen der [LLM-Wiederherstellung nach Abbruch](#llm-interruption-recovery) erfüllen, werden nach einem Abbruch des Clients automatisch als `llm`-Aufgabe erfasst.
</Note>

***

<h2 id="supported-models">
  Unterstützte Modelle
</h2>

Der unterstützte Umfang asynchroner Aufgaben richtet sich nach dem Aufgabentyp, beim Aufruf sind keine zusätzlichen Parameter nötig.

<h3 id="supported-models-image">
  Asynchrone Bilder
</h3>

| Modell           |
| ---------------- |
| `qwen-image-2.0` |

<h3 id="supported-models-video">
  Asynchrone Videos
</h3>

| Modell       |
| ------------ |
| `wan2.6-t2v` |

<h3 id="supported-models-llm">
  LLM-Wiederherstellung nach Abbruch
</h3>

| Modell           |
| ---------------- |
| `gpt-5.5-pro`    |
| `claude-fable-5` |

Der unterstützte Umfang wird laufend erweitert, diese Tabelle wird entsprechend aktualisiert.

***

<h2 id="create-async-task">
  Wie erstellt man asynchrone Aufgaben?
</h2>

<h3 id="create-async-image">
  Asynchrone Bilder
</h3>

Der Bildendpunkt gibt standardmäßig synchron zurück. Wird `async` auf `true` gesetzt, gibt der Endpunkt sofort das Aufgabenobjekt zurück und die Generierung läuft im Hintergrund weiter.

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/images/generations \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-image-2.0",
    "prompt": "A flower shop with delicate windows, warm sunlight streaming in",
    "n": 2,
    "size": "1024x1024",
    "async": true
  }'
```

`async` muss ein boolescher Wert sein. Wird das Feld nicht übergeben oder auf `false` gesetzt, behält der Bildendpunkt sein synchrones Verhalten.

<h3 id="create-async-video">
  Asynchrone Videos
</h3>

Der Videoendpunkt arbeitet immer asynchron. Nach erfolgreicher Erstellung wird der Status `pending` oder `in_progress` zurückgegeben. Ein Umschalten auf synchrones Warten über `Prefer: wait` wird nicht unterstützt.

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/videos \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.6-t2v",
    "prompt": "Ocean waves crashing on rocky cliffs at sunset",
    "seconds": "5",
    "size": "1280x720"
  }'
```

<h3 id="common-parameters">
  Gemeinsame Parameter
</h3>

`model`, `prompt`, `n`, `seconds` und `size` in den Beispielen sind gängige Modellparameter. Welche Felder und Werte ein Modell unterstützt, richtet sich nach der API-Dokumentation des jeweiligen Modells; für Videomodelle siehe die [Dokumentation zur Videogenerierung](/de/api/Video-Gen). Die folgende Tabelle beschreibt nur die Parameter, die alle asynchronen Aufgaben gemeinsam nutzen.

| Parameter               | Typ       | Erforderlich                        | Beschreibung                                                                          |
| ----------------------- | --------- | ----------------------------------- | ------------------------------------------------------------------------------------- |
| `async`                 | boolean   | Bild: ja; Video: nicht erforderlich | Der Bildendpunkt arbeitet asynchron, sobald der Wert auf `true` gesetzt ist           |
| `webhook_url`           | string    | Nein                                | HTTPS-Callback-Adresse für die aktuelle Aufgabe, maximal 512 Zeichen                  |
| `webhook_events_filter` | string\[] | Nein                                | Endstatus, die gepusht werden sollen, möglich sind `completed`, `failed`, `cancelled` |

<Note>
  Bildaufgaben können Webhooks nur bei `async: true` verwenden. Wird `webhook_events_filter` weggelassen, pusht die Plattform die drei Endstatus `completed`, `failed` und `cancelled`. Bei Angabe muss das Feld zusammen mit `webhook_url` verwendet werden und darf weder leer sein noch Duplikate enthalten.
</Note>

***

<h2 id="llm-interruption-recovery">
  Wie funktioniert die LLM-Wiederherstellung nach Abbruch?
</h2>

Die LLM-Wiederherstellung nach Abbruch dient dazu, die finale Antwort nach einem Verbindungsabbruch des Clients abzurufen. Diese Funktion nutzt die bestehende Art der LLM-Anfrage, Streaming-Verhalten und Antwortformat bleiben unverändert. Ein zusätzlicher Endpunkt zum Erstellen ist nicht erforderlich, und es wird vorab keine `task_id` zurückgegeben.

<h3 id="recovery-conditions">
  Bedingungen für die Wirksamkeit
</h3>

Die folgenden Bedingungen müssen gleichzeitig erfüllt sein:

| Bedingung                                                            | Beschreibung                                                                                                           |
| -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Asynchrone Aufgaben sind für das Konto aktiviert                     | In der AIHubMix-Konsole für das aktuelle Konto aktivieren                                                              |
| Das verwendete Modell unterstützt die Wiederherstellung nach Abbruch | Siehe [LLM-Wiederherstellung nach Abbruch](#supported-models-llm), beim Aufruf sind keine zusätzlichen Parameter nötig |
| Aufruf eines unterstützten LLM-Endpunkts                             | Die Anfrage trifft einen der unten aufgeführten Endpunkte zur Textgenerierung                                          |
| Beim Client tritt ein Abbruch auf                                    | Der Client bricht aktiv ab, die Netzwerkverbindung wird getrennt oder die aufrufende Seite storniert die Anfrage       |

Unterstützte Endpunkte:

| Endpunkt                                           | Beschreibung                                    |
| -------------------------------------------------- | ----------------------------------------------- |
| `POST /v1/chat/completions`                        | OpenAI Chat Completions, mit und ohne Streaming |
| `POST /v1/messages`                                | Anthropic Messages, mit und ohne Streaming      |
| `POST /v1/responses`                               | OpenAI Responses API                            |
| Gemini `generateContent` / `streamGenerateContent` | Native Gemini-Endpunkte zur Textgenerierung     |

<Note>
  Beim Aufruf sind keine zusätzlichen Felder zu übergeben. Den unterstützten Umfang finden Sie unter [LLM-Wiederherstellung nach Abbruch](#supported-models-llm). Für Modelle, die dort nicht aufgeführt sind, lässt sich die Wiederherstellung nach Abbruch vor der produktiven Anbindung mit einer kostengünstigen Anfrage prüfen; solche Prüfanfragen werden regulär abgerechnet. Ist eine der Bedingungen nicht erfüllt, wird die Anfrage weiterhin normal ausgeführt, nach einem Abbruch des Clients entsteht jedoch keine `llm`-Aufgabe.
</Note>

<h3 id="recovery-flow">
  Ablauf nach einem Abbruch
</h3>

```text theme={null}
1. Der Client stellt eine normale LLM-Anfrage
2. Der Client trennt die Verbindung oder bricht ab, bevor die Antwort abgeschlossen ist
3. AIHubMix verarbeitet die Anfrage weiter, die Anfrage wird regulär abgerechnet
4. Die finale JSON- oder SSE-Antwort wird als Aufgabe vom Typ llm gespeichert
5. Mit dem ursprünglichen API Key die Aufgabenliste abfragen und die gespeicherte Antwort lesen
```

Für LLM-Anfragen, die normal abgeschlossen und erfolgreich an den Client zurückgegeben werden, wird keine Aufgabe erstellt; sie erscheinen auch nicht in der Aufgabenliste. Abgebrochene Anfragen erscheinen in der Liste, sobald die finale Antwort gespeichert ist, während der Verarbeitung sind sie daher zeitweise nicht auffindbar.

<h3 id="locate-interrupted-request">
  Die zugehörige abgebrochene Anfrage finden
</h3>

Die LLM-Antwortheader enthalten `X-Aihubmix-Request-Id`. Der Client sollte diesen Wert unmittelbar nach Erhalt der Antwortheader speichern. Nach einem Abbruch lässt sich damit in der Liste der asynchronen Aufgaben in der AIHubMix-Konsole die zugehörige Aufgabe finden.

Die öffentliche Aufgaben-API unterstützt derzeit kein Filtern nach Request-ID. Ohne gespeicherte Request-ID bleibt nur die Suche nach Modell und Erstellungszeit, und zwar mit demselben API Key, mit dem die Anfrage erstellt wurde:

```bash theme={null}
# Die letzten abgebrochenen LLM-Aufgaben abfragen
curl "https://aihubmix.com/ai/v1/tasks?object=llm&model={model}&order=desc&limit=20" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"

# Nach dem Finden der task_id die Details abfragen und die Originalantwort abrufen
curl https://aihubmix.com/ai/v1/tasks/{task_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"

curl https://aihubmix.com/ai/v1/tasks/{task_id}/content \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

<Warning>
  Werden mit demselben API Key mehrere Anfragen an dasselbe Modell parallel gestellt, lässt sich allein über Modell und Erstellungszeit keine eindeutige Zuordnung sicherstellen. Wenn Sie eine zuverlässige Wiederherstellung benötigen, speichern Sie `X-Aihubmix-Request-Id` und suchen Sie über die Konsole. Liegen die Antwortheader nicht vor, sollten Sie die neueste Aufgabe in der Liste nicht ohne Weiteres als die eigene Anfrage einstufen.
</Warning>

<Warning>
  Aufgaben der LLM-Wiederherstellung nach Abbruch senden derzeit keine Webhooks, rufen Sie das Ergebnis bitte über die Aufgabenliste ab. Ein Abbruch des Clients stoppt die weitere Verarbeitung auf der Plattform nicht, der Aufruf wird weiterhin nach den Regeln des jeweiligen LLM-Endpunkts abgerechnet.
</Warning>

***

<h2 id="task-object">
  Aufgabenobjekt und Status
</h2>

Alle Aufgaben verwenden dieselbe Antwortstruktur:

```json theme={null}
{
  "id": "task_01K0ABCDEF",
  "object": "video",
  "model": "wan2.6-t2v",
  "status": "completed",
  "output": [
    {
      "index": 0,
      "result_id": "result_01K0XYZ",
      "type": "file",
      "content_type": "video/mp4",
      "content_url": "https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content"
    }
  ],
  "error": null,
  "created_at": 1784707200,
  "completed_at": 1784707320,
  "expires_at": 1784709120
}
```

| Feld           | Typ          | Beschreibung                                                                                      |
| -------------- | ------------ | ------------------------------------------------------------------------------------------------- |
| `id`           | string       | Aufgaben-ID der Plattform, also die `task_id` für nachfolgende Anfragen                           |
| `object`       | string       | Aufgabentyp: `llm`, `image` oder `video`                                                          |
| `model`        | string       | Modell, das beim Erstellen der Aufgabe verwendet wurde                                            |
| `status`       | string       | Einheitlicher Aufgabenstatus                                                                      |
| `output`       | array        | Abrufbare Ergebnisse, leeres Array, wenn die Aufgabe kein Ergebnis erzeugt hat                    |
| `error`        | object/null  | Fehlerinformationen, in der Regel mit `code` und `message`                                        |
| `created_at`   | integer      | Erstellungszeit, Unix-Sekunden                                                                    |
| `completed_at` | integer/null | Zeitpunkt, zu dem die Aufgabe abgeschlossen, fehlgeschlagen oder abgebrochen wurde, Unix-Sekunden |
| `expires_at`   | integer/null | Ablaufzeit des frühesten Ergebnisses, Unix-Sekunden                                               |

Ergebnisfelder in `output`:

| Feld           | Beschreibung                                                                                                      |
| -------------- | ----------------------------------------------------------------------------------------------------------------- |
| `index`        | Reihenfolge des Ergebnisses in der aktuellen Aufgabe, beginnend bei 0                                             |
| `result_id`    | Ergebnis-ID, wird beim Herunterladen eines bestimmten Ergebnisses aus Aufgaben mit mehreren Ergebnissen verwendet |
| `type`         | Ergebnistyp, `file` für Dateien, `response` für LLM-Antworten                                                     |
| `content_type` | Dateityp (MIME) des Ergebnisses, zum Beispiel `video/mp4` oder `application/json`                                 |
| `content_url`  | Download-Adresse des Ergebnisses, der Zugriff erfordert den API Key, mit dem die Aufgabe erstellt wurde           |
| `b64_json`     | Base64-codiertes Ergebnis, das einige Bildmodelle direkt zurückgeben können                                       |
| `truncated`    | Ob die LLM-Antwort wegen einer Größenbeschränkung abgeschnitten wurde                                             |

<h3 id="task-status">
  Statusbeschreibung
</h3>

| Status        | Bereits beendet | Beschreibung                                                            |
| ------------- | --------------- | ----------------------------------------------------------------------- |
| `pending`     | Nein            | Die Plattform hat die Aufgabe entgegengenommen und wartet auf den Start |
| `in_progress` | Nein            | Die Aufgabe wird ausgeführt                                             |
| `completed`   | Ja              | Die Aufgabe ist abgeschlossen, das Ergebnis steht in `output` bereit    |
| `failed`      | Ja              | Die Aufgabe ist fehlgeschlagen, die Ursache steht in `error`            |
| `cancelled`   | Ja              | Die Aufgabe wurde abgebrochen                                           |

Empfohlen wird eine Abfrage alle **15 Sekunden**, bis der Status auf `completed`, `failed` oder `cancelled` wechselt.

<Note>
  Auch Aufgaben mit `failed` oder `cancelled` können bereits erzeugte Teilergebnisse enthalten. Prüfen Sie neben dem Status auch, ob `output` leer ist.
</Note>

***

<h2 id="query-tasks">
  Wie fragt man Aufgaben ab?
</h2>

<h3 id="query-task-detail">
  Aufgabendetails abfragen
</h3>

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

Dieser Endpunkt gibt den zum Abfragezeitpunkt aktuellen Stand der Aufgabe zurück. Die Abfrage verändert die Aufgabe nicht, der Aufgabenstatus wird von der Plattform automatisch aktualisiert.

<h3 id="query-task-list">
  Aufgabenliste abfragen
</h3>

Ist die Antwort bei der Erstellung verloren gegangen oder möchten Sie mehrere zurückliegende Aufgaben einsehen, lässt sich die `task_id` über den Listenendpunkt wiederfinden:

```bash theme={null}
curl "https://aihubmix.com/ai/v1/tasks?object=video&status=in_progress&limit=20&order=desc" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

| Parameter | Typ     | Standardwert | Beschreibung                                                        |
| --------- | ------- | ------------ | ------------------------------------------------------------------- |
| `object`  | string  | -            | Nach Typ filtern: `llm`, `image`, `video`                           |
| `status`  | string  | -            | Nach einheitlichem Aufgabenstatus filtern                           |
| `model`   | string  | -            | Exakt nach Modellnamen filtern                                      |
| `after`   | string  | -            | Paginierungscursor, verwenden Sie `next_after` der vorherigen Seite |
| `limit`   | integer | `20`         | Anzahl pro Seite, Bereich 1 bis 100                                 |
| `order`   | string  | `desc`       | `asc` oder `desc`                                                   |

Beispielantwort:

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "task_01K0ABCDEF",
      "object": "video",
      "model": "wan2.6-t2v",
      "status": "in_progress",
      "output": [],
      "error": null,
      "created_at": 1784707200,
      "completed_at": null,
      "expires_at": null
    }
  ],
  "has_more": true,
  "next_after": "task_01K0ABCDEF"
}
```

| Feld         | Beschreibung                                                                          |
| ------------ | ------------------------------------------------------------------------------------- |
| `object`     | Fest auf `list`, kennzeichnet eine Listenantwort                                      |
| `data`       | Array der Aufgaben auf der aktuellen Seite                                            |
| `has_more`   | Ob es eine weitere Seite gibt                                                         |
| `next_after` | Cursor für die nächste Seite, wird nur zurückgegeben, wenn es eine weitere Seite gibt |

Die nächste Seite anfordern:

```bash theme={null}
curl "https://aihubmix.com/ai/v1/tasks?limit=20&order=desc&after=task_01K0ABCDEF" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

***

<h2 id="get-task-results">
  Wie ruft man Aufgabenergebnisse ab?
</h2>

<h3 id="single-artifact">
  Aufgaben mit einem Ergebnis
</h3>

Enthält `output` nur eine Datei, ist der direkte Zugriff möglich:

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id}/content \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  --output result.bin
```

Ebenso lässt sich `output[0].content_url` direkt verwenden. Der `Content-Type` der Download-Antwort entspricht `output[0].content_type`.

<h3 id="multiple-artifacts">
  Aufgaben mit mehreren Ergebnissen
</h3>

Enthält `output` mehrere Dateien, muss die zugehörige `result_id` angegeben werden:

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id}/content/{result_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  --output result.png
```

Wird bei Aufgaben mit mehreren Ergebnissen keine `result_id` angegeben, gibt der Endpunkt `400 result_id_required` zurück.

<h3 id="llm-response-task">
  LLM-Antwortaufgaben
</h3>

Sind die Bedingungen der [LLM-Wiederherstellung nach Abbruch](#llm-interruption-recovery) erfüllt und ist die Antwort gespeichert, hat die Aufgabe im Feld `object` den Wert `llm` und der Eintrag in `output` im Feld `type` den Wert `response`. Mögliche Inhaltstypen:

* `application/json`: normale JSON-Antwort
* `text/event-stream`: gespeicherte SSE-Streaming-Antwort

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id}/content \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

Die Markierung für das Abschneiden steht in den Aufgabendetails unter `output[0].truncated`. Der Wert `true` bedeutet, dass die gespeicherte Antwort wegen einer Größenbeschränkung abgeschnitten wurde. `GET /ai/v1/tasks/{task_id}/content` gibt den Original-JSON- oder SSE-Inhalt zurück und umschließt ihn nicht zusätzlich mit einem `truncated`-Feld. Fragen Sie deshalb zuerst die Aufgabendetails ab und lesen Sie danach den Inhalt.

<Warning>
  Ergebnisse können ablaufen, und es kann eine Begrenzung der Download-Anzahl geben. Bitte speichern Sie sie rechtzeitig vor `expires_at`. Nach Ablauf wird `410 artifact_expired` zurückgegeben, bei Überschreiten der Download-Grenze `429 too_many_downloads`.
</Warning>

***

<h2 id="webhooks">
  Wie verwendet man Webhooks?
</h2>

Derzeit wird ein Webhook auf Aufgabenebene beim Erstellen einer asynchronen Aufgabe unterstützt. Soll AIHubMix Sie nach Abschluss der Aufgabe aktiv benachrichtigen, übergeben Sie `webhook_url` und optional `webhook_events_filter` im Request-Body der asynchronen Bild- oder Videoanfrage:

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/videos \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.6-t2v",
    "prompt": "A tranquil Japanese garden at sunrise",
    "seconds": "5",
    "webhook_url": "https://example.com/webhooks/aihubmix",
    "webhook_events_filter": ["completed", "failed"]
  }'
```

Die Callback-Adresse muss HTTPS verwenden und darf nicht auf den lokalen Rechner, private Netze oder andere eingeschränkte Adressen zeigen.

<h3 id="webhook-payload">
  Callback-Anfrage
</h3>

AIHubMix sendet eine `POST`-Anfrage an die Callback-Adresse:

```json theme={null}
{
  "event_id": "evt_01K0ABCDEF",
  "event_type": "completed",
  "created_at": "2026-07-22T12:00:00Z",
  "data": {
    "task_id": "task_01K0ABCDEF",
    "status": "completed",
    "model": "wan2.6-t2v",
    "results": [
      {
        "url": "https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content"
      }
    ]
  }
}
```

| Feld                 | Beschreibung                                                                               |
| -------------------- | ------------------------------------------------------------------------------------------ |
| `event_id`           | Eindeutige ID dieses Callback-Ereignisses, dient zum Erkennen doppelter Benachrichtigungen |
| `event_type`         | Endstatus der Aufgabe: `completed`, `failed` oder `cancelled`                              |
| `created_at`         | Erstellungszeit des Callback-Ereignisses                                                   |
| `data.task_id`       | Aufgaben-ID, nutzbar zum Abfragen der Aufgabendetails                                      |
| `data.status`        | Aktueller Aufgabenstatus                                                                   |
| `data.model`         | Modell, das beim Erstellen der Aufgabe verwendet wurde                                     |
| `data.results[].url` | Download-Adresse des bereits erzeugten Ergebnisses                                         |
| `data.error.code`    | Fehlercode, nur bei Fehlerereignissen möglich                                              |
| `data.error.message` | Fehlerursache, nur bei Fehlerereignissen möglich                                           |

Für die URLs in `results` ist weiterhin der API Key erforderlich, mit dem die Aufgabe erstellt wurde.

<h3 id="webhook-retry">
  Wiederholung und Deduplizierung
</h3>

Die Plattform versucht die Zustellung mindestens einmal, dasselbe Ereignis kann daher mehrfach gesendet werden:

* HTTP `2xx` bedeutet erfolgreicher Empfang.
* HTTP `5xx`, Netzwerkfehler oder Timeouts lösen eine Wiederholung aus.
* HTTP `3xx` und `4xx` werden nicht wiederholt.
* Maximal 6 Zustellversuche, die Wiederholungsabstände betragen der Reihe nach 1, 4, 16, 64 und 256 Sekunden.

Die empfangende Seite sollte `event_id` speichern. Trifft dieselbe `event_id` erneut ein, überspringen Sie die Geschäftslogik und geben Sie direkt `2xx` zurück.

<Warning>
  Der aktuelle Webhook auf Aufgabenebene bietet keine konfigurierbaren eigenen Signaturzugangsdaten. Rufen Sie nach Erhalt der Benachrichtigung `GET /ai/v1/tasks/{task_id}` mit dem API Key auf, mit dem die Aufgabe erstellt wurde; maßgeblich ist das Abfrageergebnis.
</Warning>

***

<h2 id="error-codes">
  Fehlerantworten und Fehlercodes
</h2>

Fehlerantworten verwenden eine einheitliche Struktur:

```json theme={null}
{
  "error": {
    "message": "Task not found.",
    "type": "invalid_request_error",
    "code": "task_not_found",
    "tid": "req_01K0..."
  }
}
```

| Feld            | Beschreibung                                                                 |
| --------------- | ---------------------------------------------------------------------------- |
| `error.message` | Fehlerursache                                                                |
| `error.type`    | Fehlertyp                                                                    |
| `error.code`    | Maschinenlesbarer Fehlercode                                                 |
| `error.tid`     | Trace-ID der Anfrage, bitte beim Kontakt mit dem technischen Support angeben |

| HTTP-Statuscode | Fehlercode                      | Beschreibung                                                                               |
| --------------- | ------------------------------- | ------------------------------------------------------------------------------------------ |
| 400             | `invalid_request`               | Parametertyp oder Parameterwert ist ungültig                                               |
| 400             | `result_id_required`            | Bei einer Aufgabe mit mehreren Ergebnissen wurde keine `result_id` angegeben               |
| 400             | `webhook_invalid`               | Webhook-URL ist ungültig                                                                   |
| 400             | `webhook_events_filter_invalid` | Webhook-Ereignisliste ist ungültig                                                         |
| 401             | `authentication_failed`         | API Key fehlt oder ist ungültig                                                            |
| 403             | `async_not_enabled`             | Asynchrone Aufgaben sind für das Konto nicht aktiviert                                     |
| 404             | `task_not_found`                | Aufgabe existiert nicht oder gehört nicht zum aktuellen API Key                            |
| 404             | `result_not_found`              | Ergebnis existiert nicht oder ist derzeit nicht abrufbar                                   |
| 410             | `artifact_expired`              | Ergebnis ist abgelaufen                                                                    |
| 429             | `too_many_downloads`            | Die Grenze für Ergebnis-Downloads wurde überschritten                                      |
| 503             | `async_unavailable`             | Der asynchrone Bilddienst ist vorübergehend nicht verfügbar, bitte später erneut versuchen |

***

<h2 id="full-example">
  Vollständiges Beispiel
</h2>

Vollständiger Ablauf zum Erstellen einer Videoaufgabe, Abfragen des Status und Herunterladen aller Ergebnisse:

<CodeGroup>
  ```python Python theme={null}
  import base64
  import os
  import time

  import requests

  BASE_URL = "https://aihubmix.com"
  API_KEY = os.environ["AIHUBMIX_API_KEY"]
  HEADERS = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json",
  }

  # 1. Aufgabe erstellen
  response = requests.post(
      f"{BASE_URL}/ai/v1/videos",
      headers=HEADERS,
      json={
          "model": "wan2.6-t2v",
          "prompt": "A cat playing jazz on a piano",
          "seconds": "5",
          "size": "1280x720",
      },
      timeout=60,
  )
  response.raise_for_status()
  task = response.json()
  task_id = task["id"]

  # 2. Abfragen, bis die Aufgabe abgeschlossen, fehlgeschlagen oder abgebrochen ist
  while task["status"] not in {"completed", "failed", "cancelled"}:
      time.sleep(15)
      response = requests.get(
          f"{BASE_URL}/ai/v1/tasks/{task_id}",
          headers=HEADERS,
          timeout=30,
      )
      response.raise_for_status()
      task = response.json()
      print("status:", task["status"])

  # 3. Ergebnisse abrufen
  if task["output"]:
      for index, item in enumerate(task["output"]):
          if encoded := item.get("b64_json"):
              with open(f"result-{index}.bin", "wb") as file:
                  file.write(base64.b64decode(encoded))
              continue
          result = requests.get(
              item["content_url"],
              headers=HEADERS,
              timeout=120,
          )
          result.raise_for_status()
          with open(f"result-{index}.bin", "wb") as file:
              file.write(result.content)
  elif task["status"] == "failed":
      raise RuntimeError(task.get("error"))
  ```

  ```typescript TypeScript theme={null}
  import { writeFile } from "node:fs/promises";

  const BASE_URL = "https://aihubmix.com";
  const HEADERS = {
    Authorization: `Bearer ${process.env.AIHUBMIX_API_KEY}`,
    "Content-Type": "application/json",
  };

  // 1. Aufgabe erstellen
  const created = await fetch(`${BASE_URL}/ai/v1/videos`, {
    method: "POST",
    headers: HEADERS,
    body: JSON.stringify({
      model: "wan2.6-t2v",
      prompt: "A cat playing jazz on a piano",
      seconds: "5",
      size: "1280x720",
    }),
  });
  let task = await created.json();

  // 2. Abfragen, bis die Aufgabe abgeschlossen, fehlgeschlagen oder abgebrochen ist
  const finished = new Set(["completed", "failed", "cancelled"]);
  while (!finished.has(task.status)) {
    await new Promise((resolve) => setTimeout(resolve, 15_000));
    const polled = await fetch(`${BASE_URL}/ai/v1/tasks/${task.id}`, {
      headers: HEADERS,
    });
    task = await polled.json();
    console.log("status:", task.status);
  }

  // 3. Ergebnisse abrufen
  if (task.output?.length) {
    for (const [index, item] of task.output.entries()) {
      if (item.b64_json) {
        await writeFile(`result-${index}.bin`, Buffer.from(item.b64_json, "base64"));
        continue;
      }
      const result = await fetch(item.content_url, { headers: HEADERS });
      await writeFile(`result-${index}.bin`, Buffer.from(await result.arrayBuffer()));
    }
  } else if (task.status === "failed") {
    throw new Error(JSON.stringify(task.error));
  }
  ```

  ```shell curl theme={null}
  # 1. Aufgabe erstellen und die zurückgegebene id notieren
  curl -X POST https://aihubmix.com/ai/v1/videos \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "wan2.6-t2v",
      "prompt": "A cat playing jazz on a piano",
      "seconds": "5",
      "size": "1280x720"
    }'

  # 2. Alle 15 Sekunden den Status abfragen
  curl https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY"

  # 3. Ergebnis herunterladen, sobald der Status auf completed wechselt
  curl https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    --output result.mp4
  ```
</CodeGroup>

***

<h2 id="faq">
  Häufige Fragen
</h2>

**Wie oft sollte der Aufgabenstatus abgefragt werden?**

Empfohlen wird eine Abfrage alle 15 Sekunden, um häufiges Polling zu vermeiden. Auch bei Verwendung von Webhooks sollte eine Abfrage mit niedriger Frequenz als Absicherung bestehen bleiben.

**Wie findet man eine Aufgabe wieder, wenn die Antwort bei der Erstellung verloren gegangen ist?**

Rufen Sie `GET /ai/v1/tasks` mit demselben API Key auf, mit dem die Aufgabe erstellt wurde. Über `object`, `model` und `status` lässt sich die Treffermenge eingrenzen.

**Warum findet ein anderer API Key desselben Kontos die Aufgabe nicht?**

Aufgaben sind nach API Key isoliert. Abfrage-, Download- und Listenanfragen müssen denselben Key verwenden, mit dem die Aufgabe erstellt wurde.

**Warum ist `output` kein leeres Array, obwohl die Aufgabe fehlgeschlagen ist?**

Einige Modelle können vor dem endgültigen Fehlschlag oder Abbruch bereits verwertbare Ergebnisse erzeugt haben. Sobald in `output` ein `content_url` oder ein `b64_json` vorhanden ist, lässt sich das Ergebnis auf dem jeweiligen Weg abrufen.

**Was tun, wenn kein Webhook eintrifft?**

Prüfen Sie, ob die Callback-Adresse öffentlich erreichbar ist, HTTPS verwendet und innerhalb von 10 Sekunden `2xx` zurückgibt. Unabhängig von der Webhook-Nutzung lässt sich der Endstatus über `GET /ai/v1/tasks/{task_id}` abfragen.

**Muss bestehender Code für die LLM-Wiederherstellung nach Abbruch geändert werden?**

Nein. Die Art der Anfrage, das Streaming-Verhalten und das Antwortformat bleiben unverändert. Es wird empfohlen, den Antwortheader `X-Aihubmix-Request-Id` zu speichern, um die zugehörige Aufgabe nach einem Abbruch in der Konsole genau zu finden.

***

Aktualisiert am: 2026-07-28
