API
Same contract the UI uses. OpenAPI live docs: https://api.rembg.site/docs
Auth
Send Authorization: Bearer <key>. Create project keys in the dashboard after signing in. Legacy env API_KEYS still work. The signed-in website uses short-lived JWTs from POST /api/token (session required).
POST /v1/remove
- multipart field
file— JPEG, PNG, WebP, or HEIC · max 15MB - optional
crop=true— trim transparent bounds - success:
image/pngwith alpha - errors: JSON
{ error, code, hint }
Limits
- 30 requests per minute per API key or IP — HTTP
429code=rate_limited - One in-flight inference — HTTP
429code=busy - 50 removals per project per UTC day (override with API env
DAILY_QUOTA_PER_PROJECT) — HTTP429code=quota_exceeded. Hint names the limit and that usage resets at the next UTC midnight.
The daily cap is counted from today's usage_events for the authenticated project (dashboard keys, signed-in website web-ui traffic, and legacy keys). If the database is unavailable so the count cannot be read, the API fails open and still runs inference.
Restarts and first inference
The Oracle VM stays on. After a service restart the model loads into RAM; GET /v1/health returns 503 with code=waking until ready. Set client timeouts to at least 120 seconds. Warm CPU inference is typically a few seconds (isnet-general-use).
curl
curl -X POST "https://api.rembg.site/v1/remove" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@./photo.jpg" \
--max-time 120 \
-o removed.pngfetch
const form = new FormData();
form.append("file", file); // File / Blob
const res = await fetch("https://api.rembg.site/v1/remove", {
method: "POST",
headers: { Authorization: "Bearer YOUR_API_KEY" },
body: form,
// Free tier cold start: allow at least 120s
signal: AbortSignal.timeout(120_000),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.error + " — " + err.hint);
}
const png = await res.blob(); // image/png with alpha