Skip to main content

Background Removal API: Deliver Transparent Product PNGs

Cut out product photos to transparent PNGs with one API call, then verify the alpha channel and edges before you deliver.

Author
Lydia
Published
Read
17 min read
Updated
A woman in a cobalt jumpsuit beside an acrylic panel with a checkerboard portrait silhouette

You have a few hundred product photos on grey tables and window sills, and the shop, the marketplace or the designer wants each one as a transparent PNG. SpicyAPI Background Remover does that in one call: you send a photo URL and get back the main subject on a transparent PNG at the original width and height. The work that remains is yours: confirm the file really has alpha, check the edges on the backgrounds it will sit on, and export the flat copies each destination asks for.

Try it in the Playground first

Open the background-remover-v1 Playground. Drop a product photo into Input image, check the price and press Run model. Inspect the transparent result against light and dark backgrounds before using the same photo in code.

What the endpoint takes and returns

Background Remover (spicyapi/background-remover-v1/edit)
InputOne field, image_url: a JPEG, PNG or WebP photo. No prompt, mask or subject selector
Subject choiceAutomatic. Crop first if the frame holds several candidates; the tool may keep more than you want
OutputOne PNG with an alpha channel, same width and height as the input
Price$0.0048 per output image; the size of the photo you send does not change it
Time limitA task that has not finished within 1,800 seconds expires and is not charged
Result linkA pre-signed URL on output.assets[0].url, valid about 20 minutes (query the task again for a fresh one); the file itself is kept at most about 14 days

The output keeps the source canvas dimensions, so you can position the cutout over a replacement background without rescaling. Use the returned alpha channel for the cutout boundary; keeping the same canvas does not guarantee that every foreground edge or colour is unchanged. Details are on the Background Remover model page.

See a real result first

The model page's own example is a frosted dropper bottle on a grey studio backdrop, 1024 × 1536 pixels. These are the before and after files from that page; the "after" is shown here over the page background.

Source photo of a frosted glass dropper bottle with a blank label on a grey studio background, 1024 by 1536 pixels
Background Remover input: a frosted dropper bottle on a grey backdrop
The same dropper bottle cut out with a transparent background, same 1024 by 1536 size
Background Remover output: the bottle on a transparent background

Running the check script from the next sections on this pair gives the numbers a good result looks like: the output has an alpha channel, the size matches the source, about 78% of pixels are fully clear, about 22% are solid, and only about 0.35% are semi-transparent edge pixels. The subject box is 335 × 1,234 pixels. Composited on a dark navy background, the dropper tip, the brushed collar and the frosted glass shoulders have no light fringe.

Make the call

Install spicyapi and pillow with python -m pip install spicyapi pillow. Set SPICY_API_KEY and IMAGE_URL to your direct source-image URL, then run this example. It asks you to confirm the price, creates the task, waits for it, saves the cutout and writes light and dark previews.

python
import os
import urllib.request
import uuid
from io import BytesIO
from pathlib import Path

from PIL import Image
from spicyapi import SpicyClient, output_assets

client = SpicyClient()
model = "spicyapi/background-remover-v1/edit"
inputs = {"image_url": os.environ.get("IMAGE_URL", "https://cdn.spicyapi.ai/models/examples/inputs/e82b71db9e3d0e5f.png")}

quote = client.quote_task(model=model, input_data=inputs)
if input(f"Maximum ${quote['maxCharge']}. Create? [y/N] ") != "y":
    raise SystemExit("Stopped without creating a task.")

task = client.create_task(model=model, input_data=inputs, idempotency_key=str(uuid.uuid4()),
                          quote_id=quote["quoteId"], expected_cost=quote["estimatedCost"])
print("Task:", task["taskId"])  # keep this ID: a timeout does not cancel the task
task = client.wait_for_terminal(task["taskId"])
if task["state"] != "succeeded":
    raise RuntimeError(str(task.get("errorMessage", task["state"])))

asset = output_assets(task)[0]
request = urllib.request.Request(asset["url"], headers={"User-Agent": "SpicyAPI-Blog-Example/1.0"})
with urllib.request.urlopen(request, timeout=120) as response:
    data = response.read()
Path("cutout.png").write_bytes(data)

with Image.open(BytesIO(data)) as image:
    if image.format != "PNG":
        raise RuntimeError("Expected a PNG cutout.")
    rgba = image.convert("RGBA")
