Image Blur API Documentation
Overview
The Image Blur API provides automated detection and blurring of 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.
Features
- Supports up to 10 requests per second.
- Processes images in parallel for faster performance.
- A single 12MP image takes approximately 1.6 seconds to process.
- 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.
API Endpoints
Process Image
POST https://blur-api.watermarkly.com/v1/
Initiates the blurring process for an uploaded image.
Request
- Method:
POST
- Content-Type:
application/octet-stream
- Headers:
x-api-key
: Your API key
- Query Parameters:
intensity
: (Optional) A float value between 0.0 and 20.0 that adjusts blur intensity. Default:1.0
. Passing0.0
disables blurring.file_size
: (Optional) Specifies the desired output file size in bytes. The service will attempt to return an image that does not exceed this size.resize
: (Optional) Specifies the desired output image size inwidth,height
format. If the proportions differ from the original, cropping will be applied.
Response
Success Response:
{
"task_id": "cc6f1ca1-8c8a-4dec-b68b-b5554b4584f1.jpeg"
}
Error Response:
{
"message": "Error message"
}
Retrieve Processed Image
GET https://blur-api.watermarkly.com/v1/{task_id}
Retrieves the processed image using the task ID from the previous POST request.
Request
- Method: GET
- URL Parameters:
- task_id: The task identifier received from the process image endpoint
Response
- Status Code 202: Task is still processing
- Status Code 200: Processing complete, returns the processed image in the original file format
- Content-Type: Same as input image format
Processing Details
- Processed images are removed within 30 seconds after download
- The output image maintains the same file format as the input
- Maximum image size is 20Mb or 6000x6000 pixels
- Maximum number of parallel requests: 10
- Maximum number of requests per second: 10
- Maximum number of requests per day: 100,000
Security and Privacy
- POST API requests require authentication via API key
- Do not provide API key to GET requests to avoid double charging
- Customer files are not used for AI model training
- Data processing occurs on AWS infrastructure located in Sweden
Code Examples
Python
import requests
import time
API_KEY = 'your_api_key'
API_URL = 'https://blur-api.watermarkly.com/v1/'
def blur_image(input_path: str | Path, output_path: str | Path):
with requests.Session() as session:
headers = {'x-api-key': API_KEY, 'Content-Type': 'image/jpeg', 'Accept': 'application/json'}
with open(input_path, 'rb') as image_file:
response = session.post(API_URL,
headers=headers,
data=image_file)
if response.status_code == 429:
print(f'API rate limit exceeded (post)')
time.sleep(0.1)
response = session.post(API_URL, headers=headers, data=image_file)
if response.status_code != 200:
raise Exception(f'Failed to create task for {input_path}, got status code {response.status_code}')
task = response.json()
task_id = task['task_id']
while True:
response = session.get(f'{API_URL}{task_id}')
if response.status_code == 200:
# Save processed image
with open(output_path, 'wb') as f:
f.write(response.content)
break
elif response.status_code == 202 or response.status_code == 429:
# Task still processing, wait 200ms before next attempt not to cause request throttling
time.sleep(0.2)
continue
else:
raise Exception(f'Failed to retrieve processed image: {response.status_code}')
blur_image("input.jpg", "output.jpg")
NodeJS
const {createWriteStream, createReadStream} = require('node:fs');
const {Readable} = require("node:stream");
const API_KEY = 'your_api_key';
const API_URL = 'https://blur-api.watermarkly.com/v1/';
async function processImage(inputPath, outputPath) {
// Upload image for processing
const processResponse = await fetch(API_URL, {
method: 'POST',
headers: {
'x-api-key': API_KEY,
'Content-Type': 'image/jpeg',
'Accept': 'application/json'
},
body: Readable.toWeb(createReadStream(inputPath)),
duplex: 'half',
});
if (!processResponse.ok)
throw new Error("Processing API isn't available");
const task = await processResponse.json();
// Poll for processed image
for (let attempt = 0, delay = 200; attempt < 50; attempt++) {
const retrieveResponse = await fetch(`${API_URL}${task.task_id}`);
if (retrieveResponse.status === 200) {
// Create a write stream for the output file
await Readable.fromWeb(retrieveResponse.body)
.pipe(createWriteStream(outputPath));
break;
} else if (retrieveResponse.status === 202 || retrieveResponse.status === 429) {
// Wait 200ms before next attempt not to cause request throttling
await new Promise(resolve => setTimeout(resolve, delay));
delay += 50;
} else {
throw new Error(`Failed to retrieve processed image: ${retrieveResponse.status}`);
}
}
}
// Usage
processImage('image.jpg', 'processed_image.jpg').catch(console.error);