Oferta czasowaCzłonkostwo roczne:30% zniżkioraz nielimitowany dostęp do GPT Image, MiniMax H3 i innych modeli
Nowy AI Chat · Darmowe próby każdego dnia
Ulepsz teraz
Pixmind

Szybki start z API PixMind: generowanie obrazów w Node.js

Zapisuj identyfikator zadania, odpytuj o wynik i wznawiaj sprawdzanie bez automatycznego tworzenia kolejnego płatnego zadania.

Spis treści

Przyjęcie żądania generowania obrazu nie oznacza, że obraz jest już gotowy. Aplikacja musi zachować identyfikator zadania, sprawdzać to samo zadanie oraz obsługiwać nieudane lub przerwane żądania tak, by przypadkowo nie uruchomić kolejnego zadania.

W tym samouczku zbudujesz niewielkiego klienta Node.js działającego po stronie serwera, który realizuje ten proces. Udostępnia on osobne polecenia submit i resume: pierwsze tworzy zadanie, a drugie wyłącznie sprawdza istniejące zadanie. Zacznij od identyfikatorów modeli obsługiwanych przez API, a nie od nazwy modelu skopiowanej z banera na stronie głównej.

Samouczek dotyczy generowania obrazów na podstawie tekstu. Nie obejmuje przesyłania plików referencyjnych, tworzenia interfejsu przeglądarkowego ani oceny jakości modeli. Weryfikacja obejmuje 29 lokalnych testów z symulowanymi odpowiedziami oraz jedno kontrolowane zadanie generowania obrazu w środowisku produkcyjnym, przeprowadzone 4 września 2026 r. Zadanie zwróciło jeden obraz, a w rozliczeniach API odnotowano opłatę w wysokości 120 punktów. Jest to pojedyncza kontrola integracji z określoną datą, a nie test porównawczy szybkości, uniwersalna cena czy gwarancja dostępności na innym koncie.

Grafika okładkowa to zrzut ekranu katalogu modeli wykonany 4 września 2026 r. Traktuj go jako ilustrację stanu z tego dnia, a nie aktualną ofertę cenową lub gwarancję dostępności.

Najważniejsze informacje

  • Przechowuj klucz API na serwerze, poza pakietami kodu przeglądarkowego i publicznymi repozytoriami.
  • W przypadku zadania generowania obrazu odczytaj liczbowy identyfikator data.taskId z odpowiedzi potwierdzającej przyjęcie żądania i zachowaj go na potrzeby kolejnych zapytań.
  • Odpytuj zapisane zadanie do momentu uzyskania stanu ready lub failed. Adresy URL obrazów odczytuj z data.images dopiero po pomyślnym zakończeniu zadania.
  • Przekroczenie limitu czasu po stronie klienta nie dowodzi, że zadanie zdalne zakończyło się niepowodzeniem lub zostało anulowane. Jeśli masz identyfikator zadania, wznów zapytania; nie powtarzaj w ciemno żądania utworzenia zadania.

W tym przewodniku

Zanim zaczniesz

Korzystaj z prywatnego terminala lub środowiska serwerowego z Node.js, kluczem API i kontem skonfigurowanym do rozliczeń API. Dołączony przykład używa wbudowanej funkcji fetch oraz modułów JavaScript i nie wymaga instalowania pakietów zewnętrznych. Dokumentacja globalnych interfejsów API Node.js opisuje fetch i AbortSignal.timeout, których klient używa do ograniczania czasu pojedynczego żądania. Lokalne środowisko weryfikacji to Windows z Node.js v22.22.1; jest to zapis konfiguracji testowej, a nie stwierdzenie, że przetestowano wszystkie pozostałe wersje.

Przyda Ci się umiejętność edycji pliku, ustawiania zmiennych środowiskowych i odczytywania JSON. Zanim przejdziesz dalej, sprawdź zainstalowaną wersję środowiska uruchomieniowego:

node --version

Polecenie powinno wyświetlić zainstalowaną wersję. Nie łączy się z API generowania. Zapisz kompletny kod klienta z dalszej części artykułu jako examples/pixmind-image.mjs w folderze roboczym, a następnie uruchamiaj polecenia z tego folderu.

