If you are building dealership tools, an inventory management system, or a marketplace in JavaScript, the car background removal API is one of the fastest ways to turn messy lot photos into clean, studio-quality vehicle images. This Node.js tutorial walks through a complete, production-ready integration of the AutoBackgrounding vehicle image API — from your first authenticated request to a concurrency-controlled bulk pipeline that can process an entire inventory.
Every snippet below is copy-paste ready and uses standard Node.js (native fetch and fs/promises), so you can adapt it to Express, Next.js route handlers, AWS Lambda, or a background worker without pulling in extra dependencies.
Why Node.js for vehicle image processing
Node.js is a natural fit for an image processing API because most of the work is I/O bound: you are uploading photos, waiting on the API, and writing results. Node's non-blocking event loop lets you keep many vehicle images in flight at once without spinning up heavy threads, which is exactly what you want when a dealer uploads 40 photos of a single truck or syncs a 500-vehicle inventory overnight.
- Native
fetchmeans no HTTP client dependency for calling the background removal API. - Streams and
fs/promisesmake reading and writing large car photos straightforward. - The same code runs in serverless functions, containers, and long-running workers.
Prerequisites
Before you call the automotive photo API, make sure you have:
- Node.js 18 or newer installed (
node --version). - An AutoBackgrounding API key from the API pricing & docs page.
- A few sample vehicle photos to test with.
Store your API key in an environment variable rather than hard-coding it:
"tok-comment"># Never commit this file
AUTOBG_API_KEY="sk_live_your_api_key_here"
AUTOBG_API_BASE="https:">//api.autobackgrounding.com/v1"Authentication and API keys
The background removal API uses bearer token authentication. You pass your API key in the Authorization header on every request. A small helper keeps this DRY across your codebase:
"tok-comment">// client.js - a tiny wrapper around the car background removal API
const API_BASE = process.env.AUTOBG_API_BASE
const API_KEY = process.env.AUTOBG_API_KEY
export async function autobgFetch(path, options = {}) {
const res = await fetch(API_BASE + path, {
...options,
headers: {
Authorization: "Bearer " + API_KEY,
"Content-Type": "application/json",
...options.headers,
},
})
if (!res.ok) {
const detail = await res.text()
throw new Error("AutoBG API error " + res.status + ": " + detail)
}
return res.json()
}Keeping authentication in one place means you only have to update the header logic once when you rotate keys or add features like request IDs and logging.
Your first background removal request
The simplest way to process a single vehicle photo is to submit an image URL to the background removal endpoint and request a clean white studio background. This is the "hello world" of the vehicle image API:
import { autobgFetch } from "./client.js"
async function removeBackground(imageUrl) {
"tok-comment">// Submit the car photo for background removal
const job = await autobgFetch("/images/process", {
method: "POST",
body: JSON.stringify({
image_url: imageUrl,
background: "white_studio", "tok-comment">// clean dealership background
output_format: "png",
remove_other_vehicles: true, "tok-comment">// strip nearby cars from the lot
}),
})
console.log("Job submitted:", job.id)
return job
}
removeBackground("https:">//example.com/lot-photos/truck-front.jpg")
.then((job) => console.log("Status:", job.status))
.catch((err) => console.error(err))For small images the API can respond synchronously, but for full-resolution vehicle photos the request returns a job you poll for completion. That is the pattern you should build around for anything production-grade.
Handling async jobs and polling
When you submit a car photo, the image processing API returns a job with a status of queued or processing. You then poll the job endpoint until it is completed (or failed). Here is a robust polling helper with a timeout and backoff:
import { autobgFetch } from "./client.js"
const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
export async function waitForJob(jobId, { timeoutMs = 120000, intervalMs = 1500 } = {}) {
const start = Date.now()
while (Date.now() - start < timeoutMs) {
const job = await autobgFetch("/images/jobs/" + jobId)
if (job.status === "completed") return job
if (job.status === "failed") {
throw new Error("Processing failed: " + (job.error || "unknown error"))
}
"tok-comment">// Still processing - wait, then poll again
await sleep(intervalMs)
}
throw new Error("Timed out waiting for job " + jobId)
}Combine the submit and poll steps into a single reusable function so the rest of your app can process a vehicle image in one call:
import { autobgFetch } from "./client.js"
import { waitForJob } from "./poll.js"
export async function processVehiclePhoto(imageUrl, background = "white_studio") {
const job = await autobgFetch("/images/process", {
method: "POST",
body: JSON.stringify({ image_url: imageUrl, background, output_format: "png" }),
})
const finished = await waitForJob(job.id)
return finished.output_url "tok-comment">// hosted URL of the processed car photo
}Processing an inventory in bulk
Dealers rarely have one photo. To process an entire inventory with the bulk image processing APIwithout exceeding your rate limit, use a concurrency limiter. This example keeps a fixed number of vehicle photos in flight at a time:
import { processVehiclePhoto } from "./process-one.js"
"tok-comment">// Simple concurrency-controlled map for the car image API
async function mapWithConcurrency(items, limit, worker) {
const results = []
let index = 0
const runners = Array.from({ length: limit }, async () => {
while (index < items.length) {
const current = index++
try {
results[current] = { ok: true, value: await worker(items[current]) }
} catch (err) {
results[current] = { ok: false, error: String(err) }
}
}
})
await Promise.all(runners)
return results
}
const inventory = [
"https:">//example.com/vin1-front.jpg",
"https:">//example.com/vin1-side.jpg",
"https:">//example.com/vin2-front.jpg",
"tok-comment">// ...hundreds more vehicle photos
]
"tok-comment">// Keep 5 background removal requests in flight at once
const results = await mapWithConcurrency(inventory, 5, (url) => processVehiclePhoto(url))
console.log("Processed", results.filter((r) => r.ok).length, "of", inventory.length, "car photos")Tune the concurrency number to match the rate limit on your plan. If you are processing thousands of images, prefer the async batch endpoint with webhooks — covered in the webhooks and async processing guide — so you are not holding open hundreds of long-lived connections.
Production error handling and retries
A real integration with any vehicle photo API has to survive transient network errors, rate limit responses (HTTP 429), and the occasional 5xx. Wrap requests in an exponential-backoff retry that respects the Retry-After header:
const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
export async function withRetry(fn, { retries = 4, baseDelay = 500 } = {}) {
let attempt = 0
while (true) {
try {
return await fn()
} catch (err) {
attempt++
const message = String(err)
const isRetryable = message.includes("429") || message.includes("50")
if (!isRetryable || attempt > retries) throw err
"tok-comment">// Exponential backoff: 0.5s, 1s, 2s, 4s...
const delay = baseDelay * 2 ** (attempt - 1)
console.warn("Retry " + attempt + " after " + delay + "ms")
await sleep(delay)
}
}
}Wiring it into an Express endpoint
Finally, expose the background removal API through your own backend so your frontend never sees your API key. This Express route accepts an image URL, processes the car photo, and returns the clean result:
import express from "express"
import { processVehiclePhoto } from "./process-one.js"
import { withRetry } from "./retry.js"
const app = express()
app.use(express.json())
app.post("/api/clean-photo", async (req, res) => {
const { imageUrl, background } = req.body
if (!imageUrl) return res.status(400).json({ error: "imageUrl is required" })
try {
const outputUrl = await withRetry(() => processVehiclePhoto(imageUrl, background))
res.json({ outputUrl })
} catch (err) {
res.status(502).json({ error: "Background removal failed", detail: String(err) })
}
})
app.listen(3000, () => console.log("Listening on :3000"))That is a complete, production-shaped Node.js integration of the car background removal API: authenticated requests, async polling, concurrency-controlled bulk processing, retries, and a safe backend endpoint. When you are ready to go live, grab an API key and review current per-image rates and rate limits on the API pricing & docs page. Prefer Python? See the companion Python car photo API tutorial.