PDF Compression
Reduce PDF file size with configurable compression levels.
PDF Compression
Reduce the file size of generated PDFs with configurable compression levels. Compression can be added to any PDF generation endpoint.
Adding Compression to PDF Generation
Compression is available as an option on all PDF generation endpoints:
POST /v1/pdf/markdownPOST /v1/pdf/htmlPOST /v1/pdf/urlPOST /v1/pdf/template
Compression Options
| Parameter | Type | Default | Description |
|---|---|---|---|
compression.enabled | boolean | false | Enable compression |
compression.level | string | "medium" | Compression level |
Compression Levels
| Level | Description | Typical Reduction | Quality |
|---|---|---|---|
none | No compression | 0% | Original |
low | Light compression | 10-20% | Excellent |
medium | Balanced compression | 30-50% | Very good |
high | Maximum compression | 50-70% | Good |
Code Examples
curl -X POST https://api.pdfapi.dev/v1/pdf/markdown \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Large Document\n\nThis document contains lots of content...",
"options": {
"format": "A4",
"compression": {
"enabled": true,
"level": "medium"
}
}
}' \
--output compressed.pdf
const response = await fetch('https://api.pdfapi.dev/v1/pdf/html', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PDFAPI_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
html: '<html><body><h1>Invoice</h1>...</body></html>',
options: {
format: 'A4',
compression: {
enabled: true,
level: 'high'
}
}
}),
});
const buffer = await response.arrayBuffer();
console.log(`Compressed PDF size: ${buffer.byteLength} bytes`);
import requests
import os
response = requests.post(
'https://api.pdfapi.dev/v1/pdf/url',
headers={
'Authorization': f'Bearer {os.environ["PDFAPI_KEY"]}',
'Content-Type': 'application/json',
},
json={
'url': 'https://example.com/large-page',
'options': {
'format': 'A4',
'full_page': True,
'compression': {
'enabled': True,
'level': 'medium'
}
}
}
)
if response.status_code == 200:
print(f"Original size estimate vs compressed: {len(response.content)} bytes")
with open('compressed.pdf', 'wb') as f:
f.write(response.content)
package main
import (
"bytes"
"encoding/json"
"io"
"net/http"
"os"
)
func main() {
payload := map[string]interface{}{
"markdown": "# Report\n\nContent here...",
"options": map[string]interface{}{
"format": "A4",
"compression": map[string]interface{}{
"enabled": true,
"level": "medium",
},
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.pdfapi.dev/v1/pdf/markdown", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("PDFAPI_KEY"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
pdf, _ := io.ReadAll(resp.Body)
os.WriteFile("compressed.pdf", pdf, 0644)
}
Compression with Templates
Apply compression when generating PDFs from templates:
curl -X POST https://api.pdfapi.dev/v1/pdf/template \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"template": "invoice",
"data": {
"invoice_number": "INV-2025-001",
"items": [...]
},
"options": {
"compression": {
"enabled": true,
"level": "low"
}
}
}' \
--output invoice.pdf
Choosing the Right Level
Low Compression
Best for documents where quality is critical:
- Legal documents
- Contracts
- Certificates
- High-resolution images
Medium Compression
Best balance for most use cases:
- Invoices and receipts
- Reports
- General documentation
- Email attachments
High Compression
Best for minimizing file size:
- Bulk document storage
- Bandwidth-constrained delivery
- Archival purposes
- Mobile-first applications
Response Headers
When compression is enabled, the response includes additional headers:
X-Compression-Level: medium
X-Original-Size: 2456789
X-Compressed-Size: 1234567
X-Compression-Ratio: 49.7%
Notes
- Compression affects images and embedded fonts the most
- Text content is already efficiently stored in PDFs
- Very small PDFs may not benefit significantly from compression
- Compression adds minimal processing time (typically < 1 second)
- The
nonelevel is useful for explicitly disabling default compression