REST API for blurring faces and license plates in photos
The Watermarkly Blur API automatically detects and blurs license plates and faces in images.
This service is fully hosted on AWS infrastructure and ensures privacy by not using customer files for AI model training.
We’re using AWS Lambda, which allows us to handle thousands of parallel requests reliably and offer the service in several regions across the globe.
Features
- Automatically detects and blurs license plates and faces in images.
- Allows replacing license plates with your project logo.
- Optionally resizes, crops, or converts processed images.
- Supports up to 500 requests per second.
- Processes images in parallel for faster performance.
- Maximum supported image size: 6000x6000 pixels.
If you require faster processing, support for larger images, or a higher request rate, please contact us at api-support@watermarkly.com.
The API also allows you to replace license plates with your company logo.
API Endpoints
Regions
Currently, we provide the API in two regions:
- Europe: https://blur-api-eu1.watermarkly.com/ (eu-north-1)
- United States: https://blur-api-us1.watermarkly.com/ (us-east-2)
You’re free to use whichever endpoint is more convenient. You may use the second endpoint as a fallback in case a single AWS region goes down. If you need the API in a different region, please let us know.
Request Methods
You can submit images for processing using either GET or POST requests.
If your images are publicly available, we recommend sending GET requests as they are slightly faster than POST requests.
Blur Image Using GET Request (Recommended)
GET https://blur-api-eu1.watermarkly.com/blur/?url={image_url}
or
GET https://blur-api-us1.watermarkly.com/blur/?url={image_url}
Makes the service download the image from the image_url
and process it.
Request
- Method: GET
- URL Query Parameters:
url
(Required): The complete URL of the image to be processed.blur_intensity
(Optional): A float value between 0.0 and 20.0 that adjusts blur intensity. Default: 1.0. Passing 0.0 disables blurring.file_size
(Optional): Specifies the desired output file size in bytes. The service attempts to return an image that does not exceed this size.width
(Optional): Specifies the desired output image width.height
(Optional): Specifies the desired output image height.format
(Optional): Specifies the desired output image format. Possible values: JPEG, PNG, WEBP.logo_url
(Optional): The URL of a logo file to place on license plates. Can be an HTTP URL or a data URL. Ensure the URL is properly escaped before passing it as a request parameter.logo_size
(Optional): Specifies the logo size as a number from 0.1 to 1.0.plate_screws
(Optional): Adds plate screws to license plates. Effective together with logo_url parameter only.
Response
Successful Response: The service returns the processed image in one of the following formats: JPEG, PNG, WEBP.
Error Response:
{
"message": "Error message"
}
Blur Image Using POST Request
POST https://blur-api-eu1.watermarkly.com/blur/
or
POST https://blur-api-us1.watermarkly.com/blur/
Submits an image for processing.
Request
- Method:
POST
- Content-Type:
application/octet-stream
- Headers:
x-api-key
: Your API key
- Query Parameters:
blur_intensity
(Optional): A float value between 0.0 and 20.0 that adjusts blur intensity. Default: 1.0. Passing 0.0 disables blurring.file_size
(Optional): Specifies the desired output file size in bytes. The service attempts to return an image that does not exceed this size.width
(Optional): Specifies the desired output image width.height
(Optional): Specifies the desired output image height.format
(Optional): Specifies the desired output image format. Possible values: JPEG, PNG, WEBP.logo_url
(Optional): The URL of a logo file to place on license plates. Can be an HTTP URL or a data URL. Ensure the URL is properly escaped before passing it as a request parameter.logo_size
(Optional): Specifies the logo size as a number from 0.1 to 1.0.plate_screws
(Optional): Adds plate screws to license plates. Effective together with logo_url parameter only.
Response
Successful Response: The service returns the processed image in one of the following formats: JPEG, PNG, WEBP.
Error Response:
{
"message": "Error message"
}
Processing Details
- Processed images are not stored on our servers.
- The service accepts images in JPEG, PNG, WEBP, AVIF, HEIC/HEIF formats.
- AVIF and HEIF images will be converted to JPEG unless another format is specified.
- Maximum input image size:
- GET requests: 20MB or 6000x6000 pixels.
- POST requests: 6MB or 6000x6000 pixels.
- API rate limits:
- 500 parallel requests
- 500 requests per second
- 100,000 requests per day
- If you need increased limits, contact us at api-support@watermarkly.com, please.
Security and Privacy
- API requests require authentication via an API key.
- Customer files are not used for AI model training.
- All processing occurs on AWS infrastructure. We can deploy the API in a region of your choice free of charge.
Usage Examples
Python
import requests
import urllib.parse
API_KEY = 'your_api_key'
API_URL = 'https://blur-api-eu1.watermarkly.com/blur/'
input_path = '' # Local image path
output_path = '' # Local output path
# Blur image using POST request
with open(input_path, 'rb') as image_file:
response = requests.post(API_URL, headers={'x-api-key': API_KEY}, data=image_file)
if response.status_code == 429:
# API rate limit exceeded, wait a little
time.sleep(0.1)
response = requests.post(API_URL, headers={'x-api-key': API_KEY}, data=image_file)
# Save the processed image locally
with open(output_path, 'wb') as f:
f.write(response.content)
# Blur image using GET request
encoded_url = urllib.parse.quote("https://nikitin.io/eqe.jpg", safe='')
response = requests.get(API_URL + "?url=" + encoded_url, headers={'x-api-key': API_KEY})
# Save the response locally
with open(output_path, 'wb') as f:
f.write(response.content)
NodeJS
import { promises as fs } from "node:fs";
const API_KEY = 'your_api_key';
const API_URL = 'https://blur-api-eu1.watermarkly.com/blur/';
// Helper function to pause execution for the given number of milliseconds
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
(async () => {
// Blur image using POST request
try {
const inputPath = 'input_path_here'; // Replace with your actual input path
const outputPath = 'output_path_here'; // Replace with your actual output path
// Read image file as binary data asynchronously
const imageData = await fs.readFile(inputPath);
let response = await fetch(API_URL, {
method: 'POST',
headers: {
'x-api-key': API_KEY,
'Content-Type': 'application/octet-stream'
},
body: imageData
});
if (response.status === 429) {
// API rate limit exceeded, wait a little
await sleep(100); // sleep for 0.1 seconds
response = await fetch(API_URL, {
method: 'POST',
headers: {
'x-api-key': API_KEY,
'Content-Type': 'application/octet-stream'
},
body: imageData
});
}
// Save the processed image locally asynchronously
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
await fs.writeFile(outputPath, buffer);
} catch (error) {
console.error('Error during POST request:', error);
}
// Blur image using GET request
try {
const outputPath = 'output_path_here'; // Replace with your actual output path
const encodedUrl = encodeURIComponent("https://nikitin.io/eqe.jpg"); // Encode URL
const response = await fetch(`${API_URL}?url=${encodedUrl}`, {
method: 'GET',
headers: {
'x-api-key': API_KEY
}
});
// Save the response locally asynchronously
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
await fs.writeFile(outputPath, buffer);
} catch (error) {
console.error('Error during GET request:', error);
}
})();