# 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) or `application/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. ```bash curl https://xocen-rembg.hf.space/health ``` **200 OK** ```json { "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. ```bash curl https://xocen-rembg.hf.space/jobs ``` **200 OK** ```json { "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 } ] } ``` - `jobs` is ordered oldest-first; with one worker the oldest is the one `processing`. - `label` is the original filename when known (set by `/remove`, `/remove/batch`, and the UI), otherwise `null`. - `age_seconds` is 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/png` with a transparent background ```bash 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/zip` containing one PNG per input (named after the original file, with a `.png` extension). If any image fails, the ZIP also contains `_errors.txt` listing the failures — the rest still succeed. ```bash 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 the `KILL_API_KEY` env var (set as a Space secret). ```bash curl "https://xocen-rembg.hf.space/kill?key=YOUR_KEY" ``` **200 OK** ```json { "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`) ```python 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`) ```js 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 in `queue`. Check progress via `/health`. - **No auth on `/remove*`:** only `/kill` is 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, …).