alpha = rgba.getchannel("A")
values = list(alpha.getdata())
print({"size": rgba.size, "alpha_min_max": alpha.getextrema(),
       "clear_fraction": sum(v <= 8 for v in values) / len(values),
       "solid_fraction": sum(v >= 247 for v in values) / len(values),
       "soft_fraction": sum(8 < v < 247 for v in values) / len(values),
       "subject_box": alpha.getbbox()})
for name, colour in [("light", "#f5f2e8"), ("dark", "#162235")]:
    Image.alpha_composite(Image.new("RGBA", rgba.size, colour), rgba).convert("RGB").save(name + ".jpg")

To retry the same request after a lost response, reuse its idempotency key rather than creating a new one (idempotency reference). For local-file uploads, see the Python SDK and media documentation.

Verify the transparency by decoding the file

A white preview proves nothing. It might be a genuine cutout on a white page, an opaque image with a white background, or a checkerboard painted into the pixels. Decode the file and read its alpha channel. The PNG specification defines how alpha is stored; in practice you need to know whether some pixels can be transparent after decoding, not what the filename says.

The example reports how alpha is distributed and writes cream and dark navy composites for review using Pillow. Compare its reported dimensions with your source.

Note the thresholds. Counting only alpha 255 as opaque is misleading: on the dropper-bottle output, about 14% of pixels sit at alpha 1 to 254, but nearly all of those are 254, which is visually solid. Treating alpha up to 8 as clear and from 247 as solid leaves the soft fraction for what you actually care about: antialiased edges, hair, and genuinely translucent material.

How to read the report:

  • A missing alpha channel, or alpha_min_max of (255, 255), means no transparency: investigate the pipeline before reviewing edges.
  • clear_fraction near 0 on a photo that had a background, or solid_fraction near 0, means the subject was lost or the result is a haze.
  • A size mismatch usually means an EXIF-rotated source or a resize in your own code, since the endpoint preserves dimensions.
  • A large soft_fraction is normal for glass, fabric and hair and a warning sign for a matte mug. Set thresholds per product category after looking at a pilot set, not one global number.
  • A subject box that touches the canvas edge on a photo you cropped loosely suggests a second object was kept.
Diagram: alpha 0 is transparent, 128 is partial coverage, 255 is opaque; the same blue disc looks different over a light and a dark background
Alpha controls how an edge blends: inspect real edges over both a light and a dark background.

Prepare the photo without changing the product

Decide what counts as the product before you shoot or crop: a ribbon, the packaging and a contact shadow are either in or out, and the tool cannot guess a brief that was never written. Do not repaint a chipped rim or invent a missing logo; a defect the listing must show stays in the photo.

  • Crop to remove competing objects but leave margin around every extremity, so a handle or strap is not clipped before the API sees it.
  • Overlapping objects cannot be fixed by cropping, because the hidden boundary has to be guessed. Reshoot, and route overlaps, transparent display stands and cropped subjects to an exception lane so they do not clog the normal batch.
  • Submit the cleanest file. Repeated JPEG re-exports leave block artifacts exactly where the edge needs detail; keep a lossless working copy. Convert colour profiles deliberately, because a careless conversion changes the product colour before anyone reviews the cutout.

Review the edge where the image will be used

Put the cutout over the real destination background, not just the page you review it on. A cutout that looks clean on cream can show a pale rim on dark navy; the rim is source-background colour left in partly transparent pixels. Check at the delivery size, to see whether a defect matters, and at 100%, to see its shape. The script's two composites use cream and dark navy; swap in your brand colours.

Look at the regions where this kind of product is recognised, not every pixel equally: the inside of a mug handle, the rim and foot, laces and soles, bristles, the dropper tip. Compare source, alpha and composite at the same scale and crop. When you reject a file, name the lost feature and the destination ("handle opening filled on dark composite"), so the next person knows whether to crop, retouch or reshoot.

Four product shots with yellow outlines: a mug, a glass decanter, a potted plant and a black scarf with fringe, showing silhouettes, openings and fine edges that need review
Silhouettes, openings and fine edges to review: mug handle, glass, leaves and fringe (editorial illustration, not API output).

