API Documentation
Integrate automatic image optimization into any website or application. Auto-resize images on user upload, convert formats, and compress — in any language.
/api/v1/convertBase URL: https://optimize.robinswebdesign.com
All API requests require an API key passed via the x-api-key header.
| Header | Required | Description |
|---|---|---|
| x-api-key | Required | Your API key from the dashboard |
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
| image | File | Yes | The image file to optimize | - |
| format | string | No | Output format: webp, png, jpeg, avif | webp |
| quality | number | No | Compression quality 1-100 | 80 |
| width | number | No | Output width in pixels | auto |
| height | number | No | Output height in pixels | auto |
| maintainAspectRatio | boolean | No | Preserve aspect ratio when resizing | true |
| removeMetadata | boolean | No | Strip EXIF and metadata | false |
| inline | boolean | No | Return image directly (not JSON) | false |
Successful response (when inline=false):
{
"success": true,
"id": "abc123-def456",
"originalName": "photo.png",
"originalSize": 5242880,
"optimizedSize": 870400,
"compressionPercent": "83.4%",
"width": 1200,
"height": 800,
"originalFormat": "png",
"optimizedFormat": "webp",
"downloadUrl": "/api/download?id=abc123-def456",
"usage": {
"used": 1,
"limit": 10,
"remaining": 9
}
}| Code | HTTP Status | Meaning |
|---|---|---|
| INVALID_API_KEY | 401 | API key is missing or invalid |
| DAILY_LIMIT_REACHED | 429 | Daily conversion limit exceeded |
| FILE_TOO_LARGE | 400 | File exceeds your tier's size limit |
| UNSUPPORTED_FORMAT | 400 | Image format not supported |
| PROCESSING_ERROR | 500 | Image processing failed |
Code Examples in Every Language
Ready-to-use code snippets for every popular backend language. Copy and paste into your project.
curl -X POST https://optimize.robinswebdesign.com/api/v1/convert \
-H "x-api-key: YOUR_API_KEY" \
-F "[email protected]" \
-F "format=webp" \
-F "quality=80" \
-F "width=1200"import { createReadStream } from 'fs'
import FormData from 'form-data'
async function optimizeImage(imagePath) {
const form = new FormData()
form.append('image', createReadStream(imagePath))
form.append('format', 'webp')
form.append('width', '1200')
const res = await fetch(
'https://optimize.robinswebdesign.com/api/v1/convert',
{
method: 'POST',
headers: { 'x-api-key': process.env.IMG_API_KEY },
body: form,
}
)
return res.json()
}import requests
def optimize_image(image_path):
url = "https://optimize.robinswebdesign.com/api/v1/convert"
headers = {"x-api-key": "YOUR_API_KEY"}
with open(image_path, "rb") as f:
files = {"image": f}
data = {"format": "webp", "quality": 80, "width": 1200}
res = requests.post(url, headers=headers, files=files, data=data)
return res.json()
# Auto-resize user uploads in Django/Flask
result = optimize_image("user_upload.png")
print(f"Saved: {result['compressionPercent']}")<?php
function optimizeImage($imagePath) {
$url = "https://optimize.robinswebdesign.com/api/v1/convert";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"x-api-key: YOUR_API_KEY"
]);
$postFields = [
'image' => new CURLFile($imagePath),
'format' => 'webp',
'quality' => '80',
'width' => '1200'
];
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
// WordPress plugin integration
add_action('wp_handle_upload', function($data) {
$optimized = optimizeImage($data['file']);
// Save optimized version
return $data;
});'use server'
export async function optimizeUserImage(formData: FormData) {
formData.append('format', 'webp')
formData.append('quality', '80')
formData.append('width', '1200')
const res = await fetch(
'https://optimize.robinswebdesign.com/api/v1/convert',
{
method: 'POST',
headers: { 'x-api-key': process.env.IMG_API_KEY },
body: formData,
}
)
const result = await res.json()
// Download and save optimized image
const imgRes = await fetch(result.downloadUrl)
const buffer = await imgRes.arrayBuffer()
// Save to your storage (S3, Vercel Blob, etc.)
return result
}<?php
// Add to functions.php - auto-optimize on upload
add_filter('wp_generate_attachment_metadata', function($metadata, $attachment_id) {
$file = get_attached_file($attachment_id);
$response = wp_remote_post(
'https://optimize.robinswebdesign.com/api/v1/convert',
[
'headers' => ['x-api-key' => 'YOUR_API_KEY'],
'body' => [
'image' => new CURLFile($file),
'format' => 'webp',
'width' => '1920',
],
]
);
if (!is_wp_error($response)) {
$data = json_decode($response['body'], true);
// Download optimized version
$optimized = file_get_contents(
'https://optimize.robinswebdesign.com' . $data['downloadUrl']
);
$webp_path = preg_replace('/.[^.]+$/', '.webp', $file);
file_put_contents($webp_path, $optimized);
}
return $metadata;
}, 10, 2);require 'net/http'
require 'uri'
def optimize_image(image_path)
uri = URI('https://optimize.robinswebdesign.com/api/v1/convert')
request = Net::HTTP::Post.new(uri)
request['x-api-key'] = 'YOUR_API_KEY'
form_data = [
['image', File.open(image_path)],
['format', 'webp'],
['quality', '80'],
['width', '1200']
]
request.set_form(form_data, 'multipart/form-data')
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
JSON.parse(response.body)
end
# Rails callback for Active Storage
class ImageOptimizer
def self.after_upload(blob)
result = optimize_image(blob.service.path_for(blob.key))
Rails.logger.info "Saved: #{result['compressionPercent']}"
end
endpackage main
import (
"bytes"
"encoding/json"
"io"
"mime/multipart"
"net/http"
"os"
)
func optimizeImage(imagePath string) (map[string]interface{}, error) {
var buf bytes.Buffer
writer := multipart.NewWriter(&buf)
file, _ := os.Open(imagePath)
defer file.Close()
part, _ := writer.CreateFormFile("image", "photo.png")
io.Copy(part, file)
writer.WriteField("format", "webp")
writer.WriteField("quality", "80")
writer.WriteField("width", "1200")
writer.Close()
req, _ := http.NewRequest("POST",
"https://optimize.robinswebdesign.com/api/v1/convert",
&buf)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("x-api-key", "YOUR_API_KEY")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}10
conversions / day
300 / month
Max file: 5MB
1 concurrent job
$0
500
conversions / day
15,000 / month
Max file: 20MB
5 concurrent jobs
Coming Soon
5,000
conversions / day
150,000 / month
Max file: 100MB
20 concurrent jobs
Coming Soon
Use the <picture> element for maximum compatibility
<picture> <source srcset="image.webp" type="image/webp"> <source srcset="image.avif" type="image/avif"> <img src="image.jpg" alt="Fallback"> </picture>
Auto-resize on blog post upload (Next.js)
In your Next.js API route or Server Action, when a user uploads a blog image, forward it to our API with width=1200 and format=webp. Save the optimized version to your storage. Your blog images will always be perfectly sized.
Cache optimized images on your CDN
Our download URLs support Cache-Control headers. Set up your CDN to cache optimized images for maximum performance. Files are available for 30 minutes.