API documentation
Integrate image optimization directly into your application with a simple REST API call.
Authentication
All API calls require a valid API key. Send the key via the X-API-Key header or as the api_key query parameter.
Contact us to get an API key.
# Via header (recommended)
curl -H "X-API-Key: YOUR_API_KEY" ...
# Via query parameter
curl "...?api_key=YOUR_API_KEY"
curl -H "X-API-Key: YOUR_API_KEY" ...
# Via query parameter
curl "...?api_key=YOUR_API_KEY"
POST /api/v1/optimize
Optimize an image and optionally convert it to another format. Returns the optimized image directly.
Parameters
| Parameter | Type | Description |
|---|---|---|
image Required |
File | The image file to optimize. Max 2 MB (can be raised per API key) and max 2000×2000 pixels (does not apply to SVG). Formats: JPEG, PNG, WebP, GIF, AVIF, BMP, TIFF, SVG. |
output_format Optional |
String | Convert the image to this format. Values: jpg, png, webp, gif, avif. If omitted, the original format is kept. |
ratio Optional |
String | Max size in the format WIDTHxHEIGHT (e.g. 1000x1000). The image is scaled to fit inside the box, keeps the aspect ratio, and is never scaled up. |
quality Optional |
Integer 1–10 | How aggressive the compression is. 10 (default) = maximum compression with all lossy passes. 1 = lossless re-encoding only (~10% of max compression, no quality loss). Intermediate values filter out lossy passes below a quality threshold. |
response Optional |
String | Set to json to get a JSON response with metadata and a download link instead of the image directly. |
Response (binary / default)
The image is returned directly with the correct Content-Type. Extra metadata is in the headers:
| Header | Meaning |
|---|---|
X-Original-Size | Original image size in bytes |
X-Optimized-Size | Optimized file size in bytes |
X-Savings-Percent | Savings in percent |
Response (JSON)
If response=json is sent. NOTE: the file behind download_url is deleted right after the first download, or after the retention time (default 10 minutes).
{
"success": true,
"original_size": 245832,
"optimized_size": 98412,
"savings_percent": 59.9,
"output_format": "webp",
"mime_type": "image/webp",
"download_url": "/download.php?id=abc123...",
"expires_at": "2025-01-15 14:30:00"
}
"success": true,
"original_size": 245832,
"optimized_size": 98412,
"savings_percent": 59.9,
"output_format": "webp",
"mime_type": "image/webp",
"download_url": "/download.php?id=abc123...",
"expires_at": "2025-01-15 14:30:00"
}
Code examples
cURL
# Optimize a PNG image (returns the image directly)
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-F "image=@min-bild.png" \
--output optimerad.png \
https://img.klema.se/api/v1/optimize
# Convert JPEG to WebP
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-F "image=@foto.jpg" \
-F "output_format=webp" \
--output foto.webp \
https://img.klema.se/api/v1/optimize
# Scale to max 1000x1000 and conservative compression (quality=3)
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-F "image=@foto.jpg" \
-F "ratio=1000x1000" \
-F "quality=3" \
--output foto.jpg \
https://img.klema.se/api/v1/optimize
# Get a JSON response with metadata
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-F "image=@min-bild.png" \
-F "response=json" \
https://img.klema.se/api/v1/optimize
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-F "image=@min-bild.png" \
--output optimerad.png \
https://img.klema.se/api/v1/optimize
# Convert JPEG to WebP
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-F "image=@foto.jpg" \
-F "output_format=webp" \
--output foto.webp \
https://img.klema.se/api/v1/optimize
# Scale to max 1000x1000 and conservative compression (quality=3)
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-F "image=@foto.jpg" \
-F "ratio=1000x1000" \
-F "quality=3" \
--output foto.jpg \
https://img.klema.se/api/v1/optimize
# Get a JSON response with metadata
curl -X POST \
-H "X-API-Key: YOUR_API_KEY" \
-F "image=@min-bild.png" \
-F "response=json" \
https://img.klema.se/api/v1/optimize
Python
import requests
# Optimize and download
response = requests.post(
"https://img.klema.se/api/v1/optimize",
headers={"X-API-Key": "YOUR_API_KEY"},
files={"image": open("bild.png", "rb")},
data={"output_format": "webp"}
)
with open("optimerad.webp", "wb") as f:
f.write(response.content)
print(f"Savings: {response.headers['X-Savings-Percent']}%")
# Optimize and download
response = requests.post(
"https://img.klema.se/api/v1/optimize",
headers={"X-API-Key": "YOUR_API_KEY"},
files={"image": open("bild.png", "rb")},
data={"output_format": "webp"}
)
with open("optimerad.webp", "wb") as f:
f.write(response.content)
print(f"Savings: {response.headers['X-Savings-Percent']}%")
JavaScript (Node.js)
const fs = require('fs');
const FormData = require('form-data');
const form = new FormData();
form.append('image', fs.createReadStream('bild.jpg'));
form.append('output_format', 'webp');
form.append('response', 'json');
const res = await fetch('https://img.klema.se/api/v1/optimize', {
method: 'POST',
headers: { 'X-API-Key': 'YOUR_API_KEY' },
body: form
});
const data = await res.json();
console.log(`Savings: ${data.savings_percent}%`);
const FormData = require('form-data');
const form = new FormData();
form.append('image', fs.createReadStream('bild.jpg'));
form.append('output_format', 'webp');
form.append('response', 'json');
const res = await fetch('https://img.klema.se/api/v1/optimize', {
method: 'POST',
headers: { 'X-API-Key': 'YOUR_API_KEY' },
body: form
});
const data = await res.json();
console.log(`Savings: ${data.savings_percent}%`);
PHP
$ch = curl_init('https://img.klema.se/api/v1/optimize');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
CURLOPT_POSTFIELDS => [
'image' => new CURLFile('bild.png'),
'output_format' => 'webp',
],
]);
$result = curl_exec($ch);
file_put_contents('optimerad.webp', $result);
curl_close($ch);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY'],
CURLOPT_POSTFIELDS => [
'image' => new CURLFile('bild.png'),
'output_format' => 'webp',
],
]);
$result = curl_exec($ch);
file_put_contents('optimerad.webp', $result);
curl_close($ch);
Error codes
| HTTP code | Meaning |
|---|---|
400 | Bad request – missing image, invalid format, etc. |
401 | Invalid or missing API key. |
403 | The API is disabled. |
405 | Wrong HTTP method (use POST). |
500 | Server error during optimization. |
// Error responses are always returned as JSON
{
"error": "Invalid or missing API key."
}
{
"error": "Invalid or missing API key."
}
Supported formats
| Format | Input | Output |
|---|---|---|
JPEG | Yes | Yes |
PNG | Yes | Yes |
WebP | Yes | Yes |
GIF | Yes | Yes |
AVIF | Yes | Yes |
BMP | Yes | No |
TIFF | Yes | No |
SVG | Yes | No |