REST API Free Tier AI-Powered

Watermark Remover API

Remove watermarks from images programmatically with a single API call. AI-powered detection handles text watermarks, logo overlays, stamps, and tiled patterns.

Why Use This API

AI Watermark Detection

Automatically detects watermark type, position, and opacity. No manual masking or region selection required.

Text Watermark Removal

Removes text-based watermarks including copyright notices, dates, photographer names, and stock photo stamps.

Logo Overlay Removal

Cleanly removes logo overlays, brand marks, and graphical watermarks while preserving underlying image detail.

Batch Processing Support

Process multiple images programmatically. Integrate into your pipeline for automated bulk watermark removal.

Quick Start

Start removing watermarks in under a minute. Here's how:

  1. Get your API keySign up free to receive your key
  2. Send a request — POST an image to the endpoint
  3. Get the result — Receive the clean image in the response
curl -X POST https://precisioncounter.com/api/v1/remove-watermark \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@watermarked-photo.jpg" \
  -o clean-result.png
import requests

response = requests.post(
    "https://precisioncounter.com/api/v1/remove-watermark",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    files={"image": open("watermarked-photo.jpg", "rb")}
)

with open("clean-result.png", "wb") as f:
    f.write(response.content)
const fs = require("fs");
const FormData = require("form-data");

const form = new FormData();
form.append("image", fs.createReadStream("watermarked-photo.jpg"));

const response = await fetch(
  "https://precisioncounter.com/api/v1/remove-watermark",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
      ...form.getHeaders()
    },
    body: form
  }
);

const buffer = Buffer.from(await response.arrayBuffer());
fs.writeFileSync("clean-result.png", buffer);

API Reference

Base URL

https://precisioncounter.com/api/v1

Authentication

All requests require an API key passed in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Remove Watermark

POST /api/v1/remove-watermark

Removes watermarks from an uploaded image and returns the clean image.

Request Parameters

Parameter Type Description
image required file Image with watermark to remove. Accepted formats: PNG, JPG, JPEG, WebP. Max size: 10 MB.
watermark_type optional string Type of watermark. Default: auto. Options: auto, text, logo, stamp.
quality optional string Output quality. Default: standard. Options: standard, hd.

Response

200 OK — Returns the processed image as binary data with Content-Type: image/png.

Response Headers

Header Value
Content-Type image/png or image/webp
X-Credits-Remaining Number of API credits remaining
X-Processing-Time Processing time in milliseconds

Code Examples

Full Examples (with error handling)

curl -X POST https://precisioncounter.com/api/v1/remove-watermark \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@watermarked-photo.jpg" \
  -F "watermark_type=auto" \
  -F "quality=hd" \
  -o clean-result.png

echo "Watermark removed successfully"
import requests
import sys

API_KEY = "YOUR_API_KEY"
API_URL = "https://precisioncounter.com/api/v1/remove-watermark"

def remove_watermark(input_path, output_path="clean-result.png"):
    """Remove watermark from an image file."""
    with open(input_path, "rb") as img:
        response = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"image": img},
            data={"watermark_type": "auto", "quality": "hd"}
        )

    if response.status_code == 200:
        with open(output_path, "wb") as f:
            f.write(response.content)
        print(f"Saved to {output_path}")
        print(f"Credits remaining: {response.headers.get('X-Credits-Remaining')}")
    else:
        print(f"Error {response.status_code}: {response.json()['error']}")

remove_watermark("watermarked-photo.jpg")
const fs = require("fs");
const FormData = require("form-data");
const fetch = require("node-fetch");

const API_KEY = "YOUR_API_KEY";
const API_URL = "https://precisioncounter.com/api/v1/remove-watermark";

async function removeWatermark(inputPath, outputPath = "clean-result.png") {
  const form = new FormData();
  form.append("image", fs.createReadStream(inputPath));
  form.append("watermark_type", "auto");
  form.append("quality", "hd");

  const response = await fetch(API_URL, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      ...form.getHeaders()
    },
    body: form
  });

  if (response.ok) {
    const buffer = Buffer.from(await response.arrayBuffer());
    fs.writeFileSync(outputPath, buffer);
    console.log(`Saved to ${outputPath}`);
    console.log(`Credits: ${response.headers.get("x-credits-remaining")}`);
  } else {
    const error = await response.json();
    console.error(`Error ${response.status}: ${error.error}`);
  }
}

removeWatermark("watermarked-photo.jpg");
<?php
$api_key = "YOUR_API_KEY";
$url = "https://precisioncounter.com/api/v1/remove-watermark";

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $api_key"
    ],
    CURLOPT_POSTFIELDS => [
        "image" => new CURLFile("watermarked-photo.jpg"),
        "watermark_type" => "auto",
        "quality" => "hd"
    ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 200) {
    file_put_contents("clean-result.png", $response);
    echo "Watermark removed successfully\n";
} else {
    echo "Error $httpCode: $response\n";
}
?>
package main

