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_id— tu:asset_idzdję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 przyjob_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łąd | Dlaczego 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 3 | Brak 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 2 | Nowy product_ref bez product_metadata.display_name | Dodaj product_metadata z nazwą produktu — szczegóły |
409 idempotency_conflict | Ten sam external_ref, ale inna zawartość pliku (duplikat po sumie kontrolnej) | Użyj nowego external_ref dla nowego pliku — szczegóły |
409 job_not_completed | Akceptacja/odrzucenie, zanim propozycja się wygenerowała | Poczekaj na status: "completed" — szczegóły |
402 quota_exceeded | Za mało kredytów na generowanie | Sprzedawca musi doładować kredyty — szczegóły |
Co dalej
- Sesja z gotowego packshota — krótsza ścieżka, gdy packshot już jest.
- Parametry sesji — daj sprzedawcy wybór stylu i scenerii.
- Ponowna sesja — więcej zdjęć w tym samym stylu.