Gemini Watermark Remover API
Send an image, get the cleaned image back — the same pipeline as the web app: it finds the Gemini mark, reverses it losslessly with the alpha map when it can, and falls back to LaMa inpainting only where needed.
Endpoint
POST /api/v1/removeSend the image as multipart/form-data (field image), as JSON {"image": "<base64 or data URL>"}, or as the raw bytes with Content-Type: image/png / image/jpeg. Options go in the form fields, the JSON body, or the query string. PNG and JPEG, up to 15 MB and 12 megapixels.
Auth: when the server has API_KEYS configured, send X-API-Key: KEY or Authorization: Bearer KEY. CORS is open, so browsers can call it directly — keep keys out of public front-end code.
Examples
curl
curl -X POST "https://app.gemini-logo-remover.workers.dev/api/v1/remove" \
-H "X-API-Key: YOUR_KEY" \
-F "image=@gemini-image.png" \
-o clean.pngJavaScript
const form = new FormData();
form.append("image", file); // File / Blob (PNG or JPEG)
const res = await fetch("https://app.gemini-logo-remover.workers.dev/api/v1/remove", {
method: "POST",
headers: { "X-API-Key": "YOUR_KEY" },
body: form,
});
if (!res.ok) throw new Error((await res.json()).error.message);
const cleanBlob = await res.blob();
console.log(res.headers.get("X-Removal-Method")); // alpha | inpaint | alpha+inpaint | nonePython
import requests
r = requests.post(
"https://app.gemini-logo-remover.workers.dev/api/v1/remove",
headers={"X-API-Key": "YOUR_KEY"},
files={"image": open("gemini-image.png", "rb")},
timeout=120,
)
r.raise_for_status()
open("clean.png", "wb").write(r.content)
print(r.headers["X-Removal-Method"], r.headers.get("X-Clean"))Options
| Name | Default | Meaning |
|---|---|---|
| mode | auto | auto = find each mark, fit its strength, reverse it losslessly (text under it comes back), check what is left, and inpaint ONLY a leftover or a mark that no scaled alpha overlay explains. alpha = lossless only, never calls the inpaint service (unchanged image + a warning if a mark cannot be reversed). inpaint = skip alpha and inpaint the found slot. |
| response | image | image returns the cleaned file; json returns base64 plus a detailed report. |
| format | png | png, jpeg, or auto (same as the input). |
| quality | 92 | 1–100. JPEG output only. |
| sparkle | false | Also inpaint the small V3 sparkle slot. It cannot be verified, so it is off by default; turning it on can damage text near the corner. |
| feather | 12 | 0–16 px edge blend for inpainted areas. |
| full_size | — | WxH. Send only the bottom-right crop (min(W,480) x min(H,480) px) of a WxH image; the response is the cleaned crop. Used by the Colab notebook. |
| region | — | x,y,width,height in pixels. Skips detection and inpaints exactly this box. |
Response
By default the body is the cleaned image, with these headers: X-Watermark-Detected, X-Watermark-Slot, X-Detection-Confidence, X-Removal-Method (alpha, inpaint, alpha+inpaint or none), X-Clean, X-Image-Width, X-Image-Height and, if something degraded, X-Warnings. With response=json:
{
"ok": true,
"image": { "mimeType": "image/png", "format": "png", "width": 1536, "height": 1536, "base64": "iVBORw0..." },
"result": {
"detected": true,
"slot": "v1",
"confidence": 0.968,
"method": "alpha",
"clean": true,
"passes": [{ "method": "alpha", "reason": "Reverse alpha blend at V1 legacy", "region": { "x": 1376, "y": 1376, "width": 96, "height": 96 } }],
"warnings": []
}
}Errors
Errors are JSON: {"ok": false, "error": {"code": "...", "message": "..."}}
- 400 Missing/invalid image or option
- 401 Missing or invalid API key (only when the server has API_KEYS set)
- 413 Upload over 15 MB, or image over 12 megapixels
- 415 Not a PNG or JPEG
- 422 File could not be decoded
- 502 The inpaint service failed — retry, or use mode=alpha