API tutorial
Background Removal API: Upload, Poll and Download
A background removal API integration needs to handle more than the upload. With RemoveBGKit, you submit an image, receive a task ID, poll until processing finishes, and download the result with your API key. This guide implements that flow and explains what to do when a request times out.
- Use generic mode for individual photos; iconSheet is for separate icons on a green background.
- Persist one request ID per image before uploading so retries refer to the same task.
- Download the returned PNG or ZIP with authentication before its 24-hour expiry.

Choose the response contract before writing the caller
A synchronous API returns the processed image in the upload response. An asynchronous API returns a reference to work that continues on the server. RemoveBGKit uses the asynchronous pattern: POST /api/v1/process normally returns HTTP 202 and JSON. Saving that first response as output.png would save task metadata, not a transparent image.
Model the job in your application with an input reference, a stable request ID, the provider task ID, a status and a saved output location. That makes an interrupted worker recoverable. Once the image has been submitted, poll the existing task rather than repeatedly creating new ones.
This tutorial is for a backend integration. Your browser may send an image to your own application, but your application should hold the RemoveBGKit key. A private key embedded in a public page would let other people consume the same account credits.
Prepare the image and account
Create a key in the RemoveBGKit account panel, then check GET /api/v1/account. The available credit amount subtracts reservations for in-flight tasks. A balance of 10 with 10 reserved cannot start another five-credit job even though the account has not finished spending those credits.
Start with a representative source image within the limits: up to 18 MiB for the image, 24 million pixels and 8,000 pixels along either dimension. The full multipart request has a separate 20 MiB ceiling. Avoid treating an oversized-image response as a temporary network problem; retries cannot make the same bytes smaller.
For a product photo or logo, explicitly set mode=generic. Use portrait quality for a person when testing that model is appropriate. Compare the model options on your own edges, shadows and transparent materials before choosing a default. No universal quality or speed advantage is assumed here.
Upload with a stable Idempotency-Key
Generate the request ID once, before the first upload. Store it next to your input or application job record. The following cURL command sends the image as multipart data and asks for a general photo cutout. The API detects the file contents; the filename is not the processing format.
export RMBG_API_KEY='YOUR_PRIVATE_KEY'
# Generate once for this image. Keep this value for retries.
export RMBG_REQUEST_ID="$(uuidgen)"
curl --fail-with-body -i https://removebgkit.com/api/v1/process \
-H "X-API-Key: $RMBG_API_KEY" \
-H "Idempotency-Key: $RMBG_REQUEST_ID" \
-F 'image=@./product.png' \
-F 'mode=generic' \
-F 'quality=fast'Follow task status and save the correct output
Keep the returned taskId and statusUrl. Poll statusUrl with your key while the state is pending or running. Both active states use HTTP 202; completed uses 200. A failed task returns 400 with a code and message. A non-200 response therefore needs interpretation rather than an unconditional resubmit.
The returned status and result URLs start at the website root, for example /api/v1/tasks/task_.... Resolve them against https://removebgkit.com. Appending that entire path to a base that already ends in /api/v1 creates an invalid doubled path.
When the task completes, use icons[].url for individual transparent PNG files, zipUrl for the archive and mattePreviewUrl for the processed preview. Every file download requires the owning account key. Save files into your own storage before expiresAt. The expiry is 24 hours after submission, so slow processing uses part of that window.
# Replace TASK_ID with the taskId returned by the upload.
curl --fail-with-body https://removebgkit.com/api/v1/tasks/TASK_ID \
-H "X-API-Key: $RMBG_API_KEY"
# After status=completed, use the returned zipUrl or icons[].url.
# RESULT_PATH is an origin-relative path beginning /api/v1/results/.
curl --fail-with-body "https://removebgkit.com$RESULT_PATH" \
-H "X-API-Key: $RMBG_API_KEY" \
-o result.zipRun the complete TypeScript workflow
The downloadable example combines those steps with bounded retries and a total deadline. It uses Node.js built-in fetch, FormData and file APIs, so there is no third-party SDK to install. Node.js 22.18 or newer can run the TypeScript file directly.
Set the two environment variables in your server environment, run the command, then open the ZIP. The same function can be imported into an application worker. Pass an idempotencyKey from your persistent job record instead of generating one on every function invocation.
curl --fail-with-body \
https://removebgkit.com/static/examples/remove-background.mts \
-o remove-background.mts
# Node.js 22.18+; no npm packages required.
export RMBG_API_KEY='YOUR_PRIVATE_KEY'
export RMBG_REQUEST_ID="$(uuidgen)"
node remove-background.mts ./product.png ./result.zipTreat an upload timeout as an unknown outcome
A disconnected client does not prove that the server rejected an image. The server may already have reserved credits and queued the task. Retrying with the same Idempotency-Key, exact image bytes and normalized settings retrieves that job instead of charging for a second submission. Concurrent matching requests also resolve to one task.
Changed settings or image bytes with the same key produce 409. That protects against silently returning the wrong result. Use a new key when you intentionally want a different image or model. If a task has failed, replay returns that failure and does not run it again; correct the cause before creating a new job.
For 429, wait the Retry-After duration. For a transient 5xx or network error, retry with backoff and the same ID. Do not automatically retry 401, 402, 413 or 415: fix the key, credit availability, size or format first. Request IDs are retained with the task and are not a permanent deduplication ledger. Keep your own completion record for jobs that may be retried days later.
Check billing, output quality and workload size
The API reserves five credits per input image before queuing. Successful completion consumes the reservation once; terminal processing failure releases it. Upload retries with the same ID do not create another charge. GET /account exposes the live available balance, which is more useful for admission control than a locally cached total.
For a folder of photos, create one application job and one unique request ID per image. There is no multi-image upload endpoint or callback webhook in this version. The current upload limit is 20 requests per 60 seconds per IP, including retries; use a queue rather than a burst of concurrent uploads. This rate limit is not a processing-throughput guarantee.
Finally, inspect sample PNGs on light and dark backgrounds before publishing them. Automated background removal can leave edge artifacts. Transparent products, fine hair and soft shadows deserve a separate review set. Keep the source image alongside your saved result so an editor can correct the exceptional cases.