API Documentation
Integrate image compression into your applications with our REST API.
Quick Start
Get your API Key
Sign up for Pro to get API access
Make your first request
Include your API key in the X-API-Key header
curl -X POST https://api.squish.dev/api/v1/compress/single \
-H "X-API-Key: sq_live_your_key_here" \
-F "image=@photo.jpg"Get compressed image
Response includes base64-encoded compressed image and savings stats
Authentication
All API requests require authentication via the X-API-Key header.
X-API-Key: sq_live_your_api_key_hereKeep your API key secret! Don't expose it in client-side code or public repositories.
Endpoints
/api/v1/compress/singleCompress a single image
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| image | file | Yes | Image file (JPEG, PNG, WebP, AVIF) |
| quality | number | No | Compression quality 1-100 (default: 80) |
| format | string | No | Output format: jpeg, png, webp, avif |
| maxWidth | number | No | Maximum width in pixels |
| maxHeight | number | No | Maximum height in pixels |
Example Request
curl -X POST https://api.squish.dev/api/v1/compress/single \
-H "X-API-Key: sq_live_your_key_here" \
-F "image=@photo.jpg" \
-F "quality=80" \
-F "format=webp"Response
{
"success": true,
"original": { "size": 2457600 },
"compressed": { "size": 312000 },
"savings": "87%",
"image": "base64_encoded_image..."
}/api/v1/compress/bulkCompress multiple images (returns ZIP)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| images | files | Yes | Multiple image files (max 20) |
| quality | number | No | Compression quality 1-100 |
| format | string | No | Output format: jpeg, png, webp, avif |
Example Request
curl -X POST https://api.squish.dev/api/v1/compress/bulk \
-H "X-API-Key: sq_live_your_key_here" \
-F "images=@photo1.jpg" \
-F "images=@photo2.jpg" \
-F "images=@photo3.jpg" \
-F "quality=75"Response
{
"success": true,
"count": 5,
"zip": "base64_encoded_zip..."
}/api/v1/usageGet current usage statistics
Example Request
curl https://api.squish.dev/api/v1/usage \
-H "X-API-Key: sq_live_your_key_here"Response
{
"tier": "pro",
"usage": {
"images": 150,
"bytesSaved": 52428800
},
"limits": {
"maxImages": 2000,
"maxFileSize": 26214400
},
"remaining": 1850
}Which Image Format Should I Use?
Squish supports JPEG, PNG, WebP, and AVIF. Here’s a quick cheat sheet:
| Use this format | Best for | Notes |
|---|---|---|
| webp | Most photos & marketing images | Great balance of size and quality. Widely supported. |
| avif | Performance‑critical pages, hero images | Smallest files; use with fallback if you need legacy support. |
| jpeg | Older browsers, email clients | Safe choice when you can’t rely on modern formats. |
| png | Logos, UI icons, graphics with transparency | Lossless; keep when you need pixel‑perfect edges. |
Want a deeper dive into formats? Read our blog post “Complete Guide to Image Compression”.
Rate Limits
| Tier | Images/Month | Max File Size | CDN Retention | Bulk API |
|---|---|---|---|---|
| Free | 50 | 5 MB | 24 hours | No |
| Pro | 2,000 | 25 MB | 7 days | Yes |
| Team | 10,000 | 50 MB | 30 days | Yes |
| Enterprise | 100,000 | 100 MB | Unlimited | Yes |
Integration Examples
React: Upload & Compress an Image
This example shows how to call the Squish API from a React component using a file input and fetch.
import React, { useState } from 'react';
function SquishUploader() {
const [saving, setSaving] = useState(false);
const [result, setResult] = useState(null);
const handleChange = async (event) => {
const file = event.target.files?.[0];
if (!file) return;
const formData = new FormData();
formData.append('image', file);
formData.append('quality', '80');
formData.append('format', 'webp');
setSaving(true);
try {
const response = await fetch('https://api.squish.dev/api/v1/compress/single', {
method: 'POST',
headers: {
'X-API-Key': 'sq_live_your_key_here',
},
body: formData,
});
const data = await response.json();
setResult(data);
} finally {
setSaving(false);
}
};
return (
<div>
<input type="file" accept="image/*" onChange={handleChange} />
{saving && <p>Compressing...</p>}
{result && (
<div>
<p>Savings: {result.savings}</p>
{/* If you requested base64 output */}
{result.image && (
<img
src={`data:image/webp;base64,${result.image}`}
alt="Compressed"
/>
)}
{/* If you requested URL output (output=url) */}
{result.url && (
<img
src={result.url}
alt="Compressed from CDN"
/>
)}
</div>
)}
</div>
);
}
export default SquishUploader;Node.js / Express: Compress Before Uploading to Your App
Use this pattern in your backend to compress images via Squish before storing them in your own storage or database.
import express from 'express';
import multer from 'multer';
import axios from 'axios';
import FormData from 'form-data';
const app = express();
const upload = multer({ storage: multer.memoryStorage() });
app.post('/upload', upload.single('image'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No image provided' });
}
const form = new FormData();
form.append('image', req.file.buffer, req.file.originalname);
form.append('quality', '80');
form.append('format', 'webp');
form.append('output', 'url'); // get CDN URL instead of base64
try {
const response = await axios.post(
'https://api.squish.dev/api/v1/compress/single',
form,
{
headers: {
'X-API-Key': process.env.SQUISH_API_KEY!,
...form.getHeaders(),
},
}
);
const data = response.data;
// Store data.url (CDN URL) in your database, associate with user, etc.
// await saveImageForUser(req.user.id, data.url);
return res.json({
success: true,
cdnUrl: data.url,
downloadUrl: data.downloadUrl,
savings: data.savings,
});
} catch (err) {
console.error(err);
return res.status(500).json({ error: 'Failed to compress image' });
}
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});