PDF Compressor API
Pricing
from $0.002 / actor start
PDF Compressor API
Compress a PDF from a URL or file upload and save the result to the run's key-value store.
Pricing
from $0.002 / actor start
Rating
0.0
(0)
Developer
Leo Yan
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
PDF Compressor
Compress a PDF from a public URL or a file upload. Files up to 256 MB are supported. The
compressed PDF is written to the run's default key-value store, together with a machine-readable
OUTPUT record.
The Actor uses an enterprise-grade PDF compression engine to remove redundant objects and recompress images while keeping the document readable. It is intended to be called through the Apify API or from Apify Console.
Input
| Field | Type | Default | Description |
|---|---|---|---|
url | string | sample GeoTopo PDF | Public HTTP(S) URL of the PDF. |
fileUpload | string | - | Uploaded PDF or Apify key-value store record URL. Takes precedence over url. |
compressionLevel | string | recommended | low, recommended, or extreme. |
Compression levels
| Level | Image resolution | JPEG quality | Best for |
|---|---|---|---|
low | 300 DPI | 90 | Print quality, scans, documents with fine detail |
recommended | 150 DPI | 75 | General web and email use |
extreme | 96 DPI | 50 | The smallest possible file, image-heavy PDFs |
If the compressor cannot make the PDF smaller, the original PDF is returned unchanged under the
_compress.pdf name. Password-protected PDFs are rejected because their content cannot be
optimized.
Output
For an input named input.pdf, the compressed file is stored in the run's default key-value
store under input_compress.pdf with content type application/pdf.
When the run finishes, the Output tab in Apify Console lists the compressed PDF and links to
the OUTPUT record. These links are defined in .actor/output_schema.json.
An OUTPUT JSON record describes the result:
{"success": true,"message": "Compressed 5.1 MB to 1.7 MB (66.5% smaller).","input": {"source": "https://example.com/GeoTopo.pdf","filename": "GeoTopo.pdf","bytes": 5321132,"mb": "5.1 MB"},"output": {"key": "GeoTopo_compress.pdf","filename": "GeoTopo_compress.pdf","contentType": "application/pdf","bytes": 1783266,"mb": "1.7 MB","compressionRatio": 0.335,"savedPercent": 66.5,"downloadUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/GeoTopo_compress.pdf?signature=..."},"compressionLevel": "recommended","pricing": {"eventName": "pdf-mb","unitPriceUsd": 0.001,"chargedEvents": 6,"estimatedCostUsd": 0.006,"charged": true,"actorStart": {"eventName": "apify-actor-start","unitPriceUsd": 0.002,"events": 1,"estimatedCostUsd": 0.002,"chargedAutomatically": true},"estimatedTotalCostUsd": 0.008},"limits": {"memoryMb": 512,"maxMemoryMb": 512,"diskMb": 1024,"maxInputBytes": 268435456,"maxInputMb": 256}}
On failure, success is false, error.code identifies the problem, and error.message
contains a user-facing explanation. The OUTPUT record is written for both successful and
failed runs.
Filename rules
input.pdf->input_compress.pdfreport.PDF->report_compress.PDFreport->report_compress.pdf
Only PDF input is accepted. The URL does not need to end in .pdf; the downloaded content is
checked for a PDF header, and non-PDF content is rejected with NOT_A_PDF before compression
starts.
Filenames are sanitized before use with a cross-platform filename cleaner. Directory components are
removed, characters that are invalid in filenames are stripped, reserved device names are defused,
and trailing dots or spaces are removed. The remaining name is then normalized to letters, digits,
., _, and -, and truncated to a safe length. For example, hello world.pdf becomes
hello_world_compress.pdf.
Pricing
The Actor uses pay-per-event (PPE) pricing with two charges.
Per-run fee
Apify charges the synthetic apify-actor-start event automatically at $0.002 per start
($2 per 1,000 runs). It applies to every run, including runs that later fail, and is not
charged by the Actor code.
The event is charged once for every run. Because the Actor's memory is fixed at 512 MB, each run incurs exactly one start event ($0.002).
Per-MB fee
The Actor charges the event pdf-mb once per started megabyte of the input file, at
$0.001 per event:
- 1 byte to 1 MB -> 1 event -> $0.001
- 5.1 MB -> 6 events -> $0.006
- 128 MB -> 128 events -> $0.128
- 256 MB -> 256 events -> $0.256
This event is charged only after the compressed PDF has been saved to the key-value store. Failed
runs, including oversized inputs, are not charged for pdf-mb.
Total cost
| Input | Start fee | pdf-mb | Total |
|---|---|---|---|
| 1 byte to 1 MB | $0.002 | $0.001 | $0.003 |
| 5.1 MB | $0.002 | $0.006 | $0.008 |
| 128 MB | $0.002 | $0.128 | $0.130 |
| 256 MB | $0.002 | $0.256 | $0.258 |
The pricing object in OUTPUT reports both the pdf-mb charge and the automatic start fee.
Size limits
The Actor runs with 512 MB of memory and 1 GB of disk (Apify gives each run disk space equal to twice its memory). To leave headroom for the compression engine and the output file, the input limit is half the memory:
max input size = memory / 2 = 256 MB
| Memory | Disk | Maximum input |
|---|---|---|
| 512 MB (fixed) | 1 GB | 256 MB |
The Actor checks the remote Content-Length before downloading. If the server does not report a
size, the same limit is enforced while streaming the download. An oversized file produces an
OUTPUT record with error.code = "FILE_TOO_LARGE" and no pdf-mb charge.
Files larger than 256 MB cannot be processed by this Actor; split them into smaller PDFs before uploading. The default run timeout is 10 minutes.
Calling the API
Start an asynchronous run:
curl -X POST "https://api.apify.com/v2/acts/OWNER~pdf-compress-api/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"url": "https://raw.githubusercontent.com/py-pdf/sample-files/main/009-pdflatex-geotopo/GeoTopo.pdf","compressionLevel": "recommended"}'
The response contains data.id, data.defaultKeyValueStoreId, and data.status. Poll the run,
then read the metadata and download the result:
curl "https://api.apify.com/v2/actor-runs/RUN_ID?token=$APIFY_TOKEN"curl "https://api.apify.com/v2/key-value-stores/STORE_ID/records/OUTPUT?token=$APIFY_TOKEN"curl -OJ "https://api.apify.com/v2/key-value-stores/STORE_ID/records/GeoTopo_compress.pdf?token=$APIFY_TOKEN"
Synchronous call (waits for the run to finish):
curl -X POST "https://api.apify.com/v2/acts/OWNER~pdf-compress-api/run-sync?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"url":"https://example.com/input.pdf"}'
Uploading a file is also supported. Upload the PDF to a key-value store, then pass the record URL
as fileUpload:
curl -X POST "https://api.apify.com/v2/acts/OWNER~pdf-compress-api/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"fileUpload": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/input.pdf","compressionLevel": "extreme"}'
Error codes
| Code | Meaning |
|---|---|
INVALID_INPUT | Missing/invalid URL, unsupported scheme, or invalid compression level. |
DOWNLOAD_FAILED | The source could not be downloaded (DNS, TLS, HTTP 4xx/5xx, timeout). |
EMPTY_FILE | The source returned an empty file. |
NOT_A_PDF | The file is not a valid PDF or has no readable pages. |
PASSWORD_PROTECTED | The PDF is encrypted and needs a password. |
COMPRESSION_FAILED | The compressor could not optimize the document. |
UPLOAD_FAILED | The result could not be written to the key-value store. |
FILE_TOO_LARGE | The input exceeds the run's memory-derived limit. |
TEMP_DIR_FAILED | The run could not create a temporary directory. |