Wybierz bezpieczny prompt testowy, bez danych klientów ani materiałów poufnych. W tym samouczku używamy ceramicznej filiżanki kawy na studyjnym tle, więc przesyłanie materiałów referencyjnych nie jest potrzebne. Przed wysłaniem żądania sprawdź aktualną cenę API dla wybranego modelu. Nie zakładaj, że kredyty Studio, subskrypcje i rozliczenia API można stosować zamiennie; katalog modeli opisuje ofertę API właściwą dla danego modelu.

Jeśli chcesz jedynie utworzyć obraz interaktywnie, odpowiedni proces opisuje przewodnik po Image Agent. Przedstawiony tutaj klient jest przeznaczony dla aplikacji, która jawnie podaje identyfikator modelu i samodzielnie obsługuje odpowiedź.

Wybierz model do generowania obrazów i skonfiguruj klucz API

Użyj identyfikatora modelu obsługiwanego przez API oraz parametrów obsługiwanych przez ten model. W przykładzie wybrano nano-banana-pro z aspectRatio: "1:1" i resolution: "1K", zgodnie z żądaniem generowania obrazu w przewodniku szybkiego startu z API. Uwierzytelnione żądanie GET /models i test produkcyjny potwierdziły tę kombinację dla konta testowego 4 września 2026 r. Przed uruchomieniem na rzeczywistym koncie sprawdź ponownie dostępność i obsługę parametrów dla swojego konta. Zmiana samego ciągu znaków określającego model nie gwarantuje, że reszta żądania pozostanie prawidłowa.

Utwórz klucz w konsoli API, a następnie przekaż go procesowi serwerowemu jako PIXMIND_API_KEY. Jeśli masz dostęp do prywatnego mechanizmu zarządzania sekretami, skorzystaj z niego. Poniższe przykłady pokazują składnię zmiennych środowiskowych z wartością zastępczą, a nie działającymi danymi uwierzytelniającymi.

Dla 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"

Dla 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"

Te przypisania konfigurują bieżącą powłokę i uruchamiane z niej procesy. Nie tworzą zadania. Podczas wprowadzania prawdziwego sekretu chroń historię powłoki i nagrania sesji. Nigdy nie zapisuj sekretu w systemie kontroli wersji. Postępuj zgodnie z wytycznymi dotyczącymi uwierzytelniania: używaj oddzielnych kluczy dla środowisk programistycznego i produkcyjnego oraz wymieniaj klucze po ich ujawnieniu.

Bazowy adres URL w tym samouczku to:

https://aihub-admin.aimix.pro/api-platform/v1

Do tego adresu dodaj /generations lub /tasks/{taskId}. Nie dodawaj drugiego /v1. Listę modeli można pobrać przez GET /models; katalog jest wygodniejszym miejscem do zapoznania się z możliwościami poszczególnych modeli przed wyborem parametrów.

Wyślij pierwsze żądanie generowania obrazu przez cURL

Żądanie cURL jest alternatywą dla polecenia submit w Node.js, a nie krokiem konfiguracji, który trzeba wykonać wcześniej. Oba sposoby wysyłają żądanie generowania. Uruchomienie obu może utworzyć dwa płatne zadania. Jeśli wyślesz żądanie przez cURL, później użyj polecenia resume klienta Node.js ze zwróconym identyfikatorem zadania.

Ten przykład używa składni Bash. W PowerShell skorzystaj z poniższego klienta Node.js zamiast wklejać do terminala znaki kontynuacji wiersza przeznaczone dla Bash.

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"
  }'

Prompt i parametry w treści tego żądania cURL są wartościami wpisanymi na stałe. Zmiana PIXMIND_PROMPT nie zmienia tego JSON; tę zmienną środowiskową odczytuje klient Node.js. To rozróżnienie pomaga oddzielić żądanie, które zamierzasz wysłać, od otaczającej je konfiguracji powłoki.

Poniżej pokazano skróconą, przykładową odpowiedź potwierdzającą przyjęcie żądania. Zawarty w niej identyfikator jest wartością zastępczą, a nie identyfikatorem z testu produkcyjnego; 12345 nie jest zadaniem, o które należy wysyłać zapytania.

