# PDF Tools (Merge / Split / Compress / OCR / Watermark) (`mrkrokko/pdf-tools`) Actor

All-in-one PDF processor: merge multiple PDFs, split by page ranges, compress file size, extract text, OCR scanned documents (Tesseract), add text watermarks, rotate pages, and read metadata. Accepts PDF URLs or Key-Value Store keys.

- **URL**: https://apify.com/mrkrokko/pdf-tools.md
- **Developed by:** [Alex O](https://apify.com/mrkrokko) (community)
- **Categories:** Automation, E-commerce, Other
- **Stats:** 2 total users, 0 monthly users, 33.3% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 results

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

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## PDF Tools

All-in-one PDF processing Actor for the Apify platform. Merge, split, compress, extract text, OCR scanned documents, add watermarks, rotate pages, and read metadata — all from simple PDF URL inputs. No coding required.

### What is PDF Tools?

PDF Tools is a serverless PDF processor that runs entirely on the [Apify platform](https://apify.com). It accepts one or more direct-download PDF URLs and performs the operation you select. Results are stored in the run's [dataset](https://docs.apify.com/sdk/python/docs/concepts/storages#working-with-datasets) (structured JSON) and [key-value store](https://docs.apify.com/sdk/python/docs/concepts/storages#working-with-key-value-stores) (binary PDF/TXT files).

**Supported operations:**

- **Merge** — Combine multiple PDFs into a single document
- **Split** — Split a PDF by page ranges (individual pages or custom groups)
- **Compress** — Reduce file size with 3 compression levels (low / medium / high)
- **Extract Text** — Extract embedded text from PDF pages
- **OCR** — OCR scanned or image-based PDFs using Tesseract (6 languages pre-installed)
- **Watermark** — Add a customizable diagonal text watermark to every page
- **Rotate** — Rotate pages by 90°, 180°, or 270°
- **Metadata** — Read PDF metadata (title, author, creator, dates, page sizes)
- **Page Count** — Quick page count without full processing

### What can PDF Tools be used for?

- **Document automation** — Extract text from invoices, contracts, or reports for downstream processing
- **Bulk PDF processing** — Compress hundreds of PDFs to reduce storage costs
- **Archival workflows** — Add "CONFIDENTIAL" or "DRAFT" watermarks to sensitive documents
- **OCR pipelines** — Convert scanned documents to searchable text (supports English, German, French, Spanish, Italian, Portuguese)
- **Page management** — Split large documents into chapters or merge individual pages into one PDF
- **Data extraction** — Read metadata and page counts from PDF files at scale
- **Integration with AI agents** — Use as a tool in agentic workflows via Apify's [MCP integration](https://docs.apify.com/platform/integrations/mcp)

### How to use PDF Tools

1. Go to the PDF Tools [Input tab](https://console.apify.com/actors/oyjy3FcHWqW3puVYc/input)
2. Select the **Operation** you want to perform
3. Add one or more **PDF file URLs** (direct-download links ending in `.pdf`)
4. Configure any optional settings (page ranges, compression level, watermark text, etc.)
5. Click **Start** and wait for the run to complete
6. Download results from the **Dataset** tab (JSON) or **Key-Value Store** tab (PDF/TXT files)

### Input

The Actor accepts the following input fields. For a full technical reference, see the [Input tab](https://console.apify.com/actors/oyjy3FcHWqW3puVYc/input).

#### Operation (required)

Choose which PDF operation to perform: `merge`, `split`, `compress`, `extractText`, `ocr`, `watermark`, `rotate`, `metadata`, or `pageCount`.

#### PDF file URLs (required)

A list of direct-download URLs to PDF files. For the **merge** operation, the order matters — PDFs are combined in the order listed.

#### Page ranges (optional)

Comma-separated page ranges (1-indexed), e.g. `1-3,5,8-10`. Used by **split**, **extractText**, **ocr**, and **rotate** to target specific pages. If omitted, all pages are processed.

For the **split** operation, use semicolons to create separate output groups: `1-2;3-4;5` produces three separate PDFs.

#### Compression settings (optional)

Choose a compression level for the **compress** operation:

- **Low** — Strips metadata, removes unreferenced objects (lossless)
- **Medium** — Additionally recompresses internal streams using Flate compression
- **High** — Aggressive: linearizes the PDF and applies maximum stream recompression

#### Watermark settings (optional)

Configure the text watermark for the **watermark** operation:

- **Watermark text** — The text to overlay (default: `CONFIDENTIAL`)
- **Opacity** — 0.01 (barely visible) to 1.0 (fully opaque), default: 0.15
- **Font size** — 10 to 200 points, default: 60
- **Angle** — Rotation in degrees (0–360°), default: 45°

#### Rotation angle (optional)

Clockwise rotation for the **rotate** operation: `90`, `180`, or `270` degrees.

#### OCR languages (optional)

Tesseract language codes for the **ocr** operation. Pre-installed packs:

| Code | Language |
|---|---|
| `eng` | English |
| `deu` | German |
| `fra` | French |
| `spa` | Spanish |
| `ita` | Italian |
| `por` | Portuguese |

Combine multiple languages with `+`, e.g. `eng+deu`.

#### Output file name (optional)

Base name for the output file saved to the key-value store (without extension). If omitted, a name is generated automatically based on the operation.

### Output

#### Dataset (structured JSON)

Every run pushes one record per processed PDF to the default [dataset](https://docs.apify.com/platform/actors/running/output#dataset). Each record includes:

```json
{
    "operation": "compress",
    "inputFile": "https://example.com/file.pdf",
    "outputKey": "compressed_1.pdf",
    "pageCount": 3,
    "fileSizeKb": 41.3,
    "originalSizeKb": 48.5,
    "reductionPercent": 14.8,
    "status": "OK",
    "error": null
}
````

Additional fields are included depending on the operation:

| Operation | Additional fields |
|---|---|
| **extractText / ocr** | `totalChars`, `pages` (array with per-page `text` and `charCount`) |
| **compress** | `originalSizeKb`, `reductionPercent` |
| **watermark** | `watermarkText` |
| **rotate** | `rotateAngle` |
| **metadata** | `title`, `author`, `creator`, `creationDate`, `modificationDate`, `pageSizes` |

#### Key-Value Store (binary files)

Operations that produce new PDFs (**merge**, **split**, **compress**, **watermark**, **rotate**) save the resulting files to the default [key-value store](https://docs.apify.com/platform/actors/running/output#key-value-store). Text extraction and OCR save `.txt` files.

Access output files via the Apify API:

```
https://api.apify.com/v2/key-value-stores/{storeId}/records/{outputKey}
```

### Examples

#### Count pages

```json
{
    "operation": "pageCount",
    "pdfUrls": [
        "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
    ]
}
```

Result:

```json
{
    "operation": "pageCount",
    "inputFile": "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf",
    "pageCount": 3,
    "fileSizeKb": 48.5,
    "status": "OK",
    "error": null
}
```

#### Extract text from specific pages

```json
{
    "operation": "extractText",
    "pdfUrls": [
        "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
    ],
    "pageRanges": "1-2"
}
```

Result:

```json
{
    "operation": "extractText",
    "outputKey": "text_1.txt",
    "pageCount": 2,
    "totalChars": 6562,
    "pages": [
        { "page": 1, "text": "Sample PDF  Created for testing ...", "charCount": 2977 },
        { "page": 2, "text": "ipsum dolor sit amet ...", "charCount": 3585 }
    ],
    "status": "OK"
}
```

#### Compress a PDF

```json
{
    "operation": "compress",
    "pdfUrls": [
        "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
    ],
    "compressionLevel": "high"
}
```

Result: 48.5 KB → 41.3 KB (14.8% reduction)

#### Add a watermark

```json
{
    "operation": "watermark",
    "pdfUrls": [
        "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
    ],
    "watermarkText": "DRAFT",
    "watermarkOpacity": 0.2,
    "watermarkFontSize": 72,
    "watermarkAngle": 45
}
```

#### Split into custom groups

Use semicolons to define output groups:

```json
{
    "operation": "split",
    "pdfUrls": [
        "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
    ],
    "pageRanges": "1-2;3"
}
```

Result: Two output PDFs — pages 1-2 (42 KB) and page 3 (26.8 KB).

#### Read metadata

```json
{
    "operation": "metadata",
    "pdfUrls": [
        "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
    ]
}
```

Result:

```json
{
    "pageCount": 3,
    "fileSizeKb": 48.5,
    "title": "Sample PDF",
    "pageSizes": [
        { "page": 1, "widthPt": 612, "heightPt": 792 },
        { "page": 2, "widthPt": 612, "heightPt": 792 },
        { "page": 3, "widthPt": 612, "heightPt": 792 }
    ],
    "operation": "metadata",
    "status": "OK"
}
```

#### Merge two PDFs

```json
{
    "operation": "merge",
    "pdfUrls": [
        "https://example.com/first.pdf",
        "https://example.com/second.pdf"
    ],
    "outputFileName": "combined_report"
}
```

#### Rotate pages

```json
{
    "operation": "rotate",
    "pdfUrls": [
        "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
    ],
    "rotateAngle": "180",
    "pageRanges": "1"
}
```

#### OCR a scanned PDF

```json
{
    "operation": "ocr",
    "pdfUrls": [
        "https://example.com/scanned_document.pdf"
    ],
    "ocrLanguages": "eng+deu"
}
```

### Using PDF Tools with the Apify API

The Apify [API](https://docs.apify.com/api/v2) gives you programmatic access to PDF Tools. You can start runs, retrieve results, and integrate the Actor into your automation workflows.

To access the API using Python, use the `apify-client` [PyPI package](https://docs.apify.com/api/client/python). To access the API using JavaScript, use the `apify-client` [NPM package](https://docs.apify.com/api/client/js).

**Start a run via REST API:**

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/mrkrokko~pdf-tools/runs?waitForFinish=120" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "operation": "extractText",
    "pdfUrls": ["https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"]
  }'
```

**Retrieve dataset results:**

```bash
curl "https://api.apify.com/v2/datasets/{DATASET_ID}/items?format=json" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

**Download output files from Key-Value Store:**

```bash
curl "https://api.apify.com/v2/key-value-stores/{STORE_ID}/records/{outputKey}" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -o output.pdf
```

For full API documentation, see the [API tab](https://console.apify.com/actors/oyjy3FcHWqW3puVYc/api) or the [Apify API reference](https://docs.apify.com/api/v2).

### Integrations

PDF Tools can be integrated with almost any cloud service or web app through Apify's built-in [integrations](https://apify.com/integrations):

- **Make (Integromat)** — Trigger PDF processing as part of automated workflows
- **Zapier** — Connect with 5,000+ apps
- **Google Drive / Sheets** — Store results automatically
- **Webhooks** — Get notified when a run completes
- **MCP** — Use as a tool in AI agent workflows via [Apify MCP](https://docs.apify.com/platform/integrations/mcp)

# Actor input Schema

## `operation` (type: `string`):

Which PDF operation to perform.

## `pdfUrls` (type: `array`):

Direct-download URLs to PDF files. For merge, order matters. API callers may also send a single 'pdfUrl' or Apify-style 'startUrls'.

## `pdfKeys` (type: `array`):

Optional keys of PDF records stored in the run's default Key-Value Store. Useful for API workflows that upload files before running the Actor.

## `pageRanges` (type: `string`):

Comma-separated page ranges, e.g. '1-3,5,8-10'. 1-indexed. Used by split and extractText.

## `watermarkText` (type: `string`):

Text to overlay as watermark (operation=watermark).

## `watermarkOpacity` (type: `number`):

Opacity of the watermark (0.0 = invisible, 1.0 = fully opaque).

## `watermarkFontSize` (type: `integer`):

Font size in points for the watermark text.

## `watermarkAngle` (type: `integer`):

Angle in degrees to rotate the watermark text.

## `rotateAngle` (type: `string`):

Clockwise rotation angle for pages. Must be a multiple of 90.

## `ocrLanguages` (type: `string`):

Tesseract language codes, e.g. 'eng', 'deu', 'eng+deu'. Pre-installed: eng, deu, fra, spa, ita, por.

## `compressionLevel` (type: `string`):

How aggressively to compress.

## `outputFileName` (type: `string`):

Base name for the output file in Key-Value Store (without .pdf extension). Auto-generated if empty.

## Actor input object example

```json
{
  "operation": "pageCount",
  "pdfUrls": [
    "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
  ],
  "pdfKeys": [],
  "watermarkText": "CONFIDENTIAL",
  "watermarkOpacity": 0.15,
  "watermarkFontSize": 60,
  "watermarkAngle": 45,
  "rotateAngle": "90",
  "ocrLanguages": "eng",
  "compressionLevel": "medium"
}
```

# Actor output Schema

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

Structured JSON result records stored in the default dataset. Usually one item per processed PDF, or one item per split output file.

## `files` (type: `string`):

Generated PDF and TXT files stored in the default key-value store, including merged PDFs, split PDFs, compressed PDFs, rotated PDFs, watermarked PDFs, and extracted or OCR text 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 = {
    "pdfUrls": [
        "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
    ],
    "pdfKeys": [],
    "watermarkText": "CONFIDENTIAL"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrkrokko/pdf-tools").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 = {
    "pdfUrls": ["https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"],
    "pdfKeys": [],
    "watermarkText": "CONFIDENTIAL",
}

# Run the Actor and wait for it to finish
run = client.actor("mrkrokko/pdf-tools").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "pdfUrls": [
    "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf"
  ],
  "pdfKeys": [],
  "watermarkText": "CONFIDENTIAL"
}' |
apify call mrkrokko/pdf-tools --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=mrkrokko/pdf-tools",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "PDF Tools (Merge / Split / Compress / OCR / Watermark)",
        "description": "All-in-one PDF processor: merge multiple PDFs, split by page ranges, compress file size, extract text, OCR scanned documents (Tesseract), add text watermarks, rotate pages, and read metadata. Accepts PDF URLs or Key-Value Store keys.",
        "version": "0.1",
        "x-build-id": "djimrF61TQiGFKcMz"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/mrkrokko~pdf-tools/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-mrkrokko-pdf-tools",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/mrkrokko~pdf-tools/runs": {
            "post": {
                "operationId": "runs-sync-mrkrokko-pdf-tools",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/mrkrokko~pdf-tools/run-sync": {
            "post": {
                "operationId": "run-sync-mrkrokko-pdf-tools",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "operation"
                ],
                "properties": {
                    "operation": {
                        "title": "Operation",
                        "enum": [
                            "merge",
                            "split",
                            "compress",
                            "extractText",
                            "ocr",
                            "watermark",
                            "rotate",
                            "metadata",
                            "pageCount"
                        ],
                        "type": "string",
                        "description": "Which PDF operation to perform.",
                        "default": "pageCount"
                    },
                    "pdfUrls": {
                        "title": "PDF file URLs",
                        "minItems": 1,
                        "type": "array",
                        "description": "Direct-download URLs to PDF files. For merge, order matters. API callers may also send a single 'pdfUrl' or Apify-style 'startUrls'.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "pdfKeys": {
                        "title": "PDF Key-Value Store keys",
                        "type": "array",
                        "description": "Optional keys of PDF records stored in the run's default Key-Value Store. Useful for API workflows that upload files before running the Actor.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "pageRanges": {
                        "title": "Page ranges (split/extract)",
                        "type": "string",
                        "description": "Comma-separated page ranges, e.g. '1-3,5,8-10'. 1-indexed. Used by split and extractText."
                    },
                    "watermarkText": {
                        "title": "Watermark text",
                        "type": "string",
                        "description": "Text to overlay as watermark (operation=watermark)."
                    },
                    "watermarkOpacity": {
                        "title": "Watermark opacity",
                        "minimum": 0.01,
                        "maximum": 1,
                        "type": "number",
                        "description": "Opacity of the watermark (0.0 = invisible, 1.0 = fully opaque).",
                        "default": 0.15
                    },
                    "watermarkFontSize": {
                        "title": "Watermark font size",
                        "minimum": 10,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Font size in points for the watermark text.",
                        "default": 60
                    },
                    "watermarkAngle": {
                        "title": "Watermark rotation angle (degrees)",
                        "minimum": 0,
                        "maximum": 360,
                        "type": "integer",
                        "description": "Angle in degrees to rotate the watermark text.",
                        "default": 45
                    },
                    "rotateAngle": {
                        "title": "Rotation angle (degrees)",
                        "enum": [
                            "90",
                            "180",
                            "270"
                        ],
                        "type": "string",
                        "description": "Clockwise rotation angle for pages. Must be a multiple of 90.",
                        "default": "90"
                    },
                    "ocrLanguages": {
                        "title": "OCR languages",
                        "type": "string",
                        "description": "Tesseract language codes, e.g. 'eng', 'deu', 'eng+deu'. Pre-installed: eng, deu, fra, spa, ita, por.",
                        "default": "eng"
                    },
                    "compressionLevel": {
                        "title": "Compression level",
                        "enum": [
                            "low",
                            "medium",
                            "high"
                        ],
                        "type": "string",
                        "description": "How aggressively to compress.",
                        "default": "medium"
                    },
                    "outputFileName": {
                        "title": "Output file name",
                        "type": "string",
                        "description": "Base name for the output file in Key-Value Store (without .pdf extension). Auto-generated if empty."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
