Need to remove image backgrounds programmatically? Whether you're building an e-commerce product catalog, a photo editing app, or automating image processing at scale, you need a background removal API that's fast, accurate, and won't break the bank.

This tutorial walks you through the entire process: from getting an API key to making your first background removal call, handling the response, and integrating it into your application. We'll cover cURL, Node.js, and Python with copy-paste code you can use immediately.

What You'll Need

No account setup required. Enter your email, get a key instantly, start making API calls. The entire process takes under 60 seconds.

Step 1: Get Your Free API Key

1

Sign up at ClearCut

Head to clearcut-2834.polsia.app and enter your email address. Your API key is generated instantly — no email verification, no credit card, no waiting.

Your key looks like this: cc_a1b2c3d4e5f6

The free tier gives you 50 background removals per month at full API resolution. That's enough to build, test, and ship a prototype before you spend a cent.

Step 2: Remove Your First Background

The ClearCut API has a single endpoint: POST /v1/remove. Send an image, get back a transparent PNG. That's the entire API.

Request Format

Working Code Examples

# Remove background from a local image
curl -X POST https://clearcut-2834.polsia.app/v1/remove \
  -H "Authorization: Bearer cc_YOUR_API_KEY" \
  -F "image=@photo.jpg" \
  --output result.png

# The output is a transparent PNG
# Check the processing time from response headers:
curl -X POST https://clearcut-2834.polsia.app/v1/remove \
  -H "Authorization: Bearer cc_YOUR_API_KEY" \
  -F "image=@photo.jpg" \
  -D - --output result.png 2>/dev/null | grep X-Processing-Time
import { readFileSync, writeFileSync } from 'fs';

const API_KEY = 'cc_YOUR_API_KEY';
const API_URL = 'https://clearcut-2834.polsia.app/v1/remove';

async function removeBackground(imagePath) {
  const formData = new FormData();
  const imageBuffer = readFileSync(imagePath);
  const blob = new Blob([imageBuffer], { type: 'image/jpeg' });
  formData.append('image', blob, 'photo.jpg');

  const response = await fetch(API_URL, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}` },
    body: formData,
  });

  if (!response.ok) {
    const err = await response.json();
    throw new Error(err.error?.message || 'API request failed');
  }

  // Response is the PNG image directly
  const buffer = Buffer.from(await response.arrayBuffer());
  const processingTime = response.headers.get('X-Processing-Time');
  console.log(`Done in ${processingTime}`);

  return buffer;
}

// Usage
const result = await removeBackground('./photo.jpg');
writeFileSync('./result.png', result);
console.log('Saved result.png');
import requests

API_KEY = "cc_YOUR_API_KEY"
API_URL = "https://clearcut-2834.polsia.app/v1/remove"

def remove_background(image_path: str, output_path: str):
    """Remove background from an image file."""
    with open(image_path, "rb") as f:
        response = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"image": ("photo.jpg", f, "image/jpeg")},
        )

    if response.status_code != 200:
        error = response.json()
        raise Exception(error.get("error", {}).get("message", "Failed"))

    # Response body is the transparent PNG
    with open(output_path, "wb") as out:
        out.write(response.content)

    processing_time = response.headers.get("X-Processing-Time", "N/A")
    print(f"Saved to {output_path} (processed in {processing_time})")

# Usage
remove_background("photo.jpg", "result.png")

All three examples do the same thing: send photo.jpg to the API and save the transparent PNG as result.png. Processing typically takes 1–2 seconds per image.

Step 3: Handle the Response

3

Understanding the API Response

Success (200): The response body is the PNG image with a transparent background. Key response headers:

Error (4xx/5xx): Returns JSON with an error object:

// 400 — No image or invalid format
{
  "error": {
    "code": "NO_IMAGE",
    "message": "No image provided. Send a file with field name \"image\"."
  }
}

// 503 — Service temporarily unavailable
{
  "error": {
    "code": "SERVICE_UNAVAILABLE",
    "message": "Background removal service is temporarily limited."
  }
}

Processing Images in Batch

Need to process hundreds of images? Here's how to batch them efficiently with concurrency control, so you don't overwhelm the API or your own machine.

import { readFileSync, writeFileSync, readdirSync } from 'fs';
import { join, basename } from 'path';

const API_KEY = 'cc_YOUR_API_KEY';
const API_URL = 'https://clearcut-2834.polsia.app/v1/remove';
const CONCURRENCY = 3; // Process 3 images at a time

async function processOne(inputPath, outputDir) {
  const formData = new FormData();
  const blob = new Blob([readFileSync(inputPath)]);
  formData.append('image', blob, basename(inputPath));

  const res = await fetch(API_URL, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}` },
    body: formData,
  });

  if (!res.ok) throw new Error(`Failed: ${res.status}`);
  const outPath = join(outputDir, basename(inputPath, '.jpg') + '.png');
  writeFileSync(outPath, Buffer.from(await res.arrayBuffer()));
  return outPath;
}