Three situations need a decision rather than a retry:

  • Holes inside the silhouette. A handle opening or the gap between chair rails belongs to the background. An outline-only check can look right while the hole is filled. Check it on the dark composite.
  • Shadows. A contact shadow grounds a product; a long cast shadow drags background texture into the cutout. Decide whether the master keeps one, and whether the layout will draw its own. If you add your own, soften or remove the shadow already in the source so two do not conflict.
  • Glass and translucent material. A bottle's colour includes transmitted background light, so no cutout can give a physically right bottle on every new backdrop; a pale studio reflection that looks natural on white can look wrong on dark. Keep partial alpha for translucent plastic and fabric rather than thresholding it to 0 or 255, and do not erode the whole mask to remove a halo: you thin the product and lose fine features. Retouch locally on a copy.
Three close-ups: a speckled mug handle opening, an oil vial with a long cast shadow on stone, and a glass rim in front of foliage, showing handles, shadows and glass that need different decisions
A handle opening should clear, a shadow follows the brief, and glass keeps background-dependent colour (editorial illustration, not API output).

Fix the failure at the stage that caused it

Classify before you re-run. A repeated call costs money and, for most of these, changes nothing.

What you seeCauseFix
Task fails with invalid_request or a fetch errorThe URL is not a direct image fileFix the URL or upload the file; do not retry the same input
File will not decode, or no alphaTransport or your own conversionRe-download the result; check that nothing converted it to JPEG
Gift box or a second product keptSeveral subject candidatesCrop to the product and submit as a new source revision
Handle tip or strap clippedCrop was too tight before submissionRe-crop with margin around every extremity
Ragged hair, fringe or fine bristlesHard edge for any automatic cutoutReshoot on a plainer backdrop, or mask that one image by hand
Pale rim on dark backgroundsSource colour in edge pixels, or later sharpening/resizingCompare master to source to find the stage; fix the export step
Solid box around the productJPEG export filled the transparent areaFlatten on purpose (next section); keep the PNG master

There is no prompt to nudge the tool, so the levers are the input photograph and what you do after the call. If one category keeps failing, change how it is shot instead of repeating requests.

Flatten for destinations that need a solid background

Marketplaces often want a JPEG on white. JPEG has no alpha, so exporting the master to JPEG fills the transparent area with a default colour nobody approved. Flatten on a chosen colour, keep the PNG as the master, and resize uniformly (never stretch width and height independently). The light.jpg the script writes is exactly this step on cream; for white, change the colour in the loop, or export a separate flattened JPEG from your image editor. Check the flat file, not just the master: resampling, colour conversion and compression add their own defects. If a halo appears only after upload to your shop or CMS, compare the decoded pixels of the master, your export and the platform's thumbnail; the platform's resize or recompression is often the cause, not the cutout.

When a different route is the right tool

For a plain cutout, Background Remover is the lowest-priced route in this table and preserves the source canvas size. Use another route when you need something it deliberately does not offer.

NeedRoutePrice (live quote)Notes
Plain product cutout, no new contentBackground Remover$0.0048 per imageOne field; exact original size
Cutout plus a prompt-driven edit in one callGPT Image 2.5 Sunburst or Flare, edit task with background: transparent, output_format: png$0.0149 at low quality, $0.0208 at medium (1k, one input image)Generative: the product can be redrawn, so verify it and the alpha. See the Flare vs Sunburst guide
GPT Image 2 (not 2.5)Not availablebackground accepts only auto or opaque; a transparent request is rejected
A person or product lifted out of a finished design, plus text and scene layersSeedream 5.0 Flash layer decomposition$0.026 per output imageOne base plate plus up to sixteen transparent layers, billed per output; a default request quotes 17 outputs, $0.442, so it is a different job and cost from one plain cutout. See the layer-splitting guide

If a generative model returns a PNG, that does not make it transparent: PNG can carry an opaque white background. Decode every result with the same script. Where exact product pixels matter (labels, logos, packaging text), prefer the extraction route over a generative redraw.

Run a batch without drowning the reviewers