import (
    "bytes"
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "os"
)

func removeWatermark(inputPath, outputPath string) error {
    file, _ := os.Open(inputPath)
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    part, _ := writer.CreateFormFile("image", inputPath)
    io.Copy(part, file)
    writer.WriteField("watermark_type", "auto")
    writer.WriteField("quality", "hd")
    writer.Close()

    req, _ := http.NewRequest("POST",
        "https://precisioncounter.com/api/v1/remove-watermark", body)
    req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
    req.Header.Set("Content-Type", writer.FormDataContentType())

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    if resp.StatusCode == 200 {
        out, _ := os.Create(outputPath)
        defer out.Close()
        io.Copy(out, resp.Body)
        fmt.Printf("Saved to %s\n", outputPath)
    }
    return nil
}

func main() {
    removeWatermark("watermarked-photo.jpg", "clean-result.png")
}
require "net/http"
require "uri"

api_key = "YOUR_API_KEY"
uri = URI("https://precisioncounter.com/api/v1/remove-watermark")

form_data = [
  ["image", File.open("watermarked-photo.jpg", "rb")],
  ["watermark_type", "auto"],
  ["quality", "hd"]
]

req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{api_key}"
req.set_form(form_data, "multipart/form-data")

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(req)
end

if res.code == "200"
  File.binwrite("clean-result.png", res.body)
  puts "Watermark removed successfully"
else
  puts "Error #{res.code}: #{res.body}"
end
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_API_KEY");

using var form = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(File.ReadAllBytes("watermarked-photo.jpg"));
imageContent.Headers.ContentType = new("image/jpeg");
form.Add(imageContent, "image", "watermarked-photo.jpg");
form.Add(new StringContent("auto"), "watermark_type");
form.Add(new StringContent("hd"), "quality");

var response = await client.PostAsync(
    "https://precisioncounter.com/api/v1/remove-watermark", form);

if (response.IsSuccessStatusCode)
{
    var result = await response.Content.ReadAsByteArrayAsync();
    File.WriteAllBytes("clean-result.png", result);
    Console.WriteLine("Watermark removed successfully");
}

Error Handling

The API returns standard HTTP status codes with JSON error bodies:

Status Meaning Description
200 Success Image processed successfully. Response body is the output image.
400 Bad Request Missing image file, unsupported format, or file too large.
401 Unauthorized Missing or invalid API key.
429 Rate Limited Too many requests. Wait and retry with exponential backoff.
500 Server Error Internal processing error. Retry the request.

Error Response Format

{
  "error": "Invalid file format. Accepted: png, jpg, jpeg, webp",
  "code": "INVALID_FORMAT",
  "status": 400
}

Rate Limits

Plan Requests / Minute Max File Size Max Resolution
Free 10 10 MB 4096 x 4096 px
Pro 60 25 MB 8192 x 8192 px

Rate limit headers are included in every response:

X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1708646400

Use Cases

  • Stock photo processing
  • Document declassification
  • E-commerce product cleanup
  • Social media content
  • Real estate photo editing
  • Academic research images
  • Print production
  • Digital asset management

Pricing

Free to Start

Get free API credits when you sign up. No credit card required.

Frequently Asked Questions

What types of watermarks can the API remove?
The API can remove text watermarks, logo overlays, stamps, date stamps, and tiled/repeated watermarks. It uses AI to automatically detect the watermark type and position, then reconstructs the underlying image content.
Is the Watermark Remover API free?
Yes. You get free API calls to try the service when you sign up. No credit card is required to get started. Upgrade to Pro for higher rate limits and larger file sizes.
What image formats are supported?
The API accepts PNG, JPG, JPEG, and WebP images as input. The output is returned as PNG by default. You can also request WebP output for smaller file sizes.
How accurate is the watermark removal?
The AI achieves high accuracy for most watermark types. Text watermarks and semi-transparent overlays are handled with excellent results. For best quality, use the quality: "hd" parameter and specify the watermark_type if known.
Can it handle transparent/semi-transparent watermarks?
Yes. The AI is specifically trained to detect and remove semi-transparent watermarks, including those with varying opacity levels and blending modes. It reconstructs the original image content beneath the watermark.
What is the maximum file size?
The maximum file size per request is 10 MB on the free plan and 25 MB on the Pro plan. For best results and fastest processing, images under 5 MB are recommended.
Does the API work with tiled/repeated watermarks?
Yes. The API can detect and remove tiled and repeated watermark patterns across an image. Set watermark_type to auto for best results, as the AI will identify the repeating pattern and remove all instances.