No API key. No account. No sign-up. One POST with an image, and the response body is the finished transparent PNG. Nothing to register for and nothing to wait on.
Last updated: 1 September 2026
This is the same engine the BGNinja website runs on, exposed directly over HTTP. It is free to call within the limits below. You do not need to ask us for access and there is no key to rotate.
curl -s -o output.png \
-F "[email protected]" \
https://bgninja.com/api/remove
That is the whole thing. output.png is your image with the background removed and an alpha channel where the background used to be.
| Method | POST |
|---|---|
| URL | https://bgninja.com/api/remove |
| Body | multipart/form-data |
| Auth | None |
| Name | Required | What it does |
|---|---|---|
file | yes | The image. PNG, JPG, WEBP or HEIC. |
bg | no | Hex colour without the #, for example ffffff. Composites the cutout onto that flat colour instead of leaving it transparent. Leave it out for transparency. |
src | no | A label identifying your app, for example my-plugin. Up to 32 characters, letters, digits and hyphens. It only helps us see which integrations are being used. Anything else is ignored. |
On success you get HTTP 200 and the raw bytes of a PNG, with Content-Type: image/png. The call is synchronous: there is no job id, no queue and nothing to poll. Write the body straight to a file or hand it to your image library.
| Maximum file size | 99 MB |
|---|---|
| Maximum resolution | 30 megapixels |
| Running at once | 2 per IP address |
| Requests per day | No cap |
These are real and enforced. There is no hidden unlimited tier, and the free result is the full-resolution image rather than a shrunken preview.
An error comes back as JSON with a single error key, not as an image. Check the status code before you write the body to a file.
| Status | Meaning |
|---|---|
400 | The file is not an image we can read. Wrong format, or the bytes are damaged. |
413 | Too big. Either over 99 MB, or more than 30 megapixels. |
422 | No file field in the request at all. |
429 | You already have two requests running from this address. Wait for one to finish and retry. |
$ curl -s -F "[email protected]" https://bgninja.com/api/remove
{"error":"can't read this file (TXT) — please upload a photo (JPG, PNG, WEBP, HEIC)."}
Because the limit is on how many run at once and not on a daily total, the right way to handle 429 is to retry the same image shortly after, not to back off for the rest of the day.
import requests
with open("input.jpg", "rb") as f:
r = requests.post(
"https://bgninja.com/api/remove",
files={"file": f},
data={"src": "my-app"},
timeout=120,
)
r.raise_for_status()
open("output.png", "wb").write(r.content)
import { readFile, writeFile } from "node:fs/promises";
const body = new FormData();
body.append("file", new Blob([await readFile("input.jpg")]), "input.jpg");
body.append("src", "my-app");
const r = await fetch("https://bgninja.com/api/remove", { method: "POST", body });
if (!r.ok) throw new Error(`HTTP ${r.status}`);
await writeFile("output.png", Buffer.from(await r.arrayBuffer()));
curl -s -o output.png \
-F "[email protected]" \
-F "bg=ffffff" \
https://bgninja.com/api/remove
It is processed in memory and streamed straight back to you. Nothing is written to disk, so there is no stored copy sitting somewhere waiting to be deleted or leaked. We keep a count of how many requests came in and how big they were, and nothing that identifies the picture itself.
You are welcome to build on this, including in something you charge for. Two things we ask, neither of them enforced:
src label so we can see that an integration exists and avoid breaking it.If you are about to send serious volume through it, say hello on the contact page first. We would rather hear from you than throttle you.
No. There is no key, no account and no sign-up. The endpoint is open.
Yes, within the limits above. It is not a trial and there is no card to add. The optional pass raises the limits on the website; the API limits listed here apply to everyone.
No daily cap. The only limit is two requests running at the same time per IP address.
Not today. The endpoint returns the composited PNG. If you need the mask on its own, tell us on the contact page and we will look at it.
It is the same endpoint our own site calls, so it will not quietly disappear. If the shape of the request ever has to change, the old form keeps working alongside it.
Terms of use are on the terms page, and what we do with data is on the privacy page.