API Reference

EraseWatermark API

Remove watermarks from images, PDFs, and videos via REST API. Authenticate with an API key; each request spends from your subscription or pay-as-you-go credit balance.

Overview

Base URL

https://api.erasewatermark.io

Protocol

HTTPS only

Format

multipart/form-data

Authentication

Pass your API key as a Bearer token in the Authorization header of every request. API keys start with wm_. You can create and revoke keys in the API Keys dashboard.

bash
Authorization: Bearer wm_your_api_key_here
Keep your key secret. If compromised, revoke it immediately from the dashboard and create a new one.

Endpoints

All endpoints are under https://api.erasewatermark.io/api/v1/watermark.

Image — Auto

POST/api/v1/watermark/imageasync

Remove watermark from an image. AI auto-detects the watermark. Processing is asynchronous — poll task status.

Cost: 1 credit

Request body (multipart/form-data)

filerequiredfileImage file. Supported: JPG, PNG, WEBP, AVIF. Max 10 MB, up to 36 megapixels (e.g. 6000×6000).
bash
curl -X POST https://api.erasewatermark.io/api/v1/watermark/image \
  -H "Authorization: Bearer wm_your_key" \
  -F "[email protected]"

Image — Manual (brush mask)

POST/api/v1/watermark/imageasync

Remove watermark guided by a brush mask you draw over the watermark area. Subscriber / API-key only.

Cost: 1 credit

Request body (multipart/form-data)

filerequiredfileImage file (same formats as auto).
maskrequiredfilePNG mask, any size (it is resized to the image). Paint the watermark area WHITE (255); leave everything else BLACK (0). The white region is what gets erased.
bash
curl -X POST https://api.erasewatermark.io/api/v1/watermark/image \
  -H "Authorization: Bearer wm_your_key" \
  -F "[email protected]" \
  -F "[email protected]"

Detect mask only

POST/api/v1/watermark/mask

Return ONLY the auto-detected watermark mask (base64 PNG) for an image, without removing anything. Synchronous — the mask is in the response, no task to poll. Subscriber / API-key only.

Cost: free

Request body (multipart/form-data)

filerequiredfileImage file (JPG, PNG, WEBP, AVIF). Max 10 MB.

Response (application/json)

mask_b64stringBase64-encoded PNG mask; white marks the detected watermark area.
fmtstringAlways "png".
coveragenumberFraction of the image covered by the mask (0–1), or null.
bash
curl -X POST https://api.erasewatermark.io/api/v1/watermark/mask \
  -H "Authorization: Bearer wm_your_key" \
  -F "[email protected]"

PDF

POST/api/v1/watermark/pdfasync

Remove watermarks from a PDF. Processing is asynchronous — poll task status.

Cost: 1 credit per page

Request body

filerequiredfilePDF file. Max 50 MB.
first_page_onlybooleanOptional (default false). true = process only the first page (1 credit); false = process the whole document (1 credit per page).

Video

POST/api/v1/watermark/videoasync

Remove watermarks from a video. Processing is asynchronous.

Cost: 1 credit

Request body

filerequiredfileVideo file. Supported: MP4, MOV, WEBM, AVI, MKV. Max 500 MB.

Task status

All three endpoints return a task_id. Poll this endpoint until status is completed or failed.

GET/api/v1/watermark/tasks/{task_id}

Poll processing status. Returns progress and download URL on completion.

Cost: free

Response fields

statusstring"pending" | "processing" | "completed" | "failed"
progressnumber0–100 percentage (video only).
download_urlstringPresent when status = completed. Relative path — prepend base URL.
file_idstringStable ID for the processed file.
errorstringError message when status = failed.
bash
curl https://api.erasewatermark.io/api/v1/watermark/tasks/abc123 \
  -H "Authorization: Bearer wm_your_key"
GET/api/v1/watermark/my-recent-tasks

List your recent tasks (active jobs + recent history). Returns { tasks: [ { task_id, filename, file_type, status, is_active, created_at, download_available } ] }.

Cost: free

Download result

GET/api/v1/watermark/download/{file_id}

Stream the processed file. Add ?inline=true to serve inline instead of as attachment.

Cost: free
bash
curl -O -J https://api.erasewatermark.io/api/v1/watermark/download/abc123 \
  -H "Authorization: Bearer wm_your_key"

Credits & limits

OperationCredits consumed
Image (auto or manual)1
Mask detection0 (free)
PDF1 per page
Video1
Task status poll0
Download0

Credits are deducted when processing begins. Credits for failed jobs are returned to your balance automatically.

Error codes

HTTP statusMeaning
200Success
400Bad request — invalid file, unsupported format, or file too large
401Unauthorized — invalid or revoked API key (a missing key is treated as anonymous)
402Insufficient credits
403Forbidden — you do not own this task, or the feature (manual brush / mask) requires a subscription
404Task or file not found
422Validation error — a required field (e.g. file) is missing or malformed
429Rate limited (anonymous users only)
500Internal server error — please retry
502Upstream processing error (e.g. mask detection) — please retry

All error responses include a detail field with a human-readable message.

Code examples

Python

python
import requests, time

API_KEY = "wm_your_api_key"
BASE    = "https://api.erasewatermark.io"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# Remove watermark from an image (auto)
with open("photo.jpg", "rb") as f:
    r = requests.post(f"{BASE}/api/v1/watermark/image",
                      headers=HEADERS, files={"file": f})
r.raise_for_status()
task_id = r.json()["task_id"]

# Poll until done
while True:
    status = requests.get(f"{BASE}/api/v1/watermark/tasks/{task_id}",
                          headers=HEADERS).json()
    if status["status"] == "completed":
        break
    if status["status"] == "failed":
        raise Exception(status["error"])
    time.sleep(2)

# Download result
dl = requests.get(f"{BASE}{status['download_url']}", headers=HEADERS)
with open("result.jpg", "wb") as f:
    f.write(dl.content)
print("Done! Saved result.jpg")

Node.js

javascript
import fs from 'fs';
import FormData from 'form-data';
import fetch from 'node-fetch';

const API_KEY = 'wm_your_api_key';
const BASE    = 'https://api.erasewatermark.io';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Submit image
const form = new FormData();
form.append('file', fs.createReadStream('photo.jpg'));
const { task_id } = await fetch(`${BASE}/api/v1/watermark/image`,
  { method: 'POST', headers: { ...headers, ...form.getHeaders() }, body: form }
).then(r => r.json());

// Poll
let status;
do {
  await new Promise(r => setTimeout(r, 2000));
  status = await fetch(`${BASE}/api/v1/watermark/tasks/${task_id}`,
    { headers }).then(r => r.json());
} while (!['completed','failed'].includes(status.status));

if (status.status === 'failed') throw new Error(status.error);

// Download
const buf = await fetch(`${BASE}${status.download_url}`, { headers })
  .then(r => r.arrayBuffer());
fs.writeFileSync('result.jpg', Buffer.from(buf));
console.log('Done!');