Przejdź do treści

curl examples

A cheat sheet of ready-made curl calls for every endpoint of the plugin integration API.

This is a cheat sheet — just the calls, with no discussion. For step-by-step guides, with responses and error handling, see the main processes.

Replace mk_live_… with your installation's API key. The base URL is https://qamera.ai.

/me

curl https://qamera.ai/api/v1/plugin/me \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Upload a file

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": "shoe.jpg", "content_type": "image/jpeg", "size_bytes": 482310 }'

curl -X PUT "$PRESIGNED_URL" --upload-file shoe.jpg \
  -H "Content-Type: image/jpeg"

Register a source image

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": "SKU-001", "product_metadata": { "display_name": "Buty model X" }, "asset_id": "00000000-0000-0000-0000-000000000010" }
    ]
  }'

Register a packshot (approved right away)

curl -X POST https://qamera.ai/api/v1/plugin/packshots \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Content-Type: application/json" \
  -d '{
    "packshots": [
      { "external_ref": "sklep1:packshot-42", "product_ref": "SKU-001", "product_metadata": { "display_name": "Buty model X" }, "asset_id": "00000000-0000-0000-0000-000000000010" }
    ]
  }'

Submit a session (one product × 4 images)

curl -X POST https://qamera.ai/api/v1/plugin/jobs \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Idempotency-Key: order_12345-submit" \
  -H "Content-Type: application/json" \
  -d '{
    "session_config": {
      "model_id": "00000000-0000-0000-0000-000000000aaa",
      "scenery_id": "00000000-0000-0000-0000-000000000bbb",
      "preset_id": "preset_minimal",
      "aspect_ratio": "4:5",
      "suggestions": "naturalne światło"
    },
    "subjects": [
      {
        "product_label": "Buty model X",
        "product_ref": "SKU-001",
        "images_count": 4,
        "ai_model": "google/gemini-3-pro-image"
      }
    ],
    "external_metadata": { "sku": "SKU-001" }
  }'

Without packshot_asset_id the session uses the product's latest approved packshot. A product with no approved packshot → 422 packshot_not_approved (tutorial).

Order packshot candidates

curl -X POST https://qamera.ai/api/v1/plugin/jobs \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Idempotency-Key: packshoty-SKU-001" \
  -H "Content-Type: application/json" \
  -d '{
    "job_type": "packshot",
    "session_config": { "aspect_ratio": "1:1" },
    "subjects": [
      {
        "packshot_asset_id": "00000000-0000-0000-0000-000000000010",
        "product_label": "Buty model X",
        "product_ref": "SKU-001",
        "images_count": 3,
        "ai_model": "byteplus/seedream-4.5",
        "auto_register_packshot": true,
        "packshot_external_ref": "sklep1:packshot-kandydat"
      }
    ]
  }'

Submit a batch

curl -X POST https://qamera.ai/api/v1/plugin/jobs/batch \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Content-Type: application/json" \
  -d '{
    "batches": [
      {
        "session_config": { "aspect_ratio": "4:5" },
        "subjects": [
          { "product_label": "A", "product_ref": "SKU-A", "images_count": 4, "ai_model": "google/gemini-3-pro-image" }
        ]
      },
      {
        "session_config": { "aspect_ratio": "9:16" },
        "subjects": [
          { "product_label": "B", "product_ref": "SKU-B", "images_count": 4, "ai_model": "google/gemini-3-pro-image" }
        ]
      }
    ]
  }'

Limits: 100 sessions and 5000 images in total. Response: HTTP 207 with a per-session result (tutorial).

Check a job

curl https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000a1 \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

List jobs (last 25 completed)

curl "https://qamera.ai/api/v1/plugin/jobs?status=completed&limit=25" \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Refresh download URLs

curl -X POST https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000a1/refresh-url \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Cancel a pending job

curl -X DELETE https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000a1 \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Accept or reject a completed job

curl -X POST https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000a1/accept \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

curl -X POST https://qamera.ai/api/v1/plugin/jobs/00000000-0000-0000-0000-0000000000a1/reject \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Note: for a packshot job, accepting approves the product's packshot; for a photo_shoot job, it is feedback only (details).

Fetch the full session (order)

curl https://qamera.ai/api/v1/plugin/orders/00000000-0000-0000-0000-000000000099 \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Clone a session

# 1:1 — same products and image counts
curl -X POST https://qamera.ai/api/v1/plugin/orders/00000000-0000-0000-0000-000000000099/clone \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Idempotency-Key: clone-99-runda2" \
  -H "Content-Type: application/json" \
  -d '{}'

# a different image count per product
curl -X POST https://qamera.ai/api/v1/plugin/orders/00000000-0000-0000-0000-000000000099/clone \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
  -H "Idempotency-Key: clone-99-runda3" \
  -H "Content-Type: application/json" \
  -d '{ "subjects": [ { "product_ref": "SKU-001", "images_count": 8 } ] }'

Idempotency-Key is mandatory when cloning (tutorial).

List styles (presets)

curl https://qamera.ai/api/v1/plugin/presets \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Reference data

curl https://qamera.ai/api/v1/plugin/models -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
curl https://qamera.ai/api/v1/plugin/sceneries -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
curl https://qamera.ai/api/v1/plugin/ai-models -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
curl https://qamera.ai/api/v1/plugin/aspect-ratios -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
curl https://qamera.ai/api/v1/plugin/pricing -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Rotate the HMAC secret

curl -X POST https://qamera.ai/api/v1/plugin/installations/00000000-0000-0000-0000-0000000000f1/rotate-hmac \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

The response contains a new webhook_hmac_secret (shown only once); the old one keeps working for another 48 hours.

Re-send a webhook notification

curl -X POST https://qamera.ai/api/v1/plugin/webhooks/00000000-0000-0000-0000-0000000000d1/replay \
  -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"

Common errors

HTTPCodeWhen
401unauthorizedMissing, invalid, or revoked key
403forbiddenKey lacks the required permission
409idempotency_conflictSame Idempotency-Key, different body
409job_not_completedrefresh-url/rating before the job finished
409job_not_cancelableCancellation after completion
422packshot_not_approvedProduct with no approved packshot
402quota_exceededAccount out of credits
429rate_limit_exceededRequest limit exhausted; honour Retry-After
503—Beta access not yet enabled for the account

Full list: error reference.