Compress a PDF
A PDF stuffed with high-resolution scans or uncompressed images can balloon to a size no email attachment limit or upload form will accept. This compress PDF API re-encodes images, strips redundant data, and rebuilds the file to be dramatically lighter, without turning text into a blur or images into a smear of artifacts.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The problem oversized PDFs create
A scanned contract at 600 DPI, a report full of unoptimized screenshots, or a design proof exported at print resolution can easily reach tens of megabytes, and that weight causes real friction: bounced emails, slow uploads, storage bills that creep up, and mobile viewers that stall while rendering a single page. Most of that bulk is not the text — it is images embedded at a resolution far beyond what a screen or a standard printout actually needs. This endpoint targets exactly that waste.
How the compression works
You call POST /pdf/compress and the request returns a task_id right away, since the work runs asynchronously. Internally, embedded images are re-encoded at a sensible quality and resolution for on-screen and standard-print use, redundant and unused objects are removed, and the page structure is rebuilt more efficiently. Text stays as text — vector-drawn glyphs are never rasterized or degraded — so a compressed PDF still selects, searches, and prints its text crisply even as the file itself shrinks.
Why PDFs get this heavy in the first place
The PDF format was designed to embed images at their original fidelity so a document would print identically anywhere, and for decades that meant authoring tools defaulted to preserving every pixel a scanner or camera produced. That design choice made sense for archival fidelity, but it means a huge share of everyday PDFs carry images at two or three times the resolution anything will ever display them at. Compression is simply the step of matching resolution to actual use, which is why a well-compressed file can look identical on screen while weighing a fraction as much.
Where it fits in a pipeline
Place this step wherever documents are about to leave your system: right before emailing an attachment, uploading to a portal with a size cap, or archiving thousands of files where storage cost adds up. It also pairs naturally after a scan-to-PDF or merge step, since those operations are exactly where oversized files tend to appear. Because pricing scales with document size, it behaves predictably even across a batch of wildly different file weights.
Delivery, pricing, and status
The compressed file is delivered by a signed webhook, recommended for automation, or a signed link valid for 24 hours; source and output are deleted after the retention window and never used for training. Pricing is $0.041 per request plus $0.003 per megabyte processed, so the cost is transparent and tied directly to the work done. This endpoint is currently in deployment — it is not yet accepting live jobs — and will go live shortly; check the endpoint status before integrating it into a production pipeline.
What you can do with it
Fit an email attachment under a size limit
Shrink a scanned agreement or a report full of screenshots down from tens of megabytes to a size that clears typical email attachment limits, without re-scanning or re-exporting anything.
Speed up document portal uploads
Compress client-submitted PDFs before they hit an upload form with a hard size cap, cutting failed uploads and support tickets caused by oversized files.
Cut long-term storage cost across an archive
Run a batch of legacy scanned documents through compression once, reducing total archive storage significantly while keeping every page fully readable.
Optimize PDFs generated from design or print exports
Compress print-resolution PDF proofs before distributing them for on-screen review, since reviewers only need screen-quality images, not press-ready ones.
FAQ
How do I compress a PDF with an API?
Send the document to POST /pdf/compress, which returns a task_id immediately. The smaller, re-encoded file is delivered to your signed webhook or a signed link once processing finishes.
Is the compress PDF API free?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
Will compression make my text blurry?
No. Text is preserved as vector glyphs and is never rasterized, so it stays sharp, selectable, and searchable. Only embedded images are re-encoded to a sensible quality and resolution.
How much smaller does a PDF actually get?
It depends entirely on the source file: a document dominated by high-resolution scans or uncompressed images shrinks the most, while a text-only PDF with few images sees a smaller reduction since there is less redundant image data to remove.
Can I compress PDFs in bulk?
Yes. Each request is an independent asynchronous task, so you can submit large batches in parallel and collect each compressed result by webhook as it finishes.
Does compression affect image quality noticeably?
Images are re-encoded at a quality appropriate for normal screen viewing and standard printing, which is a level most people cannot distinguish from the original at typical zoom, though pixel-level inspection at extreme zoom may show a difference.
Is this endpoint live right now?
It is in deployment and not yet accepting jobs; it will be live shortly. Check the current endpoint status before wiring it into a production pipeline.
How is the cost calculated for a large batch?
Each request costs a flat $0.041 plus $0.003 per megabyte of the document processed, so total cost scales predictably with the number and size of files in your batch.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/pdf/compress \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"pdf":"https://ejemplo.com/documento.pdf"}'const res = await fetch("https://api.kit.forhosting.com/pdf/compress", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"pdf": "https://ejemplo.com/documento.pdf"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/compress",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"pdf": "https://ejemplo.com/documento.pdf"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/compress", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"pdf":"https://ejemplo.com/documento.pdf"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"pdf":"https://ejemplo.com/documento.pdf"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/compress", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"pdf": "https://ejemplo.com/documento.pdf"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.compress",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
max_pages | 200 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
413 | input_too_large | The file exceeds the size limit. |