Remove background from images in Python with the LassoCut API
With requests, removing a background is one requests.post call that returns the image bytes. This guide starts with that call, then processes a whole folder with a ThreadPoolExecutor of three workers that respects Retry-After, and shows how to keep using the community removebg package.
The official package
The quickest start is the official lassocut package: Python 3.10 or later, no dependencies, and it retries on temporary errors. The rest of this guide uses requests directly, for full control.
pip install lassocut
from lassocut import LassoCut
client = LassoCut() # reads LASSOCUT_API_KEY
result = client.remove_background("photo.jpg", size="preview")
result.save("no-bg.png")
print("credits charged:", result.credits_charged)
Every API option (marketplace presets, cast shadow, background colour, crop) is a keyword argument. Source and reference: GitHub.
Quickstart
Every request needs your key in the X-Api-Key header and exactly one image source. This example uses size=preview, which is covered by your account's 50 free previews a month (up to 10 a day). requests is the only dependency.
import os, requests
r = requests.post(
"https://api.lassocut.com/v1.0/removebg",
headers={"X-Api-Key": os.environ["LASSOCUT_API_KEY"]},
files={"image_file": open("photo.jpg", "rb")},
data={"size": "preview"},
)
r.raise_for_status()
open("no-bg.png", "wb").write(r.content)
print("credits charged:", r.headers["X-Credits-Charged"])
Tested against the production API on 27 September 2026 with this exact request; it returned a valid PNG.
Process a folder in parallel with a thread pool
Background removal is network-bound, so threads are enough: three workers keep requests flowing without tripping the rate limit for typical photo sizes. The script skips images whose result already exists, so a second run only sends what is missing.
import os, time, pathlib, requests
from concurrent.futures import ThreadPoolExecutor
API = "https://api.lassocut.com/v1.0/removebg"
KEY = os.environ["LASSOCUT_API_KEY"]
SRC, OUT = pathlib.Path("photos"), pathlib.Path("out")
OUT.mkdir(exist_ok=True)
def wait_time(r, attempt):
try:
return float(r.headers["Retry-After"])
except (KeyError, ValueError):
return 2 ** attempt # 2, 4, 8, 16 s
def cut(src):
dest = OUT / (src.stem + ".png")
if dest.exists():
return f"skip {src.name}"
for attempt in range(1, 6):
try:
with src.open("rb") as f:
r = requests.post(API, headers={"X-Api-Key": KEY},
files={"image_file": (src.name, f)},
data={"size": "full", "format": "png"},
timeout=120)
except requests.RequestException as e:
return f"failed {src.name}: {e}"
if r.status_code in (429, 503) and attempt < 5:
time.sleep(wait_time(r, attempt))
continue
if not r.ok:
return f"failed {src.name}: {r.status_code} {r.text}"
dest.write_bytes(r.content)
return f"ok {src.name} ({r.headers['X-Credits-Charged']} credit)"
photos = sorted(p for p in SRC.iterdir()
if p.suffix.lower() in {".jpg", ".jpeg", ".png", ".webp"})
with ThreadPoolExecutor(max_workers=3) as pool:
for line in pool.map(cut, photos):
print(line)
- Retries:
429 Rate limit exceededand503(a temporary processing failure that is safe to retry) are retried up to four times, waiting for theRetry-Afterheader when the API sends it, and 2, 4, 8 then 16 seconds otherwise. Nothing is charged for a failed attempt. - Rate limit: 500 megapixel-images per minute per account; an image counts as its size in megapixels, rounded up, with a minimum of 1. The
X-RateLimit-Remainingheader shows what is left in the current window. - Cost:
X-Credits-Chargedis 1 per full-size image and 0.25 per preview. A402 Insufficient creditsis reported as a failure for each remaining image: top up and run the script again, finished images are skipped. - Files: each image is opened in a
withblock, so handles are closed even on a retry. Uploads over 22 MB are refused withfile_too_large.
The script was run against a local test server that answers 429 with Retry-After before succeeding, to check the retry, skip and parallel behaviour. It needs Python 3.8 or later and pip install requests.
Point an existing Python client at LassoCut
Already using the removebg package (PyPI) to call remove.bg? Its request URL is a module-level constant you can override before creating the client:
import os
import removebg.removebg
removebg.removebg.API_ENDPOINT = "https://api.lassocut.com/v1.0/removebg"
from removebg import RemoveBg
RemoveBg(os.environ["LASSOCUT_API_KEY"], "errors.log").remove_background_from_img_file("photo.jpg")
Verified from the package's source on GitHub (brilam/remove-bg), read on 27 September 2026. It is a third-party, community-maintained package: not produced by LassoCut and not affiliated with remove.bg. For any other HTTP client, set its base URL to https://api.lassocut.com/v1.0 and keep the same X-Api-Key header.
Useful options
| Field | Example | Description |
|---|---|---|
size | preview, full, auto | Preview costs 0.25 credit; full and 50MP cost 1 credit; auto picks the largest size your balance allows. |
format | png, jpg, webp | Auto (default) returns PNG when the result has transparency, JPG otherwise. |
type | person, product, car | Selects the model. Auto (default) detects the subject. |
crop, crop_margin | True, "30px" | Crops the result to the subject, with an optional margin. |
bg_color | "81d4fa" | Fills the background with a hex colour, a colour name, or hex with alpha. |
Full list, including framing, shadows and background images: API reference.
Common errors
Errors return JSON: {"errors": [{"code": "…", "title": "…"}]}. raise_for_status() turns them into an HTTPError; the JSON body is in r.json() before that, or e.response.json() after. Nothing is charged on an error.
| Status | When | code |
|---|---|---|
| 400 | No image, or two sources given | missing_source, multiple_sources |
| 402 | Not enough credits for this size | title Insufficient credits |
| 403 | Missing or wrong X-Api-Key | titles Missing API Key, API Key invalid |
| 429 | Rate limit reached | title Rate limit exceeded, with Retry-After |
Full list: API reference.
Next steps
Read the full API reference for every parameter and header, or the migration guide if you're moving code that already calls remove.bg. Weighing a self-hosted library instead? See rembg or a hosted background removal API. No key yet? Create a free account, or try LassoCut on your image first, no key required.