Treat this as a small integration migration. The endpoint shape is familiar, but a host-and-key swap alone is not a complete migration.

1. Map the request you already send

remove.bg’s API uses a multipart POST to /v1.0/removebg authenticated with X-API-Key. Clearcut supports that path and header, plus file, public URL and Base64 inputs. That gives a simple integration a familiar starting point.

Create a Clearcut account, verify it and create a new key in Your account. Your remove.bg key and credits do not transfer. Store the new secret on your server. Use https://clearcut.sh as the API base URL.

Audit every parameter.

Clearcut accepts a defined subset of the remove.bg-style contract. Unknown fields return 422. Compare your actual request with the parameter reference or OpenAPI document, including options added by your SDK.

2. Make resolution and cost explicit

SettingWhat to do in Clearcut
sizeUse full for original dimensions. auto, preview and small fit within 625 × 400; they do not lower the credit cost.
qualityfast costs 1 credit; quality is the API value for Fine detail and costs 2. This is separate from output resolution.
formatSet png for a transparent cutout. JPG, WebP and color/alpha ZIP are also supported. Check the response before writing it to disk.
SourceChoose exactly one of image_file, image_url or image_file_b64. URLs must be publicly reachable and pass URL safety checks.
CreditsBuy a credit pack or subscribe before making API requests. The five-per-day browser allowance is not an API allowance.
ErrorsRead error.code and error.message. A queued 202 response includes error.job_id even though the request was accepted.

This changes preview economics. remove.bg documents quarter-credit API previews after its free allowance; Clearcut charges by Fast or Fine detail processing, including when you request a small result. Rework any budget that assumed cheap API previews.

3. Handle a queued response before saving bytes

Clearcut waits up to 55 seconds on the compatibility endpoint. If the image is still processing, it returns HTTP 202 with a job ID and a Location header. A 202 is a successful HTTP response, so checking only response.ok can accidentally save JSON as an image.

Poll GET /api/jobs/{id} with the same API key until the job is done or has an error. Download its authenticated result URL with that key. The example below deliberately requests a plain, full-size PNG, so result_url is the right finished file. If you use crop, a background or another output format, preserve those settings and use the export endpoint after completion rather than treating the raw cutout as a finished composite.

This complete Python example handles both immediate and queued PNG results. It makes one submission; on a submission/network error, inspect the task and reuse its saved idempotency key before retrying.

# Python 3.10+; install requests. Keep your API key on your server.
import os
import sys
import time
import uuid
from pathlib import Path
from urllib.parse import urljoin
import requests

base = os.environ.get("CLEARCUT_BASE_URL", "https://clearcut.sh").rstrip("/")
headers = {"X-API-Key": os.environ["CLEARCUT_API_KEY"]}
# Save this key with your task; reuse it with identical data after a network timeout.
request_key = os.environ.get("CLEARCUT_REQUEST_ID") or str(uuid.uuid4())
print("Request ID:", request_key, file=sys.stderr, flush=True)
source = Path(sys.argv[1])
output = Path(sys.argv[2] if len(sys.argv) > 2 else "cutout.png")

with source.open("rb") as image:
    response = requests.post(
        base + "/v1.0/removebg",
        headers={**headers, "Idempotency-Key": request_key},
        files={"image_file": (source.name, image)},
        data={"size": "full", "format": "png", "quality": "fast"},
        timeout=65,
    )
response.raise_for_status()

if response.status_code == 202:
    job_id = response.json()["error"]["job_id"]
    print("Queued job:", job_id, file=sys.stderr, flush=True)
    deadline = time.monotonic() + 360
    while time.monotonic() < deadline:
        time.sleep(2)
        status = requests.get(base + "/api/jobs/" + job_id,
                              headers=headers, timeout=30)
        if status.status_code == 429:
            time.sleep(float(status.headers.get("Retry-After", "2")))
            continue
        status.raise_for_status()
        job = status.json()
        if job["status"] == "error":
            raise RuntimeError(job.get("error") or "Processing failed")
        if job["status"] == "done":
            response = requests.get(urljoin(base + "/", job["result_url"]),
                                    headers=headers, timeout=60)
            response.raise_for_status()
            break
    else:
        raise TimeoutError("Keep job ID " + job_id + "; check it before resubmitting")

if not response.headers.get("Content-Type", "").lower().startswith("image/png"):
    raise RuntimeError("Expected PNG; inspect the response before saving it")
output.write_bytes(response.content)
print("Saved", output)

Download the Python example. Install requests, set CLEARCUT_API_KEY, then run python migrate-remove-bg.py photo.jpg cutout.png. A newly generated request ID is appropriate for a new image task; save it as CLEARCUT_REQUEST_ID for a retry of that same task.

4. Start small and keep retries bounded

The initial API limit is 60 submissions per minute per owner, with up to 100 paid jobs pending. That is an admission limit, not a promise to finish 60 images a minute. Worker starts and processing times vary. Begin with one or two concurrent tasks and measure your own completion times.

For long-running pipelines, POST /api/jobs returns immediately and is often easier to manage than keeping a request open. It accepts a file or URL with a quality setting; apply finishing options through a later export. On 429, respect Retry-After and add jitter. Keep the same idempotency key only when source and options are identical. A changed request with the same key returns 409.

Save results to your own storage within one hour. Failed processing returns the reserved credits; an intentional new attempt reserves credits again. Keep a small test set and your previous integration available until the new path has passed your own quality, failure and cost checks.

Start with your next image.

Create an account and verify your email to get 30 free credits every month: enough for 30 Fast images or 15 Fine images. Use them on the website or through the API.