Local API#
Optional HTTP API that speaks the same contract from withoutBG for Mac and Docker service-* images. Traffic stays on loopback. Images are processed on device.
Hosts#
- Mac: enable Local API in the withoutBG for Mac menu bar or Settings. Base URL
http://127.0.0.1:8000. - Docker: service-cpu / service-gpu on port 8000.
- Headless Mac (CI): /mac/headless
Endpoints#
GET /health: livenessGET /openapi.json: live OpenAPI from the running server. Canonical copy: /openapi/local-api.jsonPOST /v1/remove-background: cutout or matte
Query param ?output=cutout|matte (default cutout).
Request body: raw image bytes, or multipart field image. Response: PNG plus X-Latency-Ms header.
Smart Brush (Keep / Remove)#
New with Open Weights v4. Send masks next to the image in the same multipart request and the server fixes the cutout with the stroke-edit network, on device:
keep_mask: white where something went missing and should stay.remove_mask: white where something should go.matte(optional): the previous matte, to keep refining in rounds.
Masks and matte are PNGs at the image's size. Send at least one mask. One stroke on an object reaches the whole object, and pixels away from your strokes stay as they were. Where Keep and Remove overlap, Remove wins. Invalid masks return 422.
curl Smart Brush
curl -sS -X POST \
'http://127.0.0.1:8000/v1/remove-background?output=cutout' \
-F 'image=@input.jpg' \
-F 'remove_mask=@remove.png' \
-F 'keep_mask=@keep.png' \
-F 'matte=@matte.png' \
-o fixed.pngExamples#
curl cutout#
curl cutout
curl -sS -X POST \
'http://127.0.0.1:8000/v1/remove-background?output=cutout' \
-H 'Content-Type: image/jpeg' \
--data-binary @input.jpg \
-o cutout.pngcurl matte#
curl matte
curl -sS -X POST \
'http://127.0.0.1:8000/v1/remove-background?output=matte' \
-F 'image=@input.jpg' \
-o matte.pngPython#
Python urllib
import urllib.request
url = "http://127.0.0.1:8000/v1/remove-background?output=cutout"
with open("input.jpg", "rb") as f:
data = f.read()
req = urllib.request.Request(url, data=data, method="POST")
req.add_header("Content-Type", "image/jpeg")
with urllib.request.urlopen(req) as resp:
open("cutout.png", "wb").write(resp.read())Errors#
400: invalid or missing image422: invalid Smart Brush mask or matte (wrong size, not an image, or a matte without a mask)500: inference failure- Connection refused: Local API not running (start Mac app Local API or Docker service)
GIMP plugin#
Point the GIMP plugin at http://127.0.0.1:8000 while Local API is running.
Privacy#
Local API binds to loopback. Open Model inference and Smart Brush stay on device. The Mac Local API never calls the cloud, even when the app's optional withoutBG Pro engine is on. The Docker server only does so for engine=pro requests, when you enable it. See Privacy.