Packshot ze zdjęcia

Krok po kroku — od zwykłego zdjęcia ze sklepu, przez propozycje packshota i akceptację jednej z nich, do zamówienia sesji zdjęciowej.

Co osiągniesz

Sprzedawca ma tylko zwykłe zdjęcie produktu — z telefonu, z magazynu, z dowolnym tłem. W tym samouczku wgrasz to zdjęcie, zamówisz kilka propozycji packshota, zaakceptujesz wybraną w imieniu sprzedawcy i zamówisz pierwszą sesję zdjęciową.

Po drodze poznasz najważniejszą zasadę tego API: sesję zdjęciową można zamówić tylko dla produktu z zaakceptowanym packshotem. Sesja dla produktu bez zaakceptowanego packshota zwraca 422 packshot_not_approved.

Wymagania wstępne

  • Klucz API instalacji (jak go zdobyć) z uprawnieniami: plugin.assets:upload, plugin.catalog:write, plugin.jobs:create, plugin.jobs:read.
  • Zwykłe zdjęcie produktu (JPEG/PNG/WebP, do 50 MB).

W przykładach zamień mk_live_… na swój klucz. Bazowy adres to https://qamera.ai.

Przebieg

1. POST /assets/upload + PUT      → wgraj zdjęcie ze sklepu
2. POST /images                   → zarejestruj zdjęcie w katalogu
3. POST /jobs (job_type=packshot) → zamów N propozycji packshota
4. POST /jobs/{id}/accept         → zaakceptuj wybraną propozycję
   POST /jobs/{id}/reject         → odrzuć pozostałe
5. POST /jobs                     → zamów sesję zdjęciową

Kroki

1. Wgraj zdjęcie ze sklepu

Tak samo jak w samouczku A: pobierz tymczasowy adres i wyślij plik.

curl -X POST https://qamera.ai/api/v1/plugin/assets/upload \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "presigned",
    "filename": "kubek-z-telefonu.jpg",
    "content_type": "image/jpeg",
    "size_bytes": 1893421
  }'

curl -X PUT "$UPLOAD_URL" \
  --upload-file kubek-z-telefonu.jpg \
  -H "Content-Type: image/jpeg"

Zapisz asset_id z pierwszej odpowiedzi — użyjesz go w krokach 2 i 3.

2. Zarejestruj zdjęcie w katalogu

Rejestracja tworzy produkt (jeśli product_ref jest nowy) i podpina do niego zdjęcie źródłowe. Po rejestracji zdjęcie jest automatycznie analizowane — analiza opisuje produkt i poprawia jakość generowania.

curl -X POST https://qamera.ai/api/v1/plugin/images \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
      {
        "external_ref": "sklep1:zdjecie-101",
        "product_ref": "sklep1:produkt-7",
        "product_metadata": { "display_name": "Kubek ceramiczny 300 ml" },
        "asset_id": "9a3b8f4c-2e7a-4c1b-8d0a-1f6c2e9b3d51"
      }
    ]
  }'

Odpowiedź (HTTP 200) zawiera product_id, image_id i status: "created".

Stan analizy sprawdzisz w polu analysis_status zdjęcia (GET /products/sklep1:produkt-7 zwraca produkt z osadzonymi zdjęciami). Zanim zamówisz generowanie, poczekaj aż będzie miało wartość described zwykle to kilkanaście sekund.

3. Zamów propozycje packshota

Teraz zamawiasz generowanie: job_type: "packshot", a w produkcie sesji:

  • packshot_asset_idtu: asset_id zdjęcia ze sklepu z kroku 1 (to surowy materiał wejściowy, z którego powstanie packshot),
  • auto_register_packshot: true — wygenerowana propozycja trafi automatycznie do katalogu produktu (oba pola są wymagane przy job_type: "packshot"),
  • images_count — ile propozycji wygenerować (sprzedawca będzie miał z czego wybierać).
