Back to blog

remove.bg API migration: what actually changes

remove.bg moves its API to Leonardo.Ai on 1 December 2026. The field-by-field diff, three production traps, and our measured prices and latency.

Sep 21, 2026BackGone TeamBackGone Team

If you call api.remove.bg, you have a deadline: 1 December 2026. remove.bg's own API page now says it plainly — "Starting December 1, 2026, background removal moves to Leonardo." — and links to a migration guide on Leonardo's docs, tagged utm_source=RBG_website. Leonardo.Ai is part of Canva (Canva's own newsroom welcomed it in 2024), and Canva's public API does not expose background removal at all: we searched its published Connect specification — 52 paths — and found zero matches.

So the question is not whether you migrate, but where to, and what breaks when you do. Below is the field-by-field diff we assembled while doing this work ourselves, the three traps that only show up in production, and the numbers we measured on our own API rather than quoting someone else's brochure.

Where remove.bg actually sends you

The pointer is not a rumour. remove.bg's API page carries a "Leonardo API Migration" link, and its documentation link is tagged utm_source=RBG_website&utm_medium=removebg, which tells you the vendor considers this a hand-off rather than a suggestion.

Where remove.bg sends its API customers, and how the two request shapes differDiagram: remove.bg links to Leonardo.Ai, part of Canva, at $0.1047 per image, versus BackGone at $0.020 to $0.033. Following the pointer means JSON-only request and response, library storage by default and cost in the body; our API takes multipart, returns PNG bytes, stores nothing and reports cost in a header.Where remove.bg points its API customers — and what changes when you land thereremove.bg's own API page, read 2026-09-21: "Starting December 1, 2026, background removal moves to Leonardo."remove.bg APImoves on 2026-12-01Leonardo.Ai (Canva)$0.1047 per imageBackGone API$0.020–$0.033 per imageFollowing that pointer, you take on:a JSON-only body, with the image inside parameters.guidances.image_referencea JSON-only response: fetch results[0].url, or decode results[0].dataB64results kept in your library unless you remember ephemeral: truecost reported as a cost object inside the response bodyWhat our API asks for instead:multipart/form-data with a single image_file fieldthe transparent PNG is the response body — nothing to fetch or decodenothing stored: no library, no bucket, no URL that expirescost reported in x-backgone-credits-chargedCanva's own public API has no background removal: its published Connect API specification has 52 paths and zero matches (checked 2026-09-21).Sources: remove.bg/api, Leonardo's "Migrate from the remove.bg API" guide, canva.dev Connect API spec. Prices are each vendor's published per-image figure.

The interesting part is what is not on that path: Canva's public API. Canva owns the destination, but its Connect API — the one a developer can actually call — has no background-removal endpoint at all. If your integration needs an API, the only route remove.bg offers you is Leonardo's.

Field by field

Leonardo publishes its own comparison, and it is unusually honest. Here it is with the parts that matter to a migration, plus what to watch for:

POST https://api.remove.bg/v1.0/removebg

What it becomes (Leonardo)
POST https://cloud.leonardo.ai/api/rest/v2/generationssync
What to watch for
New host, new path version

X-Api-Key: <key>

What it becomes (Leonardo)
Authorization: Bearer <LEONARDO_API_KEY>
What to watch for
Different header — your secret store and your gateway rules both change

multipart/form-data or JSON

What it becomes (Leonardo)
JSON only (application/json)
What to watch for
Form uploads stop working

image_file / image_url / image_file_b64

What it becomes (Leonardo)
one image object inside parameters.guidances.image_reference
What to watch for
Your image reference moves two levels deep

Implicit model

What it becomes (Leonardo)
explicit "model": "remove-bg"
What to watch for
Cheap to get right, easy to forget

Raw image bytes by default (JSON optional)

What it becomes (Leonardo)
always JSON: results[0].url, or dataB64 when you ask for base64
What to watch for
You now need a second fetch or a decode before you have the picture

Nothing kept

What it becomes (Leonardo)
kept in your Leonardo library unless ephemeral: true
What to watch for
A storage decision your privacy policy may care about

png, jpg, webp, zip, auto

What it becomes (Leonardo)
png, jpg, webp (no zip, no auto)
What to watch for
Batch zips and format=auto need rework

X-Credits-Charged header

What it becomes (Leonardo)
cost object in the response body
What to watch for
Your cost accounting reads a different place

If you want the same comparison with a second column for us, our API reference keeps it updated — including the rows where we are worse.

The three traps

1. The response is not an image any more

The single most common bug we saw described while reading other migration write-ups: the code that used to stream a PNG now receives JSON. You either fetch the URL or decode the base64 — and each has a size limit. Leonardo's own guide notes that dataB64 only works for results under roughly 7.45 MB of pixels, and that the sync request itself can take up to about 27 seconds before it times out.

# Before: the response was the image
curl -s -X POST https://api.remove.bg/v1.0/removebg \
  -H "X-Api-Key: $REMOVE_BG_KEY" \
  -F image_file=@photo.jpg -o no-bg.png

# After: JSON in, decode on your side
curl -s -X POST https://cloud.leonardo.ai/api/rest/v2/generationssync \
  -H "authorization: Bearer $LEONARDO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"remove-bg","public":false,"ephemeral":true,
       "parameters":{"size":"auto","type":"auto","format":"png",
       "guidances":{"image_reference":[{"image":{"id":"https://example.com/photo.jpg","type":"URL"}}]}}}' \
  | jq -r '.results[0].dataB64' | base64 --decode > no-bg.png

