How to Use a Watermark Remover API with Node.js (2026)
Node.js is one of the most popular runtimes for building API integrations. This guide shows exactly how to remove watermarks programmatically using a watermark removal API with Node.js in 2026 — from a simple single-image call to a full bulk processing script.
Prerequisites
- Node.js 18+ (native fetch API available)
- An API key from a watermark removal provider
npm install form-data node-fetchif using Node 16 or below
Environment Setup
# .env
WATERMARK_API_KEY=your_api_key_here
WATERMARK_API_URL=https://api.provider.com/v1/images/remove-watermark
# Install dotenv
npm install dotenv
Single Image Removal (Node.js 18+)
import 'dotenv/config'
import fs from 'fs'
import path from 'path'
async function removeWatermark(inputPath, outputPath) {
const imageBuffer = fs.readFileSync(inputPath)
const blob = new Blob([imageBuffer], { type: 'image/jpeg' })
const formData = new FormData()
formData.append('image', blob, path.basename(inputPath))
formData.append('output_format', 'png')
const response = await fetch(process.env.WATERMARK_API_URL, {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + process.env.WATERMARK_API_KEY },
body: formData
})
if (!response.ok) {
const err = await response.json().catch(() => ({}))
throw new Error(`API error ${response.status}: ${err.message || 'unknown'}`)
}
const resultBuffer = Buffer.from(await response.arrayBuffer())
fs.writeFileSync(outputPath, resultBuffer)
console.log('✅ Saved:', outputPath)
}
await removeWatermark('./input.jpg', './output.png')
Bulk Processing with Concurrency Control
import pLimit from 'p-limit'
const limit = pLimit(5) // max 5 concurrent API calls to respect rate limits
async function processBatch(inputDir, outputDir) {
fs.mkdirSync(outputDir, { recursive: true })
const files = fs.readdirSync(inputDir)
.filter(f => /.(jpg|jpeg|png|webp)$/i.test(f))
console.log(`Processing ${files.length} images...`)
const results = await Promise.allSettled(
files.map(file =>
limit(async () => {
const inputPath = path.join(inputDir, file)
const outputPath = path.join(outputDir, file.replace(/.[^.]+$/, '.png'))
await removeWatermark(inputPath, outputPath)
return file
})
)
)
const succeeded = results.filter(r => r.status === 'fulfilled').length
const failed = results.filter(r => r.status === 'rejected').length
console.log(`Done. Succeeded: ${succeeded}, Failed: ${failed}`)
}
await processBatch('./watermarked', './cleaned')
Express Middleware Integration
import express from 'express'
import multer from 'multer'
const app = express()
const upload = multer({ storage: multer.memoryStorage() })
app.post('/api/remove-watermark', upload.single('image'), async (req, res) => {
if (!req.file) return res.status(400).json({ error: 'No image provided' })
try {
const blob = new Blob([req.file.buffer], { type: req.file.mimetype })
const formData = new FormData()
formData.append('image', blob, req.file.originalname)
const apiResponse = await fetch(process.env.WATERMARK_API_URL, {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + process.env.WATERMARK_API_KEY },
body: formData
})
if (!apiResponse.ok) throw new Error('API failed: ' + apiResponse.status)
const cleanedBuffer = Buffer.from(await apiResponse.arrayBuffer())
res.set('Content-Type', 'image/png')
res.set('Content-Disposition', 'attachment; filename="clean.png"')
res.send(cleanedBuffer)
} catch (err) {
res.status(500).json({ error: err.message })
}
})
app.listen(3000, () => console.log('Server running on :3000'))
Rate Limit Retry with Backoff
async function removeWithRetry(inputPath, outputPath, attempt = 0) {
try {
return await removeWatermark(inputPath, outputPath)
} catch (err) {
if (err.message.includes('429') && attempt < 4) {
const delay = (2 ** attempt) * 1000
console.warn(`Rate limited. Retrying in ${delay}ms...`)
await new Promise(r => setTimeout(r, delay))
return removeWithRetry(inputPath, outputPath, attempt + 1)
}
throw err
}
}
Conclusion
Node.js makes watermark removal API integration clean and readable using native fetch and FormData. For production bulk jobs, always add concurrency limiting and retry logic. For browser-based applications, consider client-side processing via tools like AI Watermark Remover to eliminate server-side API costs entirely.