PDF Compression API Guide: Reduce PDF Size Programmatically
Integrate PDF compression into your application using AllPDFMagic API. Python and Node.js code examples, batch compression, async processing, and production error handling.
PDF Compression API Guide: Reduce PDF Size Programmatically
Compressing PDFs at scale — thumbnailing uploads, optimising downloads, reducing storage costs — requires an API rather than a manual tool. This guide covers how to integrate PDF compression into your application using AllPDFMagic's API and common patterns for production use.
When You Need a Compression API
- User upload pipelines: Compress PDFs as users upload them to reduce storage costs
- Email delivery systems: Compress attachments before sending to stay under size limits
- Document management systems: Optimise stored PDFs retroactively to reduce storage costs
- Mobile apps: Compress PDFs before sending over mobile networks
- Print workflows: Ensure PDFs don't exceed print service size limits
AllPDFMagic Compression API
Endpoint: POST https://api.allpdfmagic.com/v1/pdf/compress
Authentication: X-API-Key: your_api_key header
Basic Python example:
import requests
API_KEY = "your_api_key"
def compress_pdf(input_path: str, output_path: str, quality: str = "balanced") -> dict:
with open(input_path, "rb") as f:
response = requests.post(
"https://api.allpdfmagic.com/v1/pdf/compress",
headers={"X-API-Key": API_KEY},
files={"file": f},
data={"quality": quality} # "low", "balanced", "high"
)
response.raise_for_status()
with open(output_path, "wb") as out:
out.write(response.content)
original_size = os.path.getsize(input_path)
compressed_size = os.path.getsize(output_path)
reduction = (1 - compressed_size / original_size) * 100
return {
"original_size_kb": original_size // 1024,
"compressed_size_kb": compressed_size // 1024,
"reduction_percent": round(reduction, 1)
}
result = compress_pdf("large_report.pdf", "compressed_report.pdf")
print(f"Reduced by {result['reduction_percent']}%")
Quality Levels
| Quality Parameter | DPI | Image Compression | Best For |
|---|---|---|---|
"high" | 150 DPI | Light | Documents that will be printed |
"balanced" | 100 DPI | Medium | Email sharing, web download (default) |
"low" | 72 DPI | Aggressive | Mobile viewing, preview thumbnails |
Node.js Integration
const fs = require("fs");
const FormData = require("form-data");
const axios = require("axios");
async function compressPDF(inputPath, outputPath, quality = "balanced") {
const form = new FormData();
form.append("file", fs.createReadStream(inputPath));
form.append("quality", quality);
const response = await axios.post(
"https://api.allpdfmagic.com/v1/pdf/compress",
form,
{
headers: { ...form.getHeaders(), "X-API-Key": process.env.PDF_API_KEY },
responseType: "arraybuffer",
}
);
fs.writeFileSync(outputPath, response.data);
const originalSize = fs.statSync(inputPath).size;
const compressedSize = fs.statSync(outputPath).size;
const reduction = ((1 - compressedSize / originalSize) * 100).toFixed(1);
console.log(`Compressed: ${reduction}% reduction`);
}
Batch Compression
For compressing multiple PDFs efficiently:
import asyncio
import aiohttp
import aiofiles
API_KEY = "your_api_key"
async def compress_pdf_async(session, pdf_path: str) -> tuple[str, float]:
async with aiofiles.open(pdf_path, "rb") as f:
content = await f.read()
data = aiohttp.FormData()
data.add_field("file", content, filename=pdf_path, content_type="application/pdf")
data.add_field("quality", "balanced")
async with session.post(
"https://api.allpdfmagic.com/v1/pdf/compress",
data=data,
headers={"X-API-Key": API_KEY}
) as response:
result = await response.read()
output_path = pdf_path.replace(".pdf", "_compressed.pdf")
async with aiofiles.open(output_path, "wb") as f:
await f.write(result)
reduction = (1 - len(result) / len(content)) * 100
return output_path, reduction
async def compress_batch(pdf_paths: list[str]):
async with aiohttp.ClientSession() as session:
tasks = [compress_pdf_async(session, p) for p in pdf_paths]
results = await asyncio.gather(*tasks)
for path, reduction in results:
print(f"{path}: {reduction:.1f}% reduction")
# Process 20 PDFs concurrently
pdf_list = ["doc1.pdf", "doc2.pdf", ...]
asyncio.run(compress_batch(pdf_list))
Error Handling in Production
from typing import Optional
import time
def compress_with_retry(
input_path: str,
output_path: str,
max_retries: int = 3,
quality: str = "balanced"
) -> Optional[dict]:
for attempt in range(max_retries):
try:
result = compress_pdf(input_path, output_path, quality)
return result
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429: # Rate limit
wait = 2 ** attempt # Exponential backoff
time.sleep(wait)
elif e.response.status_code == 422: # Invalid file
print(f"Invalid PDF: {input_path}")
return None
else:
raise
return None
Frequently Asked Questions
What is the maximum file size for the compression API?
AllPDFMagic API accepts files up to 100MB per request. For larger files, split first using the /v1/pdf/split endpoint, compress each part, then merge.
Does compression affect text searchability? No. PDF compression targets image data only. Text layers remain intact and fully searchable after compression.
Can I compress and then OCR in one pipeline? Yes. Compress → OCR is a common pipeline pattern. Compressing first reduces OCR processing time and cost because smaller images are processed faster.
Related guides:
- Best PDF APIs for Developers 2026 — full API comparison
- Extract Text from PDF with Python — text extraction
- OCR PDF with Python API — OCR integration
Frequently Asked Questions
Three quality levels: "high" (150 DPI, light compression — for documents to be printed), "balanced" (100 DPI, medium — for email sharing), and "low" (72 DPI, aggressive — for mobile viewing or thumbnails).
AllPDFMagic API accepts files up to 100MB per request. For larger files, split first using the /v1/pdf/split endpoint, compress each part, then merge.
No. PDF compression targets image data only. Text layers remain intact and fully searchable after compression.
Use asyncio with aiohttp (Python) or Promise.all with concurrency limiting (Node.js). Limit concurrent requests to 3-5 to stay within rate limits on free/indie plans. See the batch compression example in the guide.