API documentation
Base URL: https://geminiwatermarkremoverai.in/api. All requests use HTTPS. Responses are JSON unless you ask for the image itself.
Authentication
Create a key in your dashboard and send it in the Authorization header. Keep keys on your server; never put them in browser or mobile app code.
Authorization: Bearer vm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxLock a key to your servers
For production, add your servers' public IP addresses (or CIDR ranges such as 10.0.0.0/24) to the key in the dashboard. Requests from any other address are refused with 403 ip_not_allowed, so a leaked key can't be used by anyone else. The API also doesn't allow calls from web pages in a browser (no CORS), so a key copied into another website won't work there either.
Remove a watermark
POST /v1/images/remove-watermark
Send the image in one of two ways:
multipart/form-datawith the file in a field namedimage, or- the raw image bytes with
Content-Type: image/png,image/jpegorimage/webp.
Query parameters
| output_format | png (default, lossless), jpeg or webp (quality 95). |
| response | binary (default: the image itself) or json (metadata plus the image as base64). |
Supported: original Gemini images in PNG, JPEG or WebP, up to 20 MB.
Responses
With the default binary response you get the cleaned image and these headers:
| X-Watermark-Removed | true, or false when no Gemini watermark was found (the image is returned unchanged). |
| X-Quality | clean, visible-residual (a faint trace may remain) or possible-content-damage (check the corner). |
| X-Credits-Charged | 1 when a watermark was removed, otherwise 0. |
| X-Credits-Remaining | Your balance after this request. |
| RateLimit-* | Your per-minute limit, requests left and seconds until it resets. |
With response=json:
{
"request_id": 18342,
"watermark_removed": true,
"quality": "clean",
"watermark": { "size": 96, "position": { "x": 1888, "y": 1888, "width": 96, "height": 96 } },
"image": { "width": 2048, "height": 2048, "format": "png", "base64": "iVBORw0KGgo…" },
"credits": { "charged": 1, "remaining": 1999 }
}Code examples
cURL
curl -X POST "https://geminiwatermarkremoverai.in/api/v1/images/remove-watermark" \
-H "Authorization: Bearer $API_KEY" \
-F "[email protected]" \
-o clean.pngJavaScript (Node.js 18+)
import { readFile, writeFile } from 'node:fs/promises';
const form = new FormData();
form.set('image', new Blob([await readFile('input.png')], { type: 'image/png' }), 'input.png');
const res = await fetch('https://geminiwatermarkremoverai.in/api/v1/images/remove-watermark', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}` },
body: form,
});
if (!res.ok) throw new Error((await res.json()).detail);
await writeFile('clean.png', Buffer.from(await res.arrayBuffer()));
console.log('Removed:', res.headers.get('x-watermark-removed'));Python (requests)
import os, requests
with open("input.png", "rb") as f:
res = requests.post(
"https://geminiwatermarkremoverai.in/api/v1/images/remove-watermark",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
files={"image": ("input.png", f, "image/png")},
timeout=60,
)
res.raise_for_status()
open("clean.png", "wb").write(res.content)
print("Removed:", res.headers["X-Watermark-Removed"])PHP (cURL)
<?php
$ch = curl_init('https://geminiwatermarkremoverai.in/api/v1/images/remove-watermark');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('API_KEY')],
CURLOPT_POSTFIELDS => ['image' => new CURLFile('input.png', 'image/png')],
CURLOPT_RETURNTRANSFER => true,
]);
$image = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) file_put_contents('clean.png', $image);Check your credits
GET /v1/account — free
{
"email": "[email protected]",
"credits": { "remaining": 1999, "expiring_within_30_days": 0, "next_expiry": "2027-10-23T09:12:44.000Z" },
"limits": { "requests_per_minute": 60, "max_image_mb": 20 },
"key": { "name": "Production", "prefix": "vm_live_Ab12Cd" }
}Credits and limits
- 1 credit per image where a watermark is removed. No watermark found: free.
- Credits are prepaid and valid for the period shown when you buy them (oldest credits are used first).
- 60 requests per minute per account (all keys together), and up to 2 images processed at the same time. Need more? Contact us.
- Images up to 20 MB. Requests time out after 60 seconds.
- Images are processed in memory and not stored.
Errors
Errors use the standard application/problem+json format with a stable code:
{ "status": 402, "code": "insufficient_credits", "title": "Payment required", "detail": "You have no credits left. Buy more at /dashboard/billing." }| Status | Code | Meaning |
|---|---|---|
| 400 | missing_image | No image in the request, or the image is empty. |
| 400 | invalid_output_format | output_format is not png, jpeg or webp. |
| 401 | missing_api_key | No API key was sent. |
| 401 | invalid_api_key | The key is wrong or has been revoked. |
| 402 | insufficient_credits | Your credit balance is zero. Buy credits in the dashboard. |
| 403 | email_not_verified | Confirm your email address first. |
| 403 | account_suspended | The account is suspended. Contact support. |
| 403 | ip_not_allowed | The key is locked to other IP addresses. Add this server’s IP to the key in the dashboard. |
| 413 | image_too_large | The file is larger than the maximum size, or the image is over 20 megapixels (bigger than any Gemini output). |
| 415 | unsupported_image | The file is not a PNG, JPEG or WebP image. |
| 415 | unsupported_body | Use multipart/form-data with an "image" field, or raw bytes with an image/* Content-Type. |
| 422 | unprocessable_image | The image is corrupted or could not be decoded. |
| 429 | rate_limited | Too many requests per minute. Wait for the Retry-After seconds. |
| 429 | too_many_concurrent_requests | More than 2 images from your account are being processed. Wait for a response before sending the next. |
| 429 | free_limit_reached | Over 300 images in the last hour had no Gemini watermark (these are free). Send only Gemini images, or wait. |
| 503 | busy | The service is busy. Retry after a few seconds. |
| 503 | maintenance | Temporary maintenance. Retry later. |
Using the API means you agree to the API terms.