2. Results are stored unless you say otherwise

By default Leonardo keeps the result in your account library. That is a feature if you want an asset history and a liability if you process other people's photos: "we never store your images" and "your images sit in a vendor library until you delete them" are different sentences in a privacy policy. ephemeral: true gets you a 30-minute URL instead, which matches what remove.bg did (it kept nothing).

3. The price is public now

remove.bg's API page published rate limits, not a per-image price. Leonardo publishes one: $0.1047 per image, returned in every response as a cost object.

Price per image: Leonardo.Ai versus BackGone top-up tiersBar chart. Leonardo.Ai, the migration target remove.bg recommends, charges $0.1047 per image. BackGone's tiers cost $0.033, $0.029, $0.025 and $0.020 at the $10, $29, $99 and $299 levels.Price per imageLeonardo.Ai — remove.bg's own recommended migration target — against our top-up tiersLeonardo.Ai$0.1047$10 — 300$0.033$29 — 1,000$0.029$99 — 4,000$0.025$299 — 15,000$0.020$0$0.05$0.10Sources: Leonardo's remove.bg migration guide and backgone.com/pricing, read 2026-09-21.

Our own top-ups are $10 for 300, $29 for 1,000, $99 for 4,000 and $299 for 15,000 — $0.033 down to $0.020 per image. That is the comparison we can defend, because both columns are published by the vendor that charges them. What it is not is the whole decision: price per image matters less than whether the integration fits your pipeline.

The question nobody asks: what happens to large images

Background removal APIs are usually benchmarked on flattering inputs. The failure mode that costs you a customer is a print-resolution photo from a phone or a product shoot. Here is the part most comparisons skip, because it is about the server rather than the model: if the service decodes your result to inspect or resize the pixels, every megapixel costs 4 bytes of memory per pixel, and serverless runtimes cap that hard.

Why large images fail: one decode against the 128 MB isolate limitVertical bar chart in megabytes: 24 MB at 6 megapixels, 36 at 9, 48 at 12, 96 at 24 and 200 at 50, against a 128 MB isolate cap that is the same on free and paid plans.Why big images fail: one decode, measured against the isolateA 4-byte-per-pixel RGBA buffer is unavoidable if you inspect or resize pixels server-side064128192128 MB — a Cloudflare Worker isolate, identical on Free and Paid24 MB6 MPpasses36 MB9 MPpasses · the client's own ceiling48 MB12 MPfails in production96 MB24 MP200 MB50 MPMeasured on production 2026-09-21: 6 MP and 9 MP return 200; 12 MP returns Cloudflare error 1102.Bars are the RGBA buffer alone; the peak also carries the PNG, the base64 string and the runtime.