{
  "code": 1000,
  "message": "success",
  "data": {
    "id": "img_12345",
    "taskId": 12345
  }
}

W testowanych odpowiedziach produkcyjnego API mediów dane pomyślnych operacji były opakowane w obiekt z polami code, message, data i timestamp; przykład pomija znacznik czasu oraz inne pola. W tym procesie powodzenie wymaga zarówno pomyślnej odpowiedzi HTTP, jak i prawidłowej odpowiedzi na poziomie aplikacji. Odczytuj data.taskId, a nie data.id: drugie pole może zawierać ciąg znaków z prefiksem, taki jak img_12345, podczas gdy ścieżka zapytania o zadanie używa identyfikatora liczbowego.

Zapisz ten liczbowy identyfikator od razu. Jeśli żądanie przekroczy limit czasu, zanim go otrzymasz, zatrzymaj się i ustal, co stało się ze zgłoszeniem, korzystając z rejestru zadań na koncie lub pomocy technicznej. Ponowienie POST nie jest bezpiecznym zamiennikiem sprawdzenia wyniku poprzedniego żądania.

Odpytuj stan zadania i odczytaj adresy URL obrazów

Wysyłaj zapytania o istniejące zadanie, aż osiągnie stan końcowy. Dokumentacja zadań asynchronicznych opisuje stany pending, processing, ready i failed. Tylko dwa ostatnie kończą ten proces odpytywania.

Submit once
    |
Save numeric taskId
    |
GET /tasks/{taskId} <--- wait, then query again
    |                            ^
    +--- pending / processing ---+
    |
    +--- ready  ---> read images, stop
    |
    +--- failed ---> report failure, stop

Aby wysłać ręczne zapytanie w Bash, zastąp przykładowy identyfikator własnym:

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"

W obecnym formacie odpowiedzi API mediów potrzebne pola pełnią różne funkcje:

Pole Znaczenie dla tego klienta
data.taskId Liczbowy identyfikator używany do odpytywania istniejącego zadania
data.status Informacja, czy dalej czekać, odczytać wynik, czy zatrzymać się z powodu niepowodzenia
data.images Tablica adresów URL wynikowych obrazów, używana po uzyskaniu stanu ready
data.videoUrl Pole z wynikiem wideo, a nie tablica wynikowych obrazów

Odpowiedź ready bez użytecznych adresów URL obrazów nie jest pomyślnym wynikiem generowania obrazu dla aplikacji. Zgłoś tę niezgodność wraz z identyfikatorem zadania, aby można było ją zbadać. Nie podstawiaj przykładowego adresu URL ani nie informuj, że obraz został pobrany.

Klient wyświetla zwrócone adresy URL obrazów; nie pobiera ani nie archiwizuje plików graficznych. Jeśli aplikacja wymaga trwałego przechowywania, zaprojektuj je jako osobny etap i potwierdź odpowiednie warunki przechowywania oraz użytkowania zasobów. Samo istnienie adresu URL nie oznacza gwarancji bezterminowego przechowywania.

Uruchom kompletny przykład w Node.js

Użyj submit, aby utworzyć jedno nowe zadanie, lub resume, aby sprawdzić istniejące. Uruchomienie skryptu bez argumentów wyświetla instrukcję użycia i nie wywołuje API. Dzięki takiemu domyślnemu zachowaniu zwykłe ponowne uruchomienie lub szybkie sprawdzenie interfejsu CLI nie tworzy nowego zadania.

Zapisz cały poniższy kod jako examples/pixmind-image.mjs:

Kompletny kod źródłowy Node.js: 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; });
}

Najpierw sprawdź interfejs poleceń bez wysyłania żądania:

node examples/pixmind-image.mjs

Po sprawdzeniu klucza, parametrów modelu i przewidywanej opłaty utwórz jedno zadanie:

node examples/pixmind-image.mjs submit

Po pomyślnym utworzeniu zadania klient od razu wyświetla TASK_ID, zanim zacznie czekać na obraz. Skopiuj rzeczywistą wartość w prywatne miejsce. W tym przykładzie nie jest ona zapisywana w pliku ani w bazie danych, więc zamknięcie terminala może pozbawić Cię identyfikatora potrzebnego do wznowienia, jeśli nie zachowasz danych wyjściowych.