// Process a folder of images with concurrency limit
const files = readdirSync('./input').filter(f => /\.(jpg|png|webp)$/i.test(f));
for (let i = 0; i < files.length; i += CONCURRENCY) {
  const batch = files.slice(i, i + CONCURRENCY);
  const results = await Promise.all(
    batch.map(f => processOne(join('./input', f), './output'))
  );
  console.log(`Batch ${Math.floor(i / CONCURRENCY) + 1}: ${results.length} done`);
}
import os
import requests
from concurrent.futures import ThreadPoolExecutor

API_KEY = "cc_YOUR_API_KEY"
API_URL = "https://clearcut-2834.polsia.app/v1/remove"

def process_one(input_path, output_dir):
    with open(input_path, "rb") as f:
        resp = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"image": f},
        )
    resp.raise_for_status()
    name = os.path.splitext(os.path.basename(input_path))[0]
    out_path = os.path.join(output_dir, f"{name}.png")
    with open(out_path, "wb") as out:
        out.write(resp.content)
    return out_path

# Process all images in ./input with 3 threads
input_dir = "./input"
output_dir = "./output"
os.makedirs(output_dir, exist_ok=True)
images = [f for f in os.listdir(input_dir) if f.endswith((".jpg", ".png", ".webp"))]

with ThreadPoolExecutor(max_workers=3) as pool:
    paths = [os.path.join(input_dir, img) for img in images]
    results = list(pool.map(lambda p: process_one(p, output_dir), paths))

print(f"Processed {len(results)} images")

Pricing: ClearCut vs. Other APIs

Background removal APIs vary wildly in pricing. Here's how ClearCut compares to the popular alternatives for developers who care about cost:

ClearCut Typical Alternative
Per-image cost $0.02 $0.20 – $1.00
Free tier 50 images/month 1 image/month or watermarked only
Credit card required? No Usually yes
Credit packs / expiry None — pay as you go Packs of 25+, expire after 1–2 years
1,000 images $20 $200 – $1,000
10,000 images $200 $2,000 – $10,000
Output format Transparent PNG (RGBA) Transparent PNG
Max file size 25 MB 10–25 MB

At scale, the difference is dramatic. Processing 10,000 product photos costs $200 with ClearCut vs. $2,000+ with most alternatives. Same transparent PNGs. Same quality. 10x less money.

API Reference Quick Card

Endpoint POST /v1/remove
Auth Authorization: Bearer cc_xxx
Input multipart/form-data, field: image
Formats JPG, PNG, WebP (up to 25 MB)
Response Transparent PNG (binary)
Speed ~1–2 seconds per image
Rate limit Free: 50/month • Paid: unlimited

For the full API reference, error codes, and language-specific SDKs, check the ClearCut API documentation.

Common Use Cases

See more developer integration patterns in the developer use cases guide.

Tips for Best Results

  1. Use high-resolution input. The AI works best with clear, well-lit images. Low-resolution or blurry photos may produce rough edges.
  2. JPG is fine. You don't need to convert to PNG before sending. JPG, PNG, and WebP all work. The output is always a transparent PNG.
  3. Check the X-Processing-Time header. First request after a cold start may take 10–12 seconds. Subsequent requests are 1–2 seconds.
  4. Retry on 503. If the service is temporarily limited, wait 5 seconds and retry. The model scales automatically.
  5. Batch with concurrency 3–5. The API handles concurrent requests well. Going above 5 won't speed things up much.

Start removing backgrounds for free

50 images/month. No credit card. API key in 10 seconds.

Get Your Free API Key →