curl -X POST https://qamera.ai/api/v1/plugin/jobs \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Idempotency-Key: sklep1-packshoty-produkt-7" \
  -H "Content-Type: application/json" \
  -d '{
    "job_type": "packshot",
    "session_config": { "aspect_ratio": "1:1" },
    "subjects": [
      {
        "packshot_asset_id": "9a3b8f4c-2e7a-4c1b-8d0a-1f6c2e9b3d51",
        "product_label": "Kubek ceramiczny 300 ml",
        "product_ref": "sklep1:produkt-7",
        "images_count": 3,
        "ai_model": "byteplus/seedream-4.5",
        "auto_register_packshot": true,
        "packshot_external_ref": "sklep1:packshot-kandydat"
      }
    ]
  }'

Odpowiedź (HTTP 201) zawiera order_id i trzy job_ids — po jednym na propozycję. Zapisz job_ids; to nimi zaakceptujesz lub odrzucisz propozycje w kroku 4.

Odbierz wygenerowane propozycje (webhook lub GET /jobs/{id} — zobacz odbieranie wyników) i pokaż je sprzedawcy do wyboru.

4. Zaakceptuj wybraną propozycję, odrzuć pozostałe

Dwa znaczenia akceptacji. Akceptacja zadania typu packshot ma skutek w katalogu: wygenerowany packshot staje się zaakceptowanym packshotem produktu i odblokowuje sesje zdjęciowe. Akceptacja zadania typu photo_shoot (zdjęcia z sesji) to wyłącznie informacja zwrotna — niczego nie zmienia. Ten sam endpoint, inny skutek — decyduje typ zadania.

# propozycja wybrana przez sprzedawcę
curl -X POST https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000b1/accept \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

# pozostałe propozycje
curl -X POST https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000b2/reject \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
curl -X POST https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000b3/reject \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Każde wywołanie zwraca 204 No Content. Od momentu akceptacji produkt sklep1:produkt-7 ma zaakceptowany packshot — wymóg dla sesji zdjęciowych jest spełniony.

Dla porównania: packshot wgrany bezpośrednio przez POST /packshots (jak w samouczku A) jest akceptowany automatycznie. Wygenerowane propozycje wymagają jawnej akceptacji, bo to sprzedawca decyduje, która jest dobra.

5. Zamów sesję zdjęciową

Dokładnie jak w samouczku A — pomiń packshot_asset_id, a sesja użyje najnowszego zaakceptowanego packshota produktu (czyli tego z kroku 4):

curl -X POST https://qamera.ai/api/v1/plugin/jobs \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Idempotency-Key: sklep1-sesja-produkt-7" \
  -H "Content-Type: application/json" \
  -d '{
    "session_config": { "aspect_ratio": "4:5" },
    "subjects": [
      {
        "product_label": "Kubek ceramiczny 300 ml",
        "product_ref": "sklep1:produkt-7",
        "images_count": 4,
        "ai_model": "byteplus/seedream-4.5"
      }
    ]
  }'

Gdybyś wysłał to żądanie przed akceptacją z kroku 4, dostałbyś 422 packshot_not_approved — i to jest oczekiwane zachowanie, nie błąd integracji.

Częste błędy

BłądDlaczego wystąpiłCo zrobić
422 packshot_not_approvedŻadna propozycja nie została jeszcze zaakceptowana (albo wszystkie odrzucono)Zaakceptuj jedną propozycję (POST /jobs/{id}/accept) i ponów sesję — szczegóły
400 invalid_input przy kroku 3Brak auto_register_packshot: true lub packshot_asset_id przy job_type: "packshot"Uzupełnij oba pola — są wymagane dla generowania packshotów — szczegóły
400 invalid_input przy kroku 2Nowy product_ref bez product_metadata.display_nameDodaj product_metadata z nazwą produktu — szczegóły
409 idempotency_conflictTen sam external_ref, ale inna zawartość pliku (duplikat po sumie kontrolnej)Użyj nowego external_ref dla nowego pliku — szczegóły
409 job_not_completedAkceptacja/odrzucenie, zanim propozycja się wygenerowałaPoczekaj na status: "completed"szczegóły
402 quota_exceededZa mało kredytów na generowanieSprzedawca musi doładować kredyty — szczegóły

Co dalej