Aby kontynuować odpytywanie zadania, zastąp 12345 zapisaną wartością:

node examples/pixmind-image.mjs resume 12345

To polecenie wykonuje wyłącznie żądania GET dotyczące zadania. Nie odczytuje nowego promptu i nie tworzy kolejnego obrazu. Pomyślny stan końcowy powinien zwrócić adresy URL wyników Twojego zadania; nie podajemy tutaj zmyślonych wyników produkcyjnych jako punktu odniesienia.

Przykład stosuje limit 30 sekund na każde żądanie HTTP oraz pięciominutowy limit całego odpytywania. Ponowienia GET korzystają z wykładniczo rosnących opóźnień z losowym rozrzutem, lokalnego limitu opóźnienia wynoszącego 10 sekund oraz prawidłowego nagłówka odpowiedzi Retry-After, gdy ma on zastosowanie. Dłuższy czas oczekiwania wskazany przez serwer ma pierwszeństwo; jeśli nie mieści się w lokalnym limicie czasu, klient zatrzymuje się bez wcześniejszego wysyłania zapytania. Piąty z rzędu przejściowy błąd GET kończy próbę, co pozwala na cztery ponowienia w takiej serii błędów. Są to ustawienia klienta, a nie umowa o gwarantowanym poziomie usług ani obietnica, że każdy obraz będzie gotowy w ciągu pięciu minut.

Dobierz zasady łącznego czasu oczekiwania do swojej aplikacji. Długotrwałe zadanie może trwać dłużej niż sesja terminala lub żądanie internetowe. We wdrożonej usłudze zapisz identyfikator zadania we własnym rekordzie zlecenia i udostępnij przeglądarce osobny punkt końcowy do sprawdzania stanu, zamiast wymagać od użytkownika utrzymywania jednego otwartego połączenia.

Obsługuj błędy bez powielania płatnych zadań

Niepewny wynik utworzenia zadania traktuj inaczej niż nieudane zapytanie o jego stan. Żądanie GET sprawdzające zadanie można ponowić bez uruchamiania kolejnego generowania. Żądanie POST tworzące zadanie, którego odpowiedź zaginęła, mogło już uruchomić pracę, dlatego przykład nigdy nie wysyła go ponownie automatycznie.

Zaobserwowana sytuacja Następny krok
HTTP 400 Przed kolejną świadomą próbą sprawdź strukturę żądania, identyfikator modelu i obsługiwane parametry.
HTTP 401 lub 403 Sprawdź uwierzytelnianie i uprawnienia dostępu. Podczas debugowania nie zapisuj klucza w logach.
HTTP 404 przy zapytaniu o zadanie Sprawdź zapisany identyfikator liczbowy i konto, do którego należy zadanie. Nie podstawiaj identyfikatora zadania innej osoby.
HTTP 429 przy żądaniu GET dotyczącym zadania Odczekaj zgodnie z prawidłowym nagłówkiem Retry-After i ograniczonymi zasadami ponawiania klienta.
Błąd sieci lub przejściowy błąd serwera przy żądaniu GET dotyczącym zadania Ponów to samo zapytanie z opóźnieniem i zatrzymaj się po osiągnięciu skonfigurowanych limitów.
Stan zadania failed Zatrzymaj odpytywanie i zgłoś niepowodzenie zadania. Nowe generowanie wymaga osobnej decyzji.
Przekroczenie limitu czasu tworzenia, nieprawidłowy JSON lub brak taskId Traktuj wynik utworzenia jako nieznany. Przed ponownym wysłaniem żądania sprawdź rejestr zadań.

Nie zakładaj, że wszystkie błędy mają ten sam format odpowiedzi. Podczas kontroli produkcyjnej 4 września GET /models bez uwierzytelniania zwróciło HTTP 401 z samymi polami code i message; uwierzytelnione pomyślne odpowiedzi API mediów zawierały również data i timestamp. Dlatego ten samouczek nie obiecuje obecności requestId, flagi retryable ani pola z ceną w każdej odpowiedzi. Pozostałe przypadki błędów z tabeli opisują obsługę po stronie klienta, a nie potwierdzają, że każdy z nich odtworzono w środowisku produkcyjnym. Zachowuj status HTTP oraz komunikat aplikacji po usunięciu danych wrażliwych, jeśli jest dostępny; nieprawidłowe treści odpowiedzi obsługuj jako błędy, zamiast dopuścić do nieobsłużonego wyjątku w JSON.parse.