We hit this wall ourselves and it is why our API has a number in its contract instead of a promise: 50 megapixels (8000×6250), the same ceiling remove.bg used to publish for JPG and ZIP results. To get there we stopped decoding results above 6 megapixels for API and paid callers — the no-subject check now uses the output's file size as a proxy instead of a pixel scan, which is a heuristic and is documented as one. Below that threshold nothing changed.

The practical advice: before you migrate, run your worst image through the new API, not your average one. The script below does exactly that.

Latency, measured

These are single runs against our own live API, from this workstation, on 21 September 2026 — not averages, and the model dominates, which is why the numbers are not a clean curve:

End-to-end latency by input size on the live APIHorizontal bar chart of single-run production measurements: 6 megapixels 14.1 seconds, 12 megapixels 13.2, 24 megapixels 17.9, 50 megapixels 32.8. Output PNG sizes measured 3.3 MB at 6 megapixels and 16.4 MB at 50.End-to-end latency by input size, measured on the live APISingle runs, not averages: the model dominates, so the order is not a clean curve0s10s20s30s6 MP3000×200014.1s3.3 MB out12 MP4000×300013.2s24 MP6000×400017.9s50 MP8000×625032.8s16.4 MB outMeasured 2026-09-21 against backgone.com/api/v1/remove, one call per size, files uploaded from this workstation.Output sizes were recorded for the smallest and largest only; every call returned a full-resolution PNG and charged one credit.

Read that as "large inputs work and cost you a longer wait", not as a benchmark against Leonardo: we have not run a controlled side-by-side, and we are not going to publish a number we did not measure.

Verify all of this yourself in five minutes

Do not trust a migration guide, including this one. Three commands settle it:

# 1. The deadline, from remove.bg's own page
curl -s https://www.remove.bg/api | grep -o 'Starting December 1, 2026[^<]*'

# 2. Canva's public API really has no background removal (52 paths, zero hits)
curl -s https://www.canva.dev/sources/connect/api/latest/api.yml | grep -ci 'remove.background'

# 3. Your own worst image through both APIs: wall time, output bytes, price
curl -s -o /dev/null -w 'ours: %{time_total}s %{size_download} bytes\n' \
  -X POST https://backgone.com/api/v1/remove \
  -H "Authorization: Bearer $BACKGONE_KEY" -F image_file=@your-worst-photo.jpg

Sources and method

  • The deadline and the destination — remove.bg's API page and its migration guide link, read 21 September 2026.
  • The ownership — Canva's newsroom announcement welcoming Leonardo.Ai, 2024.
  • The negative finding — Canva's published Connect API specification (canva.dev), searched 21 September 2026: 52 paths, zero matches for background removal.
  • Leonardo's contract — its own "Migrate from the remove.bg API" guide, which is where the $0.1047 figure, the JSON-only body and response, the storage default and the format list come from.
  • Our latency and output sizes — single calls to backgone.com/api/v1/remove on 21 September 2026, one per input size, uploaded from this workstation; output sizes were recorded for the smallest and largest only.
  • The memory chart — bytes are arithmetic (4 bytes per pixel for RGBA); the pass/fail boundary is measured on production: 6 MP and 9 MP return 200, 12 MP returns Cloudflare error 1102 on the path that still decodes.

FAQ

Can I keep calling the remove.bg API after 1 December 2026? Its own page says background removal moves to Leonardo on that date. Plan as if the endpoint is gone; do not plan around a grace period that nobody has documented.

Is Leonardo the only option? No — it is the destination remove.bg chose to point at. The two things worth comparing are the contract (request shape, response shape, storage) and the price per image, and both are published by every serious vendor.

How much code has to change? If you follow remove.bg's pointer: the auth header, the body shape, the image reference, the response handling and your cost accounting. If you keep a multipart-in, image-out shape, less.

Do I have to worry about image size? Yes, and it is the least documented part of any of these APIs. Test your largest real input before you commit, and check what the API does when it is too big: a clear error with the megapixels it measured is worth more than a mysterious 500.


Written by the BackGone team, which runs the background-removal API linked above. Every number here comes from our own production measurement or from a first-party document named next to it; where we measured once rather than many times, the text says so. If you spot an error, tell us and we will fix it and say that we did.