Bulk sessions
How to order sessions for many products at once — limits, partial success (HTTP 207), and safe retrying.
What you'll achieve
The merchant wants to photograph their entire catalog. In this tutorial you'll send many sessions in a single call, read the result for each one separately (partial success), and learn how to safely retry the failed sessions.
First, pick the right tool:
- Many products, one configuration → one
POST /jobssession with many entries insubjects[](up to 100 products). Simpler, and it supportsIdempotency-Key. - Many sessions with different configurations →
POST /jobs/batch(up to 100 sessions in one call).
Prerequisites
- A plugin installation API key (how to get one) with the
plugin.jobs:create,plugin.jobs:readpermissions. - Every product has an approved packshot — see tutorial A or B.
In the examples, replace mk_live_… with your own key. The base address is https://qamera.ai.
Flow
1. Prepare the sessions (products + configuration) 2. POST /jobs/batch → up to 100 sessions at once 3. HTTP 207 → per-session result (accepted / failed) 4. Retry failed sessions one by one via POST /jobs 5. Receive results via webhooks or polling
Limits
| Limit | Value | What happens when exceeded |
|---|---|---|
| Products in one session | 100 | 400 invalid_input |
Images per product (images_count) | 50 | 400 invalid_input |
| Sessions in one batch | 100 | the whole call is rejected |
Images total in a batch (sum of images_count) | 5000 | the whole call is rejected |
Exceeding the batch limits rejects the whole call — no session is accepted. See batch_limit_exceeded.
Steps
1. Send a batch of sessions
Each entry in batches[] is an independent session — with its own configuration and its own products:
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": "Kubek ceramiczny", "product_ref": "sklep1:produkt-7", "images_count": 4, "ai_model": "byteplus/seedream-4.5" },
{ "product_label": "Talerz deserowy", "product_ref": "sklep1:produkt-8", "images_count": 4, "ai_model": "byteplus/seedream-4.5" }
]
},
{
"session_config": { "aspect_ratio": "9:16" },
"subjects": [
{ "product_label": "Dzbanek szklany", "product_ref": "sklep1:produkt-9", "images_count": 6, "ai_model": "byteplus/seedream-4.5" }
]
}
]
}'
2. Read the result per session (HTTP 207)
A batch always responds with 207 Multi-Status: each session succeeded or failed independently. The indexes in results[] match the order in batches[].
{
"results": [
{
"index": 0,
"status": "accepted",
"result": {
"order_id": "00000000-0000-0000-0000-000000000123",
"status": "pending",
"subjects": [
{ "product_ref": "sklep1:produkt-7", "job_ids": ["…"] },
{ "product_ref": "sklep1:produkt-8", "job_ids": ["…"] }
]
}
},
{
"index": 1,
"status": "failed",
"error": {
"code": "packshot_not_approved",
"message_i18n": { "en": "No accepted packshot found for product_ref=\"sklep1:produkt-9\"…" },
"retryable": false
}
}
],
"accepted_count": 1,
"failed_count": 1
}
Save the order_id of each accepted session. For the failed sessions, error.code tells you what to fix — here, product 9 has no approved packshot.
3. Retry failed sessions one by one
A batch does not support the Idempotency-Key header — retrying the whole batch after a timeout could duplicate sessions that were already accepted. The safe pattern:
- Send the batch once.
- Fix the sessions with
status: "failed"and send them one by one viaPOST /jobs, each with its ownIdempotency-Key:
curl -X POST https://qamera.ai/api/v1/plugin/jobs \
-H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy" \
-H "Idempotency-Key: sklep1-sesja-produkt-9-retry1" \
-H "Content-Type: application/json" \
-d '{
"session_config": { "aspect_ratio": "9:16" },
"subjects": [
{ "product_label": "Dzbanek szklany", "product_ref": "sklep1:produkt-9", "images_count": 6, "ai_model": "byteplus/seedream-4.5" }
]
}'
Thanks to Idempotency-Key, re-sending the same request (within 24 hours) returns the same session instead of creating a second one.
4. Receive the results
For bulk orders, webhooks are more convenient than polling — you get a separate notification for each completed job. See receiving results. You can check the state of an entire session (how many jobs completed, how many failed) with a single call:
curl https://qamera.ai/api/v1/plugin/orders/00000000-0000-0000-0000-000000000123 \ -H "X-Api-Key: mk_live_xxxxxxxx.yyyyyyyy"
Common errors
| Error | Why it happened | What to do |
|---|---|---|
batch_limit_exceeded | More than 100 sessions or more than 5000 images total | Split into smaller batches — details |
failed with packshot_not_approved | One of the products has no approved packshot | Go through tutorial B for that product — details |
failed with quota_exceeded | Credits ran out while the batch was being accepted | Top up credits and retry the failed sessions one by one — details |
429 rate_limit_exceeded | Too many calls per minute | Honor Retry-After; send batches instead of many single calls — details |
429 concurrency_limit_exceeded | Too many jobs for a given AI provider at once | Wait Retry-After seconds and retry — details |
Next steps
- Receiving results — webhooks at scale.
- Repeat session — generate more images for selected products.