Przekroczenie limitu czasu odpytywania oznacza, że klient przestał czekać, a nie że zdalne zadanie zostało anulowane. Zachowaj identyfikator i wznów sprawdzanie później. Nieznany stan również nie dowodzi powodzenia: ten klient zatrzymuje się i zgłasza go do sprawdzenia. Nigdy nie przechodź automatycznie do „zakończono” tylko dlatego, że danej wartości nie uwzględniono w instrukcji switch.

Na potrzeby rozwiązywania problemów zachowuj identyfikator zadania, identyfikator modelu, operację, status HTTP i przybliżony czas. Unikaj zapisywania nagłówków autoryzacji lub pełnych treści żądań z prywatnymi promptami. Zanim udostępnisz diagnostyczne treści odpowiedzi lub adresy URL wyników, sprawdź, czy nie zawierają poufnych informacji.

Dostosuj ten schemat do wideo i czatu

Wideo może korzystać z tego samego schematu wysłania żądania i odpytywania, ale wymaga własnej walidacji żądania i odczytu wyników. Sprawdź wymagane media wejściowe, czas trwania, rozdzielczość i opcje dźwięku wybranego modelu wideo, zamiast zakładać, że można ponownie użyć pól z treści żądania generowania obrazu. Gotowe wideo korzysta z data.videoUrl, a nie z data.images.

Przewodnik po Video Agent wyjaśnia interaktywny proces twórczy. Może pomóc określić zamierzone ujęcie przed zautomatyzowaniem generowania, ale obecność funkcji Agenta nie jest dowodem na istnienie parametru API o identycznej nazwie.

Czat stanowi osobną ścieżkę integracji. Udokumentowana ścieżka /chat/completions jest zgodna z OpenAI i zwraca odpowiedź czatu lub strumień, jeśli zażądano przesyłania strumieniowego. Nie przekazuj tej odpowiedzi do parsera data.taskId klienta obrazów. Ten sam bazowy adres URL nie oznacza takiej samej struktury odpowiedzi dla każdego punktu końcowego.

Ogranicz zakres klienta do obrazów, dopóki nie zweryfikujesz tej ścieżki. Adapter wideo lub klienta czatu dodaj osobno, wraz z testami właściwego dla niego formatu odpowiedzi. Taki podział jest łatwiejszy do zrozumienia niż jedna funkcja, która zgaduje, czy zwrócony obiekt jest zadaniem obrazowym, zadaniem wideo czy wiadomością czatu.

Zweryfikuj integrację i wybierz następny krok

Lokalne testy z symulowanymi odpowiedziami sprawdzają zachowanie klienta bez zużywania salda API. Dołączony zestaw pomyślnie przeszedł 29 testów we wskazanym środowisku Windows i Node.js. Obejmowały one ścieżkę wysłania z jednym POST, wznowienie wyłącznie przez GET, nieprawidłowe odpowiedzi, końcowe niepowodzenie, limity czasu i limity ponowień. Zapisz dołączony plik testowy obok kodu źródłowego klienta, a następnie uruchom zestaw testów z folderu samouczka:

node --test examples/pixmind-image.test.mjs

Testy z symulowanymi odpowiedziami nie potwierdzają dostępności produkcyjnej ani rozliczeń. W osobnej kontrolowanej próbie 4 września 2026 r. użyto tego samego klienta i zapisano następujący zakres wyników:

Element testu Zaobserwowany wynik
Żądanie Jedno POST /generations z nano-banana-pro, type: "image", aspectRatio: "1:1" i resolution: "1K"
Prompt A studio photograph of an unbranded ceramic coffee cup on a plain background
Identyfikator do wznowienia Liczbowy identyfikator zadania 64114, zachowany przed odpytywaniem; jest to odniesienie do materiału dowodowego, a nie identyfikator, o który czytelnicy powinni wysyłać zapytania
Zakończenie Osiem zapytań GET o to samo zadanie; końcowy stan ready, z jednym adresem URL w data.images
Sprawdzenie wyniku Zwrócony obraz wczytał się w rozdzielczości 1024 × 1024 piksele i wyraźnie przedstawiał ceramiczną filiżankę na jednolitym tle
Rozliczenie Odpowiedź API z wyceną wskazała 120 punktów za tę konfigurację; rejestr rozliczeń API powiązany z zadaniem odnotował obciążenie w wysokości 120 punktów

W próbie użyto jednego istniejącego klucza API projektu i promptu bez danych wrażliwych, bez przesyłania materiałów referencyjnych oraz bez automatycznego ponawiania tworzenia zadania. Wpis w rejestrze rozliczeń dopasowano do identyfikatora zadania, zamiast wnioskować o nim na podstawie wyświetlanego salda Studio. Na żywo przetestowano tylko tę jedną konfigurację i pomyślną ścieżkę generowania obrazu; nie testowano wideo, czatu, rozliczeń nieudanych zadań, zwrotów opłat ani niezawodności przy powtarzanych uruchomieniach. Przed własnym zgłoszeniem sprawdź cenę ponownie, zamiast traktować tę historyczną opłatę jako stałą ofertę.

Zanim podłączysz przykład do rzeczywistego procesu dostępnego dla użytkowników, sprawdź, czy:

  • Klucz pozostaje na serwerze i nie ma go w pakietach kodu klienckiego, na zrzutach ekranu ani w publicznych logach.
  • Wybrany model i każdy parametr są obsługiwane w aktualnej ofercie API.
  • Po przyjęciu żądania masz zapisany liczbowy identyfikator zadania, który umożliwia wznowienie sprawdzania.
  • resume nie wykonuje POST tworzącego zadanie, również po przejściowych błędach zapytań.
  • Niepowodzenie zadania, pusty wynik i lokalne przekroczenie limitu czasu dają różne wyniki diagnostyczne.
  • Utrata odpowiedzi na żądanie utworzenia nie uruchamia automatycznego drugiego zgłoszenia.

Podczas własnej kontrolowanej próby na żywo zapisz konto, model, zatwierdzony zakres kosztów, żądanie z usuniętymi danymi wrażliwymi, identyfikator zadania, odpowiedź ze stanem końcowym i rzeczywisty wpis rozliczeniowy. Sprawdź sam wynik niezależnie od sprawdzenia, czy istnieje jego adres URL. Nie uruchamiaj kolejnych „testów dymnych” bez uwzględnienia tego, że każde nowe zgłoszenie może uruchomić płatne zadanie.

Gdy będziesz gotów, utwórz klucz API i wybierz jedną metodę wysyłania żądania. Zacznij od procesu opartego na zapisanym zadaniu, zanim dodasz kolejki, przesyłanie plików czy przetwarzanie wsadowe. Jeśli kolejnym krokiem ma być włączenie wygenerowanych zasobów do procesu oceny kreacji, proces tworzenia reklamy produktu w Canvas przedstawia osobny przykład sterowany przez człowieka; nie stanowi obietnicy, że projekty Canvas można wykonywać przez to API.

Odpowiedzialność redakcyjna: PixMind Editorial Team to nazwa zespołu podpisującego ten samouczek jako autor organizacyjny. Podstawę dowodową stanowią oficjalna dokumentacja, implementacja kontrolera mediów w projekcie, 29 lokalnych testów z symulowanymi odpowiedziami i opisana powyżej pojedyncza kontrola produkcyjna. Wszystkie te materiały sprawdzono 4 września 2026 r. Zapisy zadania i rozliczeń po usunięciu danych wrażliwych są przechowywane na potrzeby weryfikacji redakcyjnej. Nie przypisujemy indywidualnemu inżynierowi określonych kwalifikacji ani nie przedstawiamy wyników porównania jakości modeli czy testu porównawczego wydajności.


Wan 3.0 Video: kompletny przewodnik po danych wejściowych, audio, cenach i API

继续浏览中,生成器即将加载...