Пакшот із фото

Крок за кроком — від звичайного фото з магазину, через варіанти пакшота й прийняття одного з них, до замовлення фотосесії.

Що ви отримаєте

Продавець має лише звичайне фото продукту — з телефона, зі складу, з будь-яким тлом. У цьому матеріалі ви завантажите це фото, замовите кілька варіантів пакшота, приймете обраний від імені продавця та замовите першу фотосесію.

Дорогою ви засвоїте найважливіше правило цього API: фотосесію можна замовити лише для продукту з прийнятим пакшотом. Сесія для продукту без прийнятого пакшота повертає 422 packshot_not_approved.

Передумови

  • Ключ API інсталяції (як його отримати) з дозволами: plugin.assets:upload, plugin.catalog:write, plugin.jobs:create, plugin.jobs:read.
  • Звичайне фото продукту (JPEG/PNG/WebP, до 50 МБ).

У прикладах замініть mk_live_… на свій ключ. Базова адреса — https://qamera.ai.

Перебіг

1. POST /assets/upload + PUT      → завантажте фото з магазину
2. POST /images                   → зареєструйте фото в каталозі
3. POST /jobs (job_type=packshot) → замовте N варіантів пакшота
4. POST /jobs/{id}/accept         → прийміть обраний варіант
   POST /jobs/{id}/reject         → відхиліть решту
5. POST /jobs                     → замовте фотосесію

Кроки

1. Завантажте фото з магазину

Так само, як у матеріалі A: отримайте тимчасову адресу та надішліть файл.

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"

Збережіть asset_id з першої відповіді — він знадобиться в кроках 2 і 3.

2. Зареєструйте фото в каталозі

Реєстрація створює продукт (якщо product_ref новий) і прив'язує до нього вихідне фото. Після реєстрації фото автоматично аналізується — аналіз описує продукт і покращує якість генерації.

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

Відповідь (HTTP 200) містить product_id, image_id і status: "created".

Стан аналізу перевірите в полі analysis_status фото (GET /products/sklep1:produkt-7 повертає продукт із вкладеними фото). Перш ніж замовляти генерацію, зачекайте, доки воно набуде значення described — зазвичай це кілька десятків секунд.

3. Замовте варіанти пакшота

Тепер ви замовляєте генерацію: job_type: "packshot", а в продукті сесії:

  • packshot_asset_idтут: asset_id фото з магазину з кроку 1 (це сирий вхідний матеріал, з якого постане пакшот),
  • auto_register_packshot: true — згенерований варіант автоматично потрапить до каталогу продукту (обидва поля обов'язкові при job_type: "packshot"),
  • images_count — скільки варіантів згенерувати (продавцеві буде з чого обирати).
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"
      }
    ]
  }'

Відповідь (HTTP 201) містить order_id і три job_ids — по одному на варіант. Збережіть job_ids; саме ними ви приймете або відхилите варіанти в кроці 4.

Отримайте згенеровані варіанти (вебхук або GET /jobs/{id} — див. отримання результатів) і покажіть їх продавцеві на вибір.

4. Прийміть обраний варіант, відхиліть решту

Два значення прийняття. Прийняття завдання типу packshot має наслідок у каталозі: згенерований пакшот стає прийнятим пакшотом продукту й розблоковує фотосесії. Прийняття завдання типу photo_shoot (зображення із сесії) — це винятково зворотний зв'язок, воно нічого не змінює. Той самий ендпойнт, інший наслідок — вирішує тип завдання.

# варіант, обраний продавцем
curl -X POST https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000b1/accept \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

# решта варіантів
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"

Кожен виклик повертає 204 No Content. Від моменту прийняття продукт sklep1:produkt-7 має прийнятий пакшот — вимогу для фотосесій виконано.

Для порівняння: пакшот, завантажений напряму через POST /packshots (як у матеріалі A), приймається автоматично. Згенеровані варіанти потребують явного прийняття, бо саме продавець вирішує, який із них вдалий.

5. Замовте фотосесію

Точно як у матеріалі A — пропустіть packshot_asset_id, і сесія візьме найновіший прийнятий пакшот продукту (тобто той із кроку 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"
      }
    ]
  }'

Якби ви надіслали цей запит до прийняття з кроку 4, то отримали б 422 packshot_not_approved — і це очікувана поведінка, а не помилка інтеграції.

Поширені помилки

ПомилкаЧому виниклаЩо зробити
422 packshot_not_approvedЖоден варіант ще не прийнято (або всі відхилено)Прийміть один варіант (POST /jobs/{id}/accept) і повторіть сесію — подробиці
400 invalid_input у кроці 3Бракує auto_register_packshot: true або packshot_asset_id при job_type: "packshot"Заповніть обидва поля — вони обов'язкові для генерації пакшотів — подробиці
400 invalid_input у кроці 2Новий product_ref без product_metadata.display_nameДодайте product_metadata з назвою продукту — подробиці
409 idempotency_conflictТой самий external_ref, але інший вміст файлу (дублікат за контрольною сумою)Використайте новий external_ref для нового файлу — подробиці
409 job_not_completedПрийняття/відхилення до того, як варіант згенерувавсяЗачекайте на status: "completed"подробиці
402 quota_exceededНедостатньо кредитів на генераціюПродавець має поповнити кредити — подробиці

Що далі