BulkImagen batch caps 10/50/100: job sizing and Bubble catalog chunking via BIAIG without batch-id sprawl
BulkImagen caps total images per POST /v1/batches—not CSV row count. Size chunks from repeating-group data, store one parent job in Bubble, and avoid non-retryable 403 batch_limit_exceeded.
Why this matters now
I hit this again on an October-scale catalog run: repeating group, credits looked fine—and submit failed. Not insufficient credits. Submit time: one POST with a total that was too large → HTTP 403 batch_limit_exceeded. The docs mark it non-retryable. Chunk before POST. Not in a retry loop.
BulkImagen pricing spells it out: Max images/batch Starter 10, Studio 50, Scale 100, plus concurrent batches 1 / 10 / 20.
What the API actually limits
The cap is images per batch, not catalog row count. I’ve burned myself on that—row count in the CSV lies if templates fan out.
Computed total on POST https://bulkimagen.com/api/v1/batches depends on refMode and countPerCombo (1–20):
| refMode | Approximate total |
|---|---|
none or combined |
≈ len(prompts) × countPerCombo |
each |
≈ len(prompts) × len(refImages) × countPerCombo |
I don’t trust memory for 10/50/100. At run start I GET /v1/me → limits.maxImagesPerBatch, maxConcurrentBatches, activeBatches.
Example (Scale): countPerCombo = 4, refMode = none → up to ~25 prompt rows per POST (100 ÷ 4). Five rows at countPerCombo = 20 already hit 100—row count is misleading.
Credits charge on batch create; I poll GET /v1/batches/{id} until batch.done. The API is server-to-server only (no CORS)—keys and POSTs stay in Bubble backend/API workflows (API Connector), not the browser. A closer look: The ~500-row bulk-tools ceiling in.
Bubble: repeating group / CSV → chunk size
This is how I wire it in a backend workflow:
- Load catalog rows (SKU, template, refs).
- Apply SKU/template logic before chunking—prompts and ref fan-out define images, not raw row count.
- maxRowsPerChunk (prompt rows per POST):
refMode none/combined:floor(maxImagesPerBatch / countPerCombo)refMode each:floor(maxImagesPerBatch / (len(refImages) × countPerCombo))when fan-out is uniform per chunk.
- Pre-flight each POST’s computed
total; if it exceedsmaxImagesPerBatch, shrink the chunk orcountPerCombo.
BIAIG (in-house orchestration layer)
Public BulkImagen/Bubble docs do not name “BIAIG”—here it’s my editorial label for the orchestration layer: one parent catalog job in Bubble, chunk sub-jobs, and an ordered list of BulkImagen batch ids (b_…) from POST responses—no unrelated batch ids scattered in the UI. Worth reading next: BulkImagen day-one GPT Image 2.5:.
Minimal parent Thing fields:
status(draft → chunking → submitting → polling → done / failed)plan_snapshot(from/v1/meat run start)chunk_size,chunk_countbulkimagen_batch_ids(ordered)current_chunk_index, optionallast_error_code
When a single POST would exceed the cap: the parent job does not send one oversized batch. BIAIG (backend workflow) splits into N chunks; each POST keeps total ≤ cap, appends ids, then polls—sequentially or within concurrent limits. Same topic: Fozzels October 2026: Image Flow.
Sequencing and concurrent caps
| Plan | maxImagesPerBatch | maxConcurrentBatches |
|---|---|---|
| Starter | 10 | 1 |
| Studio | 50 | 10 |
| Scale | 100 | 20 |
Starter effectively serializes multi-chunk runs. I tried parallel “schedule on a list” without guardrails once and got concurrent_limit_exceeded.
From Bubble Manual:
- Schedule API workflow on a list—intervals help with rate limits; they do not guarantee non-overlap.
- For strict sequencing (Starter or deliberate queuing)—recursive backend workflow: chunk N → POST → poll until done → N+1.
Parallel chunk POSTs only when activeBatches + new submissions ≤ maxConcurrentBatches (Studio/Scale).
Pre-production checklist
- GET
/v1/me→ storemaxImagesPerBatchon the parent job - Verify
totalformula for yourrefMode/countPerCombo - Chunk on prompt rows or stable catalog keys (SKU ids) if one row fans out to many images
- Credit balance before the POST series (402
insufficient_credits) - After
batch.done, noteresultUrlsare public—control access on Things/in-app - Do not retry
batch_limit_exceeded—reduce chunk size
| Check | What it is for | What it is not for |
|---|---|---|
GET /v1/me → store maxImagesPerBatch on the parent job |
Read batch size limit and persist it on the parent job | Assuming a fixed batch limit without calling /v1/me |
Verify total formula for your refMode / countPerCombo |
Confirm expected image count matches your configuration | Posting batches without validating total for your refMode and countPerCombo |
| Chunk on prompt rows or stable catalog keys (SKU ids) when one row fans out to many images | Keep each batch within limits when fan-out is high | Single giant batches when rows produce many images |
Credit balance before the POST series (402 insufficient_credits) |
Avoid starting a series that fails for lack of credits | Issuing POSTs without checking balance first |
After batch.done, note resultUrls are public—control access on Things/in-app |
Restrict who can reach generated image URLs | Treating resultUrls as private or access-controlled by default |
Do not retry batch_limit_exceeded—reduce chunk size |
Recover by sending smaller chunks | Retrying the same request after batch_limit_exceeded |
Tie-in to SKU templates
Templates define prompt/ref content; plan tier defines max images per POST. My pipeline: template → fan-out → chunk size → BIAIG parent + ordered b_… ids.
Scout sources: bulkimagen.com/pricing, docs/api, llms-full.txt, openapi.json; Bubble Manual—backend workflows, API workflows.