The model call is cheap and fast; reviewing is the bottleneck. Start with a pilot of about a dozen rights-cleared photos that represent the catalogue: one clean solid object, one with a handle or opening, one glossy, one with a fine edge, one with a competing object. The pilot decides which categories go through light review and which always get a human.

  • Submit with bounded concurrency and keep a separate download queue, so a slow download never triggers a repeat extraction. Retry a failed download against the existing result while its link is valid. The backpressure guide covers the queue design.
  • Store your own asset ID, source checksum, task ID, output location and review decision per source revision. A SKU alone is not enough: one product has several angles and reshoots.
  • Treat "succeeded" as "ready for inspection", never as "publish". Run the script automatically, then send only flagged and sampled files to a person. Categories that pass the pilot (solid objects on neutral backgrounds) can move to a lighter lane with periodic sampling to catch drift; reflective, transparent and ambiguous items stay on full review. Review campaign hero images before secondary angles instead of in completion order.
  • For completion notifications, see the polling vs webhook guide; either way the result feeds the same inspection step.
  • Pause when failures share a cause. Ten lost handle openings are information about the source set, not ten reasons to retry.

What it costs per accepted image

A hundred cutouts cost $0.48 and a thousand cost $4.80. The figure that matters is spend per accepted master. As a planning example, a batch of 100 first cutouts plus 10 re-cropped ones is 110 × $0.0048 = $0.528; if 95 pass review, that is about $0.0056 per accepted image.

Cost worked example: 110 cutouts at $0.0048 is $0.528; divided by 95 accepted masters is about $0.00556 each; review labour is a separate input
Worked cost example: 110 cutouts at $0.0048 is $0.528, about $0.00556 per accepted image, before review labour.

Review time usually costs more than the API. The useful levers are upstream: if most review time goes to glass bottles, a better lit setup for those saves more than any price difference. A completed cutout that you reject is still a completed, charged output; failed and expired tasks release their hold.

Keep source, master and exports apart

Keep the source photo, the transparent PNG master and each flattened delivery copy as separate files, named for what they are (for example <asset>-source, <asset>-cutout-master, <asset>-catalogue-cream), and keep retouched versions apart from the untouched API output so a later halo can be traced to the cutout or the export. Store the approved destination size with each master, so a card-size approval is not mistaken for a hero-size one.

Log each rejection under one category: wrong subject, lost feature, fringe, leftover background fragment or export defect. A count only matters when it changes something: a crop rule, a manual lane for glass, a corrected export preset. Give the photographer concrete capture rules ("keep the whole handle visible; no gift box behind the opening", "darker backdrop for pale products") rather than "make it easier for AI".

A perfume bottle shown as four print-style cards labelled Source, Master, Review copies (light and dark) and Final export, showing why the files stay separate
Source, master, light and dark review copies, and destination export stay separate (editorial illustration, not a real delivery folder).

Questions

Is there a free background removal API?

Not for this endpoint: each completed output costs $0.0048, so a 100-photo pilot costs $0.48. If free is the requirement, self-hosting an open-source remover such as rembg avoids per-image fees, but you then run and tune it yourself; the hosted route buys a stable endpoint and predictable cost.

Does saving the result as PNG make the background transparent?

No. PNG can carry alpha, but it can also contain an opaque white background. Decode the file and read the alpha channel, then review light and dark composites. Renaming a JPEG to .png adds nothing.

Can I tell it to keep the handle, the hair or the shadow?

Not on this task: its input is the image URL only. Crop the source, reshoot, or retouch locally. If you want a prompt-driven result, use an image-edit route from the table above and verify the product and the alpha afterwards.

How should I start?

Pick one representative product and one destination. Send the photo, decode the PNG, review the edges over two backgrounds, flatten the approved derivative, and have the designer open it in the real layout. Then run the harder members of your pilot set and write down which ones need a reshoot or a manual lane before scheduling the whole catalogue.

Let an Agent handle the call

Use an Agent when you want it to prepare the inputs and return the result while you approve the price and creative choices.

  • CLI: with the same input object saved as input.json, use npx @spicyapi/cli tasks create --model spicyapi/background-remover-v1/edit --input-file input.json --wait. The CLI confirms the price; keep the returned task ID for recovery.
  • MCP: ask your assistant to use spicyapi_task_create for spicyapi/background-remover-v1/edit, then spicyapi_task_wait. The MCP server requests price confirmation before creation.
  • Skill: install with npx skills add spicyapi-ai/spicy-skill, then ask $spicyapi to run the same workflow and stop for your approval. The Skill uses a configured CLI or MCP connection.

Also in 日本語 · 한국어 · Deutsch · Français · Español · Português (Brasil) · Русский · Italiano · Polski

Try it yourself

Pay only for what you run — no plan, no subscription.

Made with MiniMax H3 · ByteDance Seedance 2.0 Fast