Processing one photo at a time is fine for a live upload form — but dealerships and marketplaces don't deal in one photo. They deal in inventories: hundreds of vehicles, each with a dozen photos. For that, you need a bulk image processing API. This guide shows how to process whole inventories efficiently with the AutoBackgrounding API batch endpoint, where volume drives the rate down to 5¢ per image.
This builds on the integration basics — if you haven't made a single call yet, start there.
Why Batch Instead of Looping
The naive approach is a for loop of synchronous /v1/process calls. It works for a handful of images but falls apart at scale:
- Slow: each request blocks until processing finishes, so 1,000 images take forever serially.
- Fragile: one network hiccup can halt the whole run.
- Rate-limit prone: naive parallel loops slam the API and trigger
429s.
The batch endpoint solves all three: submit everything at once, get job IDs instantly, and let the API process asynchronously while it notifies you as each finishes.
The Batch Endpoint
POST /v1/batch accepts an array of image objects and an optional webhook URL. It returns a batch ID and per-image job IDs immediately — it does not wait for processing to complete.
Submitting a Batch
curl https:"tok-comment">//api.autobackgrounding.com/v1/batch \
-H "Authorization: Bearer $AUTOBG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"background": "studio_white",
"webhook_url": "https:">//yourapp.com/webhooks/autobg",
"images": [
{ "ref": "vin123-01", "image_url": "https:">//example.com/vin123-01.jpg" },
{ "ref": "vin123-02", "image_url": "https:">//example.com/vin123-02.jpg" },
{ "ref": "vin456-01", "image_url": "https:">//example.com/vin456-01.jpg" }
]
}'Note the ref field — attach your own identifier (VIN, stock number, photo slot) so you can match results back to the right vehicle when they return.
Tracking Progress: Polling vs Webhooks
Two ways to collect results:
- Webhooks (recommended): provide a
webhook_urland the API POSTs to it as each image completes. No wasted requests, near real-time. See the webhooks deep-dive. - Polling: periodically call
GET /v1/jobs/{id}to check status. Simple, but less efficient — best for small batches or when you can't host a public endpoint.
async function pollJob(id) {
while (true) {
const res = await fetch(`https:"tok-comment">//api.autobackgrounding.com/v1/jobs/${id}`, {
headers: { Authorization: `Bearer ${process.env.AUTOBG_API_KEY}` },
});
const job = await res.json();
if (job.status === "completed") return job.output_url;
if (job.status === "failed") throw new Error(`Job ${id} failed`);
await new Promise((r) => setTimeout(r, 2000)); "tok-comment">// wait 2s
}
}Safe Concurrency & Rate Limits
If you do fan out synchronous calls (e.g. no public webhook endpoint), cap concurrency so you don't trip rate limits. A small worker pool keeps throughput high without 429s:
async function processPool(items, worker, concurrency = 5) {
const results = [];
let index = 0;
async function run() {
while (index < items.length) {
const current = index++;
results[current] = await worker(items[current]);
}
}
"tok-comment">// Start N workers in parallel
await Promise.all(Array.from({ length: concurrency }, run));
return results;
}
"tok-comment">// Usage: process up to 5 images at a time
const outputs = await processPool(images, processWithRetry, 5);Always honor the limits published on the API docs page and back off when you receive a 429.
Full Inventory Example
A realistic flow: pull vehicles from your database, submit them in chunks to the batch endpoint with a webhook, and store outputs as they arrive.
function chunk(arr, size) {
const out = [];
for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
return out;
}
async function processInventory(vehicles) {
const images = vehicles.flatMap((v) =>
v.photos.map((url, i) => ({ ref: `${v.vin}-${i}`, image_url: url }))
);
"tok-comment">// Submit in batches of 200
for (const batch of chunk(images, 200)) {
await fetch("https:">//api.autobackgrounding.com/v1/batch", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AUTOBG_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
background: "studio_white",
webhook_url: "https:">//yourapp.com/webhooks/autobg",
images: batch,
}),
});
}
"tok-comment">// Results arrive at your webhook; match them by "ref"
}Cost at Scale
Bulk is where the economics shine. The same per-image pricing applies, and higher volume drops your rate to as low as 5¢ per image. Because failed images consume no credits, a 5,000-image inventory run stays predictable. For the full breakdown, see API pricing explained and the live pricing page.
Ready to batch your inventory? Grab an API key and the batch endpoint reference from the API pricing & docs page.