Eine angenommene Anfrage zur Bildgenerierung ist noch kein fertiges Bild. Deine Anwendung muss die Task-ID speichern, den Status desselben Tasks abfragen und mit fehlgeschlagenen oder unterbrochenen Anfragen umgehen, ohne versehentlich einen weiteren Auftrag zu starten.
In diesem Tutorial entwickelst du einen kleinen serverseitigen Node.js-Client für diesen Ablauf. Er bietet getrennte Befehle für submit und resume: Der eine erstellt einen Task, der andere fragt ausschließlich einen bestehenden Task ab. Beginne mit den von der API unterstützten Modell-IDs, nicht mit einem Modellnamen, den du aus einem Banner auf der Startseite kopiert hast.
Das Tutorial behandelt die Text-zu-Bild-Generierung. Es lädt keine Referenzdateien hoch, implementiert keine Browseroberfläche und bewertet keine Modellqualität. Die Validierung umfasst 29 lokale Mock-Tests und einen kontrollierten Bildgenerierungs-Task im Produktivsystem vom 04.09.2026. Dieser Task lieferte ein Bild; für ihn wurde eine API-Abbuchung von 120 Punkten erfasst. Das ist eine einzelne, datierte Integrationsprüfung, kein Geschwindigkeitsbenchmark, kein allgemeingültiger Preis und keine Verfügbarkeitsgarantie für ein anderes Konto.
Das Titelbild ist ein Screenshot des Modellkatalogs vom 04.09.2026. Betrachte es als datierte Illustration, nicht als aktuelle Preisangabe oder Verfügbarkeitsgarantie.
Das Wichtigste auf einen Blick
- Bewahre den API-Schlüssel auf deinem Server auf, außerhalb von Browser-Bundles und öffentlichen Repositorys.
- Lies bei einem Bild-Task den numerischen Wert
data.taskIdaus der Annahmeantwort aus und speichere ihn für spätere Abfragen.- Frage den gespeicherten Task ab, bis er
readyoderfailederreicht. Lies Bild-URLs erst nach erfolgreichem Abschluss ausdata.imagesaus.- Eine Zeitüberschreitung im Client belegt nicht, dass der entfernte Task fehlgeschlagen ist oder abgebrochen wurde. Setze die Abfragen fort, wenn du eine Task-ID hast; wiederhole die Erstellungsanfrage nicht auf Verdacht.
In dieser Anleitung
- Bevor du beginnst
- Modell auswählen und API-Schlüssel konfigurieren
- Anfrage mit cURL senden
- Task-Polling und Bild-URLs auslesen
- Vollständiges Node.js-Beispiel
- Fehler behandeln
- Unterschiede bei Video und Chat
- Integration überprüfen
Bevor du beginnst
Verwende eine private Terminal- oder Serverumgebung mit Node.js, einem API-Schlüssel und einem Konto, das für die API-Abrechnung eingerichtet ist. Das zugehörige Beispiel nutzt das integrierte fetch und JavaScript-Module; du musst keine Pakete von Drittanbietern installieren. Die Dokumentation der globalen Node.js-APIs beschreibt fetch und AbortSignal.timeout, mit denen der Client die Dauer einzelner Anfragen begrenzt. Die lokale Validierung erfolgte unter Windows mit Node.js v22.22.1; dies dokumentiert die Testumgebung und bedeutet nicht, dass jede andere Version getestet wurde.
Du solltest Dateien bearbeiten, Umgebungsvariablen setzen und JSON lesen können. Prüfe deine installierte Laufzeitumgebung, bevor du fortfährst:
node --version
Der Befehl sollte deine installierte Version ausgeben. Er kontaktiert die Generierungs-API nicht. Speichere den vollständigen Client aus dem späteren Abschnitt als examples/pixmind-image.mjs in einem Arbeitsordner und führe seine Befehle anschließend in diesem Ordner aus.
Wähle einen unbedenklichen Test-Prompt ohne Kundendaten oder vertrauliche Inhalte. Dieses Tutorial verwendet eine Kaffeetasse aus Keramik vor einem Studiohintergrund und benötigt daher keinen Referenz-Upload. Prüfe vor dem Absenden den aktuellen API-Preis des gewählten Modells. Gehe nicht davon aus, dass Studio-Guthaben, Abonnements und API-Abrechnung untereinander austauschbar sind; der Modellkatalog erläutert das jeweils geltende API-Angebot.
Wenn du einfach interaktiv ein Bild erstellen möchtest, beschreibt die Anleitung zum Image Agent diesen Ablauf. Der hier vorgestellte Client ist für eine Anwendung gedacht, die ausdrücklich eine Modell-ID übergibt und die Antwort selbst verarbeitet.
Modell auswählen und API-Schlüssel konfigurieren
Verwende eine von der API unterstützte Modell-ID und Parameter, die dieses Modell unterstützt. Das Beispiel wählt nano-banana-pro mit aspectRatio: "1:1" und resolution: "1K", entsprechend der Bildanfrage im API-Schnellstart. Ein authentifizierter Aufruf von GET /models und der Test im Produktivsystem bestätigten diese Kombination am 04.09.2026 für das Testkonto. Prüfe Verfügbarkeit und Parameterunterstützung für dein eigenes Konto erneut, bevor du einen Live-Durchlauf startest. Nur die Modellzeichenfolge zu ändern, garantiert nicht, dass der Rest der Anfrage weiterhin gültig ist.
Erstelle einen Schlüssel in der API-Konsole und stelle ihn dem Serverprozess anschließend als PIXMIND_API_KEY bereit. Nutze dafür deine private Geheimnisverwaltung, sofern vorhanden. Die folgenden Beispiele zeigen die Syntax für Umgebungsvariablen mit einem Platzhalter, nicht mit gültigen Zugangsdaten.
Für PowerShell:
$env:PIXMIND_API_KEY = "REPLACE_WITH_YOUR_PRIVATE_API_KEY"
$env:PIXMIND_MODEL = "nano-banana-pro"
$env:PIXMIND_PROMPT = "A ceramic coffee cup on a plain studio background, soft side lighting, no text"
Für Bash:
export PIXMIND_API_KEY="REPLACE_WITH_YOUR_PRIVATE_API_KEY"
export PIXMIND_MODEL="nano-banana-pro"
export PIXMIND_PROMPT="A ceramic coffee cup on a plain studio background, soft side lighting, no text"
Diese Zuweisungen konfigurieren die aktuelle Shell und die von ihr gestarteten Prozesse. Sie erstellen keinen Task. Schütze den Shell-Verlauf und Aufzeichnungen, wenn du ein echtes Geheimnis eingibst, und übernimm es niemals in die Versionsverwaltung. Beachte die Hinweise zur Authentifizierung zu getrennten Entwicklungs- und Produktionsschlüsseln sowie zum Austausch offengelegter Schlüssel.
Die Basis-URL dieses Tutorials lautet:
https://aihub-admin.aimix.pro/api-platform/v1
Hänge /generations oder /tasks/{taskId} an diese Basis an. Füge kein zweites /v1 hinzu. Verfügbare Modelle lassen sich über GET /models ermitteln; der Katalog ist der bequemere Ort, um vor der Parameterauswahl die modellspezifischen Funktionen nachzulesen.
Erste Anfrage zur Bildgenerierung mit cURL senden
Die cURL-Anfrage ist eine Alternative zum Node.js-Befehl submit, kein Einrichtungsschritt, den du zuerst ausführen musst. Beide senden eine Generierungsanfrage. Wenn du beide ausführst, können zwei kostenpflichtige Tasks entstehen. Sendest du die Anfrage mit cURL, verwende danach den Node.js-Befehl resume mit der zurückgegebenen Task-ID.
Dieses Beispiel verwendet Bash-Syntax. Nutze in PowerShell den unten stehenden Node.js-Client, statt Bash-Zeilenfortsetzungen in das Terminal einzufügen.
curl --connect-timeout 10 --max-time 30 \
--request POST \
'https://aihub-admin.aimix.pro/api-platform/v1/generations' \
--header "Authorization: Bearer $PIXMIND_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "nano-banana-pro",
"type": "image",
"prompt": "A ceramic coffee cup on a plain studio background, soft side lighting, no text",
"aspectRatio": "1:1",
"resolution": "1K"
}'
Der Prompt und die Parameter in diesem cURL-Anfragetext sind fest eingetragene Werte. Eine Änderung von PIXMIND_PROMPT verändert dieses JSON nicht; diese Umgebungsvariable wird vom Node.js-Client gelesen. Diese Unterscheidung hilft dir, die tatsächlich beabsichtigte Anfrage von der umgebenden Shell-Konfiguration zu trennen.
Unten siehst du eine gekürzte Beispielantwort für eine angenommene Anfrage. Ihre ID ist ein Platzhalter, nicht die ID des Tests im Produktivsystem; 12345 ist kein Task, den du abfragen solltest.
{
"code": 1000,
"message": "success",
"data": {
"id": "img_12345",
"taskId": 12345
}
}
Die getesteten Medienantworten im Produktivsystem enthielten erfolgreiche Daten in einem Objekt mit code, message, data und timestamp; im Beispiel fehlen der Zeitstempel und weitere Felder. Für diesen Ablauf sind sowohl eine erfolgreiche HTTP-Antwort als auch eine gültige Anwendungsantwort erforderlich. Lies data.taskId, nicht data.id: Letzteres kann eine Zeichenfolge mit Präfix wie img_12345 enthalten, während der Pfad zur Task-Abfrage die numerische ID verwendet.
Speichere diese numerische ID sofort. Wenn die Anfrage abläuft, bevor du sie erhältst, halte an und gleiche die Übermittlung mit den Task-Aufzeichnungen deines Kontos oder mithilfe des Supports ab. Das Wiederholen des POST ist kein sicherer Ersatz dafür, den tatsächlichen Ablauf zu klären.
Task-Polling durchführen und Bild-URLs auslesen
Frage den bestehenden Task ab, bis er einen Endzustand erreicht. Die Dokumentation zu asynchronen Tasks beschreibt pending, processing, ready und failed. Nur die letzten beiden Zustände beenden diesen Polling-Ablauf.
Submit once
|
Save numeric taskId
|
GET /tasks/{taskId} <--- wait, then query again
| ^
+--- pending / processing ---+
|
+--- ready ---> read images, stop
|
+--- failed ---> report failure, stop
Ersetze für eine manuelle Abfrage in Bash die Platzhalter-ID durch deine eigene:
TASK_ID="REPLACE_WITH_YOUR_NUMERIC_TASK_ID"
curl --connect-timeout 10 --max-time 30 \
"https://aihub-admin.aimix.pro/api-platform/v1/tasks/$TASK_ID" \
--header "Authorization: Bearer $PIXMIND_API_KEY"
Im aktuellen Antwortformat für Medien erfüllen die benötigten Felder unterschiedliche Aufgaben:
| Feld | Bedeutung für diesen Client |
|---|---|
data.taskId |
Numerische Kennung zur Abfrage des bestehenden Tasks |
data.status |
Gibt an, ob weiter gewartet, das Ergebnis ausgelesen oder bei einem Fehler angehalten werden soll |
data.images |
Array mit Bildausgabe-URLs, das nach ready verwendet wird |
data.videoUrl |
Feld für die Videoausgabe, nicht das Array mit Bildergebnissen |
Eine ready-Antwort ohne nutzbare Bild-URLs ist für deine Anwendung kein erfolgreiches Bildergebnis. Melde diese Abweichung zusammen mit der Task-ID, damit sie untersucht werden kann. Setze keine Beispiel-URL als Ersatz ein und behaupte nicht, ein Bild sei heruntergeladen worden.
Der Client gibt zurückgelieferte Bild-URLs aus; er ruft die Bilddateien nicht ab und archiviert sie nicht. Benötigt deine Anwendung dauerhafte Speicherung, plane diese als separaten Schritt und prüfe die geltenden Bedingungen zur Aufbewahrung und Nutzung der Dateien. Leite aus dem Vorhandensein einer URL keine Garantie für dauerhafte Speicherung ab.
Vollständiges Node.js-Beispiel ausführen
Verwende submit für einen neuen Task oder resume für einen bestehenden. Wenn du das Skript ohne Argumente startest, gibt es Nutzungshinweise aus und ruft keine API auf. Dieses Standardverhalten verhindert, dass ein gewöhnlicher Neustart oder ein kurzer Blick auf die CLI einen neuen Auftrag erstellt.
Speichere den vollständigen Quellcode unten als examples/pixmind-image.mjs:
Vollständiger Node.js-Quellcode: pixmind-image.mjs
import { pathToFileURL } from 'node:url';
const BASE_URL = 'https://aihub-admin.aimix.pro/api-platform/v1';
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
export class ApiError extends Error {
constructor(message, { status = 0, transient = false, retryAfterMs = 0 } = {}) {
super(message);
Object.assign(this, { status, transient, retryAfterMs });
}
}
export function parseTaskId(value) {
if (!/^\d+$/.test(String(value))) throw new Error('Use a numeric taskId, not img_...');
const id = Number(value);
if (!Number.isSafeInteger(id) || id <= 0) throw new Error('Invalid taskId');
return id;
}
export function retryAfter(value, now) {
if (!value) return 0;
if (/^\d+(\.\d+)?$/.test(value)) return Number(value) * 1000;
const date = Date.parse(value);
return Number.isFinite(date) ? Math.max(0, date - now) : 0;
}
export function createClient({
apiKey,
fetchImpl = fetch,
now = Date.now,
wait = sleep,
random = Math.random,
requestTimeoutMs = 30_000,
pollTimeoutMs = 300_000,
maxConsecutiveErrors = 5,
} = {}) {
if (typeof apiKey !== 'string' || !apiKey.trim()) throw new Error('Set PIXMIND_API_KEY');
async function request(path, method, payload, timeoutMs = requestTimeoutMs) {
let response;
let body;
try {
response = await fetchImpl(`${BASE_URL}${path}`, {
method,
redirect: 'error',
headers: {
Authorization: `Bearer ${apiKey}`,
...(payload ? { 'Content-Type': 'application/json' } : {}),
},
...(payload ? { body: JSON.stringify(payload) } : {}),
signal: AbortSignal.timeout(Math.max(1, Math.ceil(timeoutMs))),
});
// Read the body inside the timeout/network error boundary as well.
body = await response.text();
} catch {
throw new ApiError('Network error or request timeout', { transient: true });
}
let envelope;
try { envelope = JSON.parse(body); } catch { /* handle below */ }
const transient = response.status === 429 || response.status >= 500;
if (!response.ok) {
// Do not echo arbitrary server bodies, prompts, credentials, or output URLs.
throw new ApiError(`HTTP ${response.status}; inspect the account and request`, {
status: response.status,
transient,
retryAfterMs: retryAfter(response.headers.get('retry-after'), now()),
});
}
if (!envelope || typeof envelope !== 'object') {
throw new ApiError('Expected a JSON API response');
}
if (envelope.code !== 1000 || !envelope.data) {
throw new ApiError('API returned an unsuccessful or incomplete envelope');
}
return envelope.data;
}
async function submit({ model = 'nano-banana-pro', prompt } = {}) {
if (typeof model !== 'string' || !model.trim()) throw new Error('A model is required');
if (typeof prompt !== 'string' || !prompt.trim()) throw new Error('A prompt is required');
try {
const data = await request('/generations', 'POST', {
model, type: 'image', prompt, aspectRatio: '1:1', resolution: '1K',
});
// The public media contract returns a number, not the prefixed display ID.
if (typeof data.taskId !== 'number') throw new Error('Missing numeric taskId');
return parseTaskId(data.taskId);
} catch (error) {
// A timeout or malformed response does not prove that creation failed.
throw new Error(`Submission not confirmed: ${error.message}. No automatic retry was made. Check task records before submitting again.`);
}
}
async function poll(taskId) {
const id = parseTaskId(taskId);
const deadline = now() + pollTimeoutMs;
let attempts = 0;
let errors = 0;
const timedOut = () => new Error(`Stopped waiting for task ${id}; it may still be running. Resume this ID later.`);
while (now() < deadline) {
let retryFloor = 0;
let task;
try {
task = await request(`/tasks/${id}`, 'GET', undefined,
Math.min(requestTimeoutMs, deadline - now()));
errors = 0;
} catch (error) {
if (now() >= deadline) throw timedOut();
if (!(error instanceof ApiError) || !error.transient) throw error;
errors += 1;
if (errors >= maxConsecutiveErrors) {
throw new Error(`Stopped after ${errors} consecutive query errors for task ${id}; resume this ID later.`);
}
retryFloor = error.retryAfterMs;
}
if (now() >= deadline) throw timedOut();
if (task) {
if (task.taskId !== id) throw new Error('Task response ID does not match the requested task');
if (task.status === 'failed') throw new Error(`Task ${id} failed; inspect its record before creating another task.`);
if (task.status === 'ready') {
if (!Array.isArray(task.images) || task.images.length === 0 ||
!task.images.every(url => {
try { return ['https:', 'http:'].includes(new URL(url).protocol); }
catch { return false; }
})) throw new Error(`Task ${id} is ready but has no valid image URLs`);
return task.images;
}
if (!['pending', 'processing'].includes(task.status)) {
throw new Error(`Task ${id} returned an unrecognized status; inspect its record.`);
}
}
// Client policy, not a PixMind latency guarantee or server-side retry feature.
const ceiling = Math.min(10_000, 1_000 * 2 ** Math.min(attempts++, 4));
const delay = Math.max(retryFloor, ceiling * (0.5 + 0.5 * random()));
const remaining = deadline - now();
if (delay >= remaining) {
// Never poll earlier than Retry-After just to fit the local deadline.
await wait(Math.max(0, remaining));
throw timedOut();
}
await wait(delay);
}
throw timedOut();
}
return { submit, poll };
}
export async function main(args = process.argv.slice(2), env = process.env, deps = {}) {
const log = deps.log ?? console.log;
const [mode, rawId] = args;
if (!mode) {
log('Usage: node examples/pixmind-image.mjs submit | resume TASK_ID');
return;
}
if (!((mode === 'submit' && args.length === 1) || (mode === 'resume' && args.length === 2))) {
throw new Error('Use submit, or resume followed by a numeric taskId');
}
const resumeId = mode === 'resume' ? parseTaskId(rawId) : undefined;
const client = createClient({ ...deps, apiKey: env.PIXMIND_API_KEY });
const id = resumeId ?? await client.submit({
model: env.PIXMIND_MODEL || 'nano-banana-pro',
prompt: env.PIXMIND_PROMPT || 'A studio photograph of an unbranded ceramic coffee cup on a plain background',
});
// Save this line in your application record before relying on the polling process.
log(`TASK_ID=${id}`);
log(`Resume without a new generation: node examples/pixmind-image.mjs resume ${id}`);
const images = await client.poll(id);
log(JSON.stringify({ taskId: id, images }, null, 2));
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
main().catch(error => { console.error(error.message); process.exitCode = 1; });
}
Sieh dir zuerst die Befehlsoberfläche an, ohne etwas abzusenden:
node examples/pixmind-image.mjs
Nachdem du Schlüssel, Modellparameter und erwartete Kosten geprüft hast, erstelle einen Task:
node examples/pixmind-image.mjs submit
Wenn die Erstellung gelingt, gibt der Client TASK_ID sofort aus, noch bevor er auf das Bild wartet. Kopiere den tatsächlichen Wert an einen privaten Speicherort. Dieses Beispiel speichert ihn nicht in einer Datei oder Datenbank. Wenn du die Ausgabe nicht gesichert hast, kann daher beim Schließen des Terminals die Kennung verloren gehen, mit der du die Abfrage fortsetzen könntest.
Um einen Task weiter abzufragen, ersetze 12345 durch den gespeicherten Wert:
node examples/pixmind-image.mjs resume 12345
Dieser Befehl führt ausschließlich GET-Anfragen für den Task aus. Er liest keinen neuen Prompt ein und erstellt kein weiteres Bild. Ein erfolgreicher Endzustand sollte Ausgabe-URLs für deinen eigenen Task liefern; hier werden keine erfundenen Ergebnisse aus dem Produktivsystem als Benchmark angegeben.
Das Beispiel begrenzt jede HTTP-Anfrage auf 30 Sekunden und das gesamte Polling auf fünf Minuten. GET-Wiederholungen verwenden exponentielles Backoff mit zufälliger Streuung, eine lokale Backoff-Obergrenze von 10 Sekunden und gegebenenfalls einen gültigen Retry-After-Antwortheader. Eine längere, vom Server angeforderte Wartezeit hat Vorrang. Passt sie nicht in die lokale Frist, stoppt der Client, ohne vorzeitig erneut abzufragen. Der fünfte aufeinanderfolgende vorübergehende GET-Fehler beendet den Versuch; innerhalb dieser Fehlerfolge sind somit vier Wiederholungen möglich. Diese Werte sind Client-Einstellungen, keine Service-Level-Vereinbarung und kein Versprechen, dass jedes Bild innerhalb von fünf Minuten fertig wird.
Wähle eine zur Anwendung passende Strategie für die gesamte Wartezeit. Ein lang laufender Auftrag kann länger dauern als eine Terminalsitzung oder Webanfrage. Speichere in einem bereitgestellten Dienst die Task-ID zusammen mit deinem eigenen Auftragsdatensatz und stelle dem Browser einen separaten Statusendpunkt bereit, statt Nutzer eine einzige Verbindung offen halten zu lassen.
Fehler behandeln, ohne kostenpflichtige Aufträge doppelt auszuführen
Behandle einen unklaren Ausgang der Erstellung anders als eine fehlgeschlagene Statusabfrage. Eine GET-Anfrage zum Task-Status kann wiederholt werden, ohne eine weitere Generierung zu erstellen. Ein Erstellungs-POST, dessen Antwort verloren ging, hat möglicherweise bereits Arbeit ausgelöst. Deshalb sendet das Beispiel ihn niemals automatisch erneut.
| Beobachtung | Nächster Schritt |
|---|---|
HTTP 400 |
Prüfe vor einem weiteren bewussten Versuch das Anfrageformat, die Modell-ID und die unterstützten Parameter. |
HTTP 401 oder 403 |
Prüfe Authentifizierung und Zugriff. Schreibe den Schlüssel bei der Fehlersuche nicht in Protokolle. |
HTTP 404 bei einer Task-Abfrage |
Prüfe die gespeicherte numerische ID und das Konto, dem der Task gehört. Verwende nicht die Task-ID einer anderen Person. |
HTTP 429 bei einer Task-GET-Anfrage |
Warte gemäß einem gültigen Retry-After-Header und der begrenzten Wiederholungsstrategie des Clients. |
| Netzwerkfehler oder vorübergehender Serverfehler bei einer Task-GET-Anfrage | Wiederhole dieselbe Abfrage mit Backoff und stoppe beim Erreichen der konfigurierten Grenzen. |
Task-Status failed |
Beende die Abfragen und melde den Task-Fehler. Eine neue Generierung erfordert eine separate Entscheidung. |
Zeitüberschreitung bei der Erstellung, ungültiges JSON oder fehlende taskId |
Behandle das Erstellungsergebnis als unbekannt. Prüfe die Task-Aufzeichnungen, bevor du erneut eine Anfrage sendest. |
Gehe nicht davon aus, dass alle Fehler dasselbe Antwortformat haben. Bei der Prüfung im Produktivsystem am 04.09.2026 gab GET /models ohne Authentifizierung HTTP 401 mit ausschließlich code und message zurück; authentifizierte erfolgreiche Medienantworten enthielten zusätzlich data und timestamp. Dieses Tutorial verspricht daher weder eine requestId noch ein retryable-Flag oder ein Preisfeld in jeder Antwort. Die übrigen oben aufgeführten Fehlerfälle beschreiben die Behandlung durch den Client und behaupten nicht, dass jeder davon im Produktivsystem reproduziert wurde. Bewahre den HTTP-Status und, sofern vorhanden, eine von sensiblen Daten bereinigte Anwendungsmeldung auf; behandle fehlerhaft formatierte Antwortinhalte als Fehler, statt innerhalb von JSON.parse abzustürzen.
Eine Zeitüberschreitung beim Polling bedeutet, dass der Client nicht länger wartet, nicht dass der entfernte Task abgebrochen wurde. Bewahre die ID auf und setze die Abfrage später fort. Auch ein unbekannter Status belegt keinen Erfolg: Dieser Client stoppt und meldet ihn zur Prüfung. Wechsle niemals einfach zu „abgeschlossen“, nur weil ein Wert in einer switch-Anweisung nicht berücksichtigt wurde.
Bewahre zur Fehlersuche Task-ID, Modell-ID, Operation, HTTP-Status und ungefähren Zeitpunkt auf. Vermeide es, Autorisierungsheader oder vollständige Anfragetexte mit privaten Prompts aufzuzeichnen. Prüfe vor dem Weitergeben, ob diagnostische Antwortinhalte oder Ausgabe-URLs sensible Informationen enthalten.
Das Muster für Video und Chat anpassen
Video kann denselben Ansatz aus Übermittlung und Polling verwenden, benötigt aber eine eigene Anfragevalidierung und Ergebnisverarbeitung. Prüfe die erforderlichen Eingabemedien, Dauer, Auflösung und Audiooptionen des ausgewählten Videomodells, statt die Felder der Bildanfrage ungeprüft zu übernehmen. Ein fertiggestelltes Video verwendet data.videoUrl, nicht data.images.
Die Anleitung zum Video Agent erläutert einen interaktiven Kreativablauf. Sie kann dir helfen, die gewünschte Einstellung zu definieren, bevor du die Generierung automatisierst. Eine Agent-Funktion belegt jedoch nicht, dass ein gleichnamiger API-Parameter existiert.
Chat ist ein eigener Integrationsweg. Die dokumentierte Route /chat/completions ist OpenAI-kompatibel und liefert eine Chat-Antwort oder einen Stream, wenn Streaming angefordert wird. Übergib diese Antwort nicht an den data.taskId-Parser des Bild-Clients. Dieselbe Basis-URL bedeutet nicht, dass jeder Endpunkt dieselbe Antwortstruktur verwendet.
Halte den Funktionsumfang des Bild-Clients eng begrenzt, bis dieser Ablauf überprüft ist. Ergänze einen Videoadapter oder Chat-Client separat, jeweils mit Tests für das eigene Antwortformat. Diese Trennung lässt sich leichter nachvollziehen als eine einzige Funktion, die errät, ob ein zurückgegebenes Objekt ein Bild-Task, Video-Task oder eine Chat-Nachricht ist.
Integration überprüfen und den nächsten Schritt wählen
Lokale Mock-Tests prüfen das Client-Verhalten, ohne API-Guthaben zu verbrauchen. Die zugehörige Testsuite bestand in der angegebenen Windows- und Node.js-Umgebung 29 Tests, darunter den Übermittlungsablauf mit genau einem POST, das Fortsetzen ausschließlich per GET, fehlerhaft formatierte Antworten, endgültiges Fehlschlagen, Fristen und Wiederholungsgrenzen. Speichere die zugehörige Testdatei neben dem Client-Quellcode und starte die Testsuite anschließend aus dem Tutorial-Ordner:
node --test examples/pixmind-image.test.mjs
Mock-Tests belegen weder die Verfügbarkeit im Produktivsystem noch die Abrechnung. Eine separate kontrollierte Prüfung am 04.09.2026 verwendete denselben Client mit folgendem dokumentierten Umfang:
| Testgegenstand | Beobachtetes Ergebnis |
|---|---|
| Anfrage | Ein POST /generations mit nano-banana-pro, type: "image", aspectRatio: "1:1" und resolution: "1K" |
| Prompt | A studio photograph of an unbranded ceramic coffee cup on a plain background |
| Kennung zum Fortsetzen | Numerische Task-ID 64114, vor dem Polling gespeichert; dies ist eine Referenz zum Nachweis, keine ID zum Abfragen durch Leser |
| Abschluss | Acht GET-Abfragen desselben Tasks; Endstatus ready, mit einer URL in data.images |
| Prüfung der Ausgabe | Das zurückgegebene Bild wurde mit 1.024 × 1.024 Pixeln geladen und zeigte erkennbar eine Keramiktasse vor einem schlichten Hintergrund |
| Abrechnung | Die API-Preisantwort nannte 120 Punkte für diese Konfiguration; im mit dem Task verknüpften API-Buchungsprotokoll wurde eine Abbuchung von 120 Punkten erfasst |
Die Prüfung verwendete einen bestehenden Projekt-API-Schlüssel, einen nicht sensiblen Prompt, keine Referenz-Uploads und keine automatische Wiederholung der Erstellung. Der Buchungseintrag wurde anhand der Task-ID zugeordnet, nicht aus einer Studio-Guthabenanzeige abgeleitet. Nur diese eine Konfiguration und der erfolgreiche Bildablauf wurden live getestet; Video, Chat, Abrechnung bei Fehlern, Rückerstattungen und Zuverlässigkeit bei wiederholten Durchläufen wurden nicht getestet. Prüfe den Preis vor deiner eigenen Anfrage erneut, statt diese historische Abbuchung als dauerhaftes Preisangebot zu betrachten.
Bevor du das Beispiel in einen echten nutzerseitigen Ablauf einbindest, prüfe Folgendes:
- Der Schlüssel bleibt auf dem Server und taucht weder in Client-Bundles noch in Screenshots oder öffentlichen Protokollen auf.
- Das gewählte Modell und jeder einzelne Parameter werden vom aktuellen API-Angebot unterstützt.
- Nach einer angenommenen Übermittlung steht dir eine wiederauffindbare numerische Task-ID zur Verfügung.
resumeführt keinen Erstellungs-POST aus, auch nicht nach vorübergehenden Abfragefehlern.- Ein fehlgeschlagener Task, ein leeres Ergebnis und eine lokale Zeitüberschreitung führen zu unterschiedlichen Diagnosemeldungen.
- Eine verlorene Erstellungsantwort löst keine automatische zweite Übermittlung aus.
Dokumentiere für deine eigene kontrollierte Live-Prüfung das Konto, das Modell, den genehmigten Kostenrahmen, die bereinigte Anfrage, die Task-ID, die Antwort mit dem Endzustand und den tatsächlichen Buchungseintrag. Prüfe die Ausgabe selbst getrennt davon, ob ihre URL vorhanden ist. Führe keine wiederholten „Smoke-Tests“ aus, ohne zu berücksichtigen, dass jede neue Übermittlung kostenpflichtige Arbeit auslösen kann.
Wenn du bereit bist, erstelle einen API-Schlüssel und wähle eine Übermittlungsmethode. Baue zunächst auf dem Ablauf mit gespeicherten Tasks auf, bevor du Warteschlangen, Uploads oder Stapelverarbeitung ergänzt. Wenn du als Nächstes generierte Dateien in einen kreativen Prüfprozess einbinden möchtest, bietet der Canvas-Workflow für Produktwerbung ein separates, von Menschen gesteuertes Beispiel. Er ist kein Versprechen, dass Canvas-Projekte über diese API ausgeführt werden können.
Redaktionelle Verantwortung: PixMind Editorial Team ist die als Autor genannte Organisation dieses Tutorials. Die Beleggrundlage bilden die offizielle Dokumentation, die Mediencontroller-Implementierung des Projekts, 29 lokale Mock-Tests und die oben beschriebene einzelne Prüfung im Produktivsystem, alles am 04.09.2026 geprüft. Bereinigte Task- und Abrechnungsaufzeichnungen werden zur redaktionellen Verifikation aufbewahrt. Es werden weder Qualifikationen eines einzelnen Engineers noch vergleichende Ergebnisse zur Modellqualität oder ein Leistungsbenchmark behauptet.
Wan 3.0 Video: Kompletter Leitfaden zu Eingaben, Audio, Preisen und API



