rembg · birefnet-general — API Reference
Background-removal service (model: birefnet-general). Exposes a REST API and a Gradio web UI on a single port (7860). All inference runs through one shared worker — every request (UI or API) is queued and processed one image at a time.
- Base URL:
https://xocen-rembg.hf.space - Web UI:
https://xocen-rembg.hf.space/→ redirects to/ui - Content type of results:
image/png(single) orapplication/zip(batch)
Note: birefnet-general on free CPU is slow (~10–30 s per image). Large batches take a while because they run sequentially through the single worker.
Endpoints
| Method | Path | Purpose | Returns |
|---|---|---|---|
| GET | / |
Redirect to the web UI | 307 → /ui |
| GET | /health |
Liveness + queue status | JSON |
| GET | /jobs |
List current jobs (queued + processing) | JSON |
| POST | /remove |
Remove background from one image | image/png |
| POST | /remove/batch |
Remove background from many images | application/zip |
| GET | /kill?key=… |
Cancel queued jobs + hard-restart worker | JSON |
GET /health
Health check and live queue stats.
curl https://xocen-rembg.hf.space/health
200 OK
{
"status": "ok",
"model": "birefnet-general",
"queue": 0,
"in_flight": 0
}
queue— jobs waiting to start.in_flight— jobs currently being processed (0 or 1 with a single worker).
GET /jobs
List the jobs the server currently knows about — both waiting and processing. Jobs disappear from the list once they finish (the response is already returned to that client). Useful for watching a batch drain.
curl https://xocen-rembg.hf.space/jobs
200 OK
{
"total": 3,
"queue": 2,
"in_flight": 1,
"jobs": [
{ "id": "9f2c…", "status": "processing", "label": "a.jpg", "age_seconds": 12.4 },
{ "id": "1b07…", "status": "queued", "label": "b.jpg", "age_seconds": 12.3 },
{ "id": "44de…", "status": "queued", "label": "c.jpg", "age_seconds": 12.3 }
]
}
jobsis ordered oldest-first; with one worker the oldest is the oneprocessing.labelis the original filename when known (set by/remove,/remove/batch, and the UI), otherwisenull.age_secondsis how long the job has existed (queued + processing time).
POST /remove
Remove the background from a single image.
- Body:
multipart/form-data - Field name:
file(must be an image; max size =MAX_FILE_MB, default 30 MB) - Response:
image/pngwith a transparent background
curl -X POST https://xocen-rembg.hf.space/remove \
-F "file=@input.jpg" \
--output output.png
Errors
| Status | When |
|---|---|
| 400 | Field isn't an image, or file exceeds the size limit |
POST /remove/batch
Remove backgrounds from multiple images in one call.
- Body:
multipart/form-data - Field name:
files— repeat it once per image (max count =MAX_BATCH_FILES, default 20) - Response:
application/zipcontaining one PNG per input (named after the original file, with a.pngextension). If any image fails, the ZIP also contains_errors.txtlisting the failures — the rest still succeed.
curl -X POST https://xocen-rembg.hf.space/remove/batch \
-F "files=@a.jpg" \
-F "files=@b.png" \
-F "files=@c.webp" \
--output results.zip
unzip -l results.zip
# a.png
# b.png
# c.png
# _errors.txt (only present if something failed)
Errors
| Status | When |
|---|---|
| 400 | More than MAX_BATCH_FILES files uploaded |
Per-file problems (not an image, too large, inference error) do not fail the
whole batch — that file is skipped and recorded in _errors.txt.
GET /kill
Cancel everything: drops all queued jobs and hard-restarts the worker process, aborting the job currently in progress. Guarded by a secret key.
- Query param:
key— must equal theKILL_API_KEYenv var (set as a Space secret).
curl "https://xocen-rembg.hf.space/kill?key=YOUR_KEY"
200 OK
{ "killed_pending": 3, "worker_restarted": true }
Errors
| Status | When |
|---|---|
| 401 | Missing or wrong key |
| 503 | KILL_API_KEY is not configured on the server |
After a kill, the worker respawns and reloads the model on the next request (a few seconds of warm-up).
Usage examples
Python (requests)
import requests
BASE = "https://xocen-rembg.hf.space"
# single
with open("input.jpg", "rb") as f:
r = requests.post(f"{BASE}/remove", files={"file": f})
r.raise_for_status()
with open("output.png", "wb") as out:
out.write(r.content)
# batch
files = [
("files", ("a.jpg", open("a.jpg", "rb"), "image/jpeg")),
("files", ("b.png", open("b.png", "rb"), "image/png")),
]
r = requests.post(f"{BASE}/remove/batch", files=files)
r.raise_for_status()
with open("results.zip", "wb") as out:
out.write(r.content)
# kill
requests.get(f"{BASE}/kill", params={"key": "YOUR_KEY"})
JavaScript (browser / Node fetch)
const BASE = "https://xocen-rembg.hf.space";
// single
const fd = new FormData();
fd.append("file", fileInput.files[0]);
const res = await fetch(`${BASE}/remove`, { method: "POST", body: fd });
const blob = await res.blob(); // image/png
const url = URL.createObjectURL(blob);
// batch
const fd2 = new FormData();
for (const f of fileInput.files) fd2.append("files", f);
const zip = await (await fetch(`${BASE}/remove/batch`, { method: "POST", body: fd2 })).blob();
Configuration (server-side env vars)
Set these in the Space → Settings → Variables and secrets.
| Var | Default | Meaning |
|---|---|---|
KILL_API_KEY |
(unset) | Required for /kill; unset → /kill returns 503. Store as a secret. |
WORKERS |
1 |
Worker processes (each holds one ~1 GB model copy). Keep at 1 on free CPU. |
MAX_BATCH_FILES |
20 |
Max files per /remove/batch request. |
MAX_FILE_MB |
30 |
Max size per uploaded file. |
Behavior notes
- Single queue: UI and API share one worker. With
WORKERS=1, only one image is processed at a time; others wait inqueue. Check progress via/health. - No auth on
/remove*: only/killis key-protected. Add a proxy/auth layer if you need to restrict who can submit images. - Output is always PNG (RGBA with transparency), regardless of input format (JPG, PNG, WebP, …).