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
| HTTP | Code | When |
|---|---|---|
401 | unauthorized | Missing, invalid, or revoked key |
403 | forbidden | Key lacks the required permission |
409 | idempotency_conflict | Same Idempotency-Key, different body |
409 | job_not_completed | refresh-url/rating before the job finished |
409 | job_not_cancelable | Cancellation after completion |
422 | packshot_not_approved | Product with no approved packshot |
402 | quota_exceeded | Account out of credits |
429 | rate_limit_exceeded | Request limit exhausted; honour Retry-After |
503 | — | Beta access not yet enabled for the account |
Full list: error reference.