REST API. Blur Faces and License Plates in Photos

The Watermarkly Blur API automatically detects and blurs faces and license plates in images. It runs entirely on AWS infrastructure and prioritizes privacy - your files are never used to train AI models. We use AWS Lambda to process thousands of requests in parallel, ensuring reliable performance and availability in multiple regions worldwide.

Try For Free

We sell the API through AWS Marketplace. Сost: $0.01 / request. There is an option of free 7 day trial.


Main Features

Automatically detects and blurs license plates and faces in images

Optionally replaces license plates with your project or company logo.

Can resize, crop, or convert processed images.

Supports up to 500 requests per second.

Processes images in parallel for faster performance.

Maximum supported image size: 6000 × 6000 pixels.

API requests require authentication via an API key.

If you need faster processing, support for larger images, or a higher request rate, please contact us at api-support@watermarkly.com.


Output Examples

The woman’s face and the license plate are blurred.

API for blurring faces and license plates on images

The license plate is replaced with the company’s logo, and the woman’s face is blurred.

API for blurring faces and license plates on images

Get API

We sell the API through AWS Marketplace. Сost: $0.01 / request. There is an option of free 7 day trial.


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

API Endpoints

Regions

Currently, we provide the API in two regions:

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.

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
  • Headers:
    • x-api-key: Your API key
  • 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: (HTTP Status: 200) The service returns the processed image in one of the following formats: JPEG, PNG, WEBP.

Error Response: (HTTP Status: 500, 403)

{
  "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: (HTTP Status: 200) The service returns the processed image in one of the following formats: JPEG, PNG, WEBP.

Error Response: (HTTP Status: 500, 403)

{
  "message": "Error message"
}

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);
  }
})();