# PDF Compressor: Reduce PDF File Size in Bulk (`data-done-right/pdf-compressor`) Actor

PDF compressor API: compress PDF files from URLs in bulk and reduce PDF size by downsampling images with Ghostscript. Presets screen, ebook, printer. Reports bytes saved per file; you pay only for PDFs that shrink.

- **URL**: https://apify.com/data-done-right/pdf-compressor.md
- **Developed by:** [Data Done Right](https://apify.com/data-done-right) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.40 / 1,000 pdf compresseds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## PDF Compressor: Reduce PDF File Size in Bulk

**PDF Compressor** compresses PDF files from URLs in bulk and reduces PDF size by downsampling and re-encoding the images inside them with Ghostscript. Give it a list of PDF links, pick a preset, and get back smaller PDFs with a signed download link, the original and new size in bytes, the percent saved and the method used. You pay only for PDFs that actually got smaller.

Use it as a **PDF compressor API** in a pipeline, to **compress PDF** archives before emailing or storing them, or to **reduce PDF size** for web and mobile.

### Features

- **Real compression, not just repacking.** Scanned or image-heavy PDFs shrink a lot (often 50-90%) because embedded images are downsampled and recompressed. Fonts are subset and duplicate images are merged.
- **Four presets:** `screen` (smallest, about 72 dpi images), `ebook` (balanced, about 150 dpi, default), `printer` (about 300 dpi), `light` (near-lossless, smallest savings).
- **Never makes a file bigger.** If the result is not smaller, you get the original bytes back, `reduced: false` and a note, and you are not charged.
- **Honest numbers per file:** `originalBytes`, `compressedBytes`, `savedPercent`, `method`.
- **Bulk:** hundreds of PDFs per run, processed in parallel; one bad file never stops the batch.
- **Encrypted PDFs:** give the `password`; the output is not encrypted. Without it you get a clear error for that file.
- **Safe caps:** maximum file size, maximum pages per file, and a timeout per file.
- **Dropbox and Google Drive share links** (public files) are converted to direct downloads.

### How to compress PDF files in bulk

1. Paste your PDF links into **PDF URLs** (one per line).
2. Choose a **Compression preset**. Start with `ebook`; use `screen` if you want the smallest file.
3. Run the Actor. Open the **Compressed PDFs** table in the Output tab and click **Download**, or fetch the dataset through the API.

#### Input example

```json
{
  "urls": [
    "https://example.com/reports/annual-report.pdf",
    "https://example.com/scans/contract-scan.pdf"
  ],
  "preset": "ebook",
  "maxFileSizeMb": 50
}
```

#### Output example

```json
{
  "index": 0,
  "status": "ok",
  "sourceUrl": "https://example.com/scans/contract-scan.pdf",
  "fileName": "contract-scan-compressed.pdf",
  "downloadUrl": "https://api.apify.com/v2/key-value-stores/.../records/0000-contract-scan-compressed.pdf?signature=...",
  "reduced": true,
  "originalBytes": 8421337,
  "compressedBytes": 1203455,
  "savedPercent": 85.7,
  "method": "ghostscript /ebook",
  "preset": "ebook",
  "pageCount": 12,
  "note": null,
  "error": null
}
```

A file that could not shrink comes back like this, free of charge:

```json
{ "status": "ok", "reduced": false, "originalBytes": 41233, "compressedBytes": 41233, "savedPercent": 0,
  "method": "ghostscript /ebook (no gain, original kept)",
  "note": "Already well optimized: compression did not make this PDF smaller, so the original file is returned unchanged and you are not charged. ..." }
```

### How to reduce PDF size for email

Most mail servers reject attachments over 10-25 MB. Use the `screen` preset for scans and photo-heavy decks: images drop to about 72 dpi, which is fine on a screen but soft in print. For documents you will print, use `printer` or `light`.

### How to compress an encrypted PDF

Set **PDF password (optional)**. It is applied to every file in the run and is never logged. The compressed copy is written without encryption and the row says so in `note`. If the password is missing or wrong, only that file fails, with a clear message.

### How much does it cost

Pay per event: **$0.008 per PDF that gets smaller** (event `pdf-compressed`, $8 per 1,000). PDFs that cannot be reduced (returned unchanged) and failed files are free. There is no start fee. Platform compute for the run is small: a typical PDF takes a few seconds. A free test run on the default input costs a fraction of a cent.

Set a maximum spend in the run options and the Actor stops cleanly when it is reached.

### FAQ

**How much will my PDF shrink?** It depends on the content. PDFs with large images (scans, photos, slide decks exported at high resolution) often drop 50-90%. PDFs that are mostly text, or were already optimized, shrink little (0-10%) and some cannot shrink at all. Those come back unchanged and free.

**Will the quality suffer?** Text and vector graphics stay sharp. Images are lowered in resolution and quality depending on the preset: `screen` is visibly softer, `ebook` is fine for reading on screen, `printer` and `light` keep print quality.

**What happens if the compressed file is larger than the original?** You get the original file back, `reduced: false` and an explanation, and you are not charged.

**Does it work on password-protected PDFs?** Yes if you provide the password. The output is unencrypted. Permission-only restrictions (no password to open) are handled the same way.

**What are the limits?** Default 50 MB per file (hard maximum 300 MB), 500 pages per file, 180 seconds per file. Files above the limits are reported as errors and not charged. The PDF must be reachable by a plain download link; links that need a login are not supported.

**Which engine is used?** Ghostscript (`-dPDFSETTINGS` presets), followed by an object-stream optimization pass. If Ghostscript cannot process a file, the Actor falls back to a built-in optimizer that recompresses large images as JPEG; the `method` field always tells you which one ran.

### Related tools

- **Extract Zip Files**: unpack ZIP archives full of PDFs before compressing them.
- **PDF to Text & OCR**: extract the text of your PDFs, with OCR for scans.
- **PDF Merger & Splitter**: merge or split PDFs, then compress the result.

# Actor input Schema

## `urls` (type: `array`):

Direct links to the PDF files you want to compress. One URL per line. Dropbox and Google Drive share links work if the file is public. Example: https://example.com/report.pdf

## `preset` (type: `string`):

How hard to compress. screen = smallest file, images at about 72 dpi (good for email and web). ebook = balanced, about 150 dpi (default). printer = about 300 dpi, larger. light = highest image quality, smallest savings. Example: ebook

## `password` (type: `string`):

Password to open encrypted PDFs. The same password is used for every file in the run. Without it, an encrypted PDF is reported as an error. The compressed output is not encrypted. Example: s3cret

## `linearize` (type: `boolean`):

Also optimize the PDF for fast web viewing (linearize). Usually adds a little size. Example: false

## `maxFileSizeMb` (type: `integer`):

Skip PDFs larger than this many megabytes (checked before and during download). Hard maximum 300. Example: 50

## `maxPagesPerFile` (type: `integer`):

Skip PDFs with more pages than this. Example: 500

## `maxFiles` (type: `integer`):

Process at most this many URLs from the list. Example: 100

## `timeoutSecs` (type: `integer`):

Stop compressing a single PDF after this many seconds. Example: 180

## `maxConcurrency` (type: `integer`):

How many PDFs to process at the same time (1-6). Example: 2

## `outputStoreName` (type: `string`):

Save compressed PDFs in a named key-value store that is kept until you delete it, instead of the run's default store. Example: my-compressed-pdfs

## `proxyConfiguration` (type: `object`):

Optional proxy for downloading the PDFs (only needed if the host blocks datacenter IPs). Example: {"useApifyProxy": true}

## Actor input object example

```json
{
  "urls": [
    "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
  ],
  "preset": "ebook",
  "linearize": false,
  "maxFileSizeMb": 50,
  "maxPagesPerFile": 500,
  "maxFiles": 1000,
  "timeoutSecs": 180,
  "maxConcurrency": 2
}
```

# Actor output Schema

## `results` (type: `string`):

All result items of this run (the default dataset), as JSON, CSV, Excel and more.

## `records` (type: `string`):

Key-value store records: the run summary, notes on any problems, and any files.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("data-done-right/pdf-compressor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": ["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"] }

# Run the Actor and wait for it to finish
run = client.actor("data-done-right/pdf-compressor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
  ]
}' |
apify call data-done-right/pdf-compressor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,data-done-right/pdf-compressor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/hslyqOyd5Ouj7LAhp/builds/abrnycncWYF3xr1PF/openapi.json
