API

Remove Image Backgrounds in Python with an API (requests, 20 Lines)

September 6, 20266 min readBy BG Clear Editorial

You can remove backgrounds in Python with rembg on your own machine, but you will spend the afternoon on model downloads, CPU time and edge cases. If you would rather ship, an API call is 20 lines with nothing but the requests library. This tutorial uses the bgclear API because its request format is the remove.bg one, so the code also documents the migration if you are coming from there.

In this guide

Setup: one key, one library

Create a key on the API dashboard (the first key includes 10 free full-resolution credits; preview-size results are always free), export it, and install requests.

export BGCLEAR_API_KEY=bgc_live_...
pip install requests

Single image: file in, transparent PNG out

The endpoint returns the image bytes directly, so saving the result is one line.

import os, requests

API = "https://www.bgclear.ai/api/v1/remove"
HEADERS = {"Authorization": f"Bearer {os.environ['BGCLEAR_API_KEY']}"}

def remove_background(path: str, out: str, size: str = "full") -> None:
    with open(path, "rb") as f:
        r = requests.post(API, headers=HEADERS,
                          files={"image_file": f},
                          data={"size": size, "format": "png"},
                          timeout=60)
    if r.status_code != 200:
        raise RuntimeError(r.json()["error"]["message"])
    with open(out, "wb") as f:
        f.write(r.content)
    print(f"{out}: charged {r.headers['X-Credits-Charged']}, "
          f"remaining {r.headers['X-Credits-Remaining']}")

remove_background("photo.jpg", "photo-no-bg.png")

size="preview" (up to 800 px) is free and is the right setting while you test edge quality; full is native resolution and costs one credit; auto picks full for images up to 4 MP. Add "bg_color": "ffffff" to get a white background instead of transparency, or "crop": "true" to trim to the subject's bounding box.

URL input and JSON responses

If the image already lives at a URL (a product feed, S3, a CMS), skip the download and let the API fetch it. Ask for JSON with the Accept header and you get metadata plus a hosted result URL that stays valid for 24 hours — useful when the result goes straight into a database or another service.

r = requests.post(API,
    headers={**HEADERS, "Accept": "application/json"},
    json={"image_url": "https://example.com/shoe.jpg", "size": "auto",
          "format": "webp", "bg_color": "ffffff"},
    timeout=60)
data = r.json()
# {'id': '…', 'url': 'https://www.bgclear.ai/api/v1/results/…', 'width': 1600,
#  'height': 1067, 'credits_charged': 1, 'credits_remaining': 9, 'processing_ms': 1840}

A folder script with safe retries

Two details turn a loop into something you can run unattended. An Idempotency-Key header makes a retried request return the cached result instead of charging again (for 24 hours), and checking the balance up front avoids a half-processed folder.

import hashlib, pathlib, time, requests

def key_for(path: pathlib.Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()

def process_folder(src="in", dst="out"):
    pathlib.Path(dst).mkdir(exist_ok=True)
    for path in sorted(pathlib.Path(src).glob("*.jp*g")):
        out = pathlib.Path(dst) / (path.stem + ".png")
        if out.exists():
            continue
        for attempt in range(3):
            with path.open("rb") as f:
                r = requests.post(API,
                    headers={**HEADERS, "Idempotency-Key": key_for(path)},
                    files={"image_file": f}, data={"size": "full"}, timeout=90)
            if r.status_code == 200:
                out.write_bytes(r.content); break
            if r.status_code == 429:
                time.sleep(int(r.headers.get("X-RateLimit-Reset", "5"))); continue
            if r.status_code == 402:
                raise SystemExit("out of credits: https://www.bgclear.ai/api-pricing/")
            print(path.name, r.status_code, r.json()["error"]["message"]); break

process_folder()

The rate limit is 60 requests a minute per key; the loop above sleeps until the window resets on a 429 rather than hammering.

Images over 4 MP: async jobs

Synchronous requests at full size are capped at 4 megapixels so they finish within 30 seconds. Larger images (up to 50 MP) go through jobs: same inputs, immediate 202, then poll or receive a callback.

JOBS = "https://www.bgclear.ai/api/v1/jobs"

with open("huge-photo.jpg", "rb") as f:
    job = requests.post(JOBS, headers=HEADERS, files={"image_file": f},
                        data={"size": "full"}, timeout=60).json()

while True:
    status = requests.get(f"{JOBS}/{job['job_id']}", headers=HEADERS).json()
    if status["status"] in ("done", "failed"):
        break
    time.sleep(2)

if status["status"] == "done":
    png = requests.get(status["url"]).content   # result URLs need no auth, valid 24 h
    open("huge-no-bg.png", "wb").write(png)
else:
    print("failed:", status["error"])            # failed jobs are not charged

For hundreds of images, POST /api/v1/jobs/batch takes up to 50 image_urls per call, and an X-Callback-Url header replaces polling — see the bulk guide.

Errors you will actually see

Every error is JSON with a stable code: invalid_request (400 — wrong or missing parameter, or the URL could not be fetched), unsupported_format (400), image_too_large (400 — over 25 MB or 50 MP), insufficient_credits (402), rate_limited (429), processing_failed (500/504) and gpu_unavailable (503 with Retry-After). Log r.json()["error"]["message"] and the X-Job-Id header; both are what support will ask for. The full list is in the docs.

Frequently asked questions

Is there a Python SDK?

Not needed: the API is plain multipart or JSON over HTTPS, and the requests snippets above are the whole integration. They also work unchanged with httpx.

How is this different from rembg?

rembg runs a model on your machine — free per image, but you manage model downloads, CPU or GPU time and quality tuning. The API returns a result in a few seconds with no ML dependencies, and preview-size results are free for testing.

Can I get a white background instead of transparent?

Yes — pass bg_color=ffffff (any hex works). Combine with format=jpg for the smallest marketplace-ready file.

What does a full-resolution image cost?

One credit. Packs are $9 for 100, $39 for 500 and $129 for 2,000; credits never expire and previews are free.

Ship it with the bgclear API

remove.bg-compatible endpoints, credits from $9 for 100 images, no subscription. Pay, get a key, make your first call in under two minutes.

Get API credits →

Tools for this guide

Background Removal API Free

background removal api free

Background Remover Python Library

background remover python library

Canva Background Remover Alternative

canva background remover alternative

Keep reading

API

Remove Image Backgrounds in Node.js with fetch and FormData (No SDK)

Node 18+ built-in fetch, a file upload, a URL input, an Express proxy endpoint so your browser never sees the key, and retries that cannot double-charge.

API

Bulk Background Removal via API: Async Jobs, Batches of 50 and Webhooks

How to process a catalogue of thousands of images without babysitting a script: batch submission, callbacks instead of polling, credit accounting, and what to do when the queue is full.

API

remove.bg Is Shutting Down on 1 December 2026: Migrate Your API Integration in 10 Minutes

remove.bg's standalone site and API close on 1 Dec 2026 (9:00 CET) as it folds into Canva's Leonardo.Ai, and unused credits expire the same day. A field-by-field migration to a drop-in compatible API, with code.

API

Background Removal API Pricing Guide (2026)

Practical 2026 guide to background removal api pricing for tech buyers working on building a budget. Free tool, HD output, no signup.