# PDF Text Extractor – PDF to Text, Metadata & Pages (`haketa/pdf-text-extractor`) Actor

Extract clean text and metadata from any PDF by URL: full text, per-page text, page count, title, author, dates and producer. No browser, no OCR needed for text PDFs. Ideal for AI/RAG, search and document data extraction. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/haketa/pdf-text-extractor.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Developer tools, AI, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

<h1 align="center">PDF Text Extractor 📄</h1>

<p align="center">
  <img alt="Platform" src="https://img.shields.io/badge/Made%20for-Apify-97D700?style=for-the-badge">
  <img alt="What" src="https://img.shields.io/badge/PDF-%E2%86%92%20Text%20%26%20Metadata-4C8BF5?style=for-the-badge">
  <img alt="AI" src="https://img.shields.io/badge/AI%2FRAG-ready-8A2BE2?style=for-the-badge">
  <img alt="No code" src="https://img.shields.io/badge/No%20code-required-FF7A00?style=for-the-badge">
  <img alt="Export" src="https://img.shields.io/badge/Export-Excel%20%7C%20CSV%20%7C%20JSON%20%7C%20API-00B3A4?style=for-the-badge">
</p>

<p align="center"><b>Turn any PDF into clean, structured text and metadata.</b></p>

Give it PDF URLs and get back the **full text**, **per-page text**, and **document metadata** (title, author, page count, dates, producer) — clean and ready for **AI/RAG pipelines, search, and data extraction**. Fast, serverless and **no code required**.

***

### ⚡ At a glance

| | |
|---|---|
| 📝 **Full text** | Clean plain text from the whole document |
| 📑 **Per-page text** | Optional page-by-page array for chunking |
| 🏷️ **Metadata** | Title, author, page count, dates, producer |
| 🤖 **AI/RAG ready** | Feed text straight into LLMs & vector DBs |
| 📦 **Bulk** | Process one PDF or thousands from a list |
| ⚡ **Fast** | Pure code — no browser, no OCR needed |
| 💾 **Export** | Excel, CSV, JSON or API |

***

### 📌 Why this Actor?

- 📝 **Clean text extraction** — the full document as readable plain text, with broken PDF spacing fixed.
- 📑 **Per-page output** — an optional `pages` array so you can chunk documents page-by-page for embeddings and RAG.
- 🏷️ **Rich metadata** — title, author, subject, keywords, creator, producer, creation & modification dates and page count.
- 🤖 **Built for AI** — structured JSON output that drops straight into LLM, embedding and search workflows.
- 📦 **Bulk-friendly** — pass a big list of PDF URLs and get one clean dataset back.

***

### ✨ What you get (data fields)

| Field | Description |
|-------|-------------|
| `text` | Full extracted text (plain) |
| `pages` | Per-page text array *(optional)* |
| `pageCount` | Number of pages |
| `wordCount` | Extracted word count |
| `title` | Document title |
| `author` | Document author |
| `subject` | Document subject |
| `keywords` | Document keywords |
| `creator` | Creating application |
| `producer` | PDF producer |
| `creationDate` / `modificationDate` | Document dates |
| `fileName` | File name |
| `fileSizeBytes` | File size |
| `url` | Source URL |
| `error` | Set if extraction failed |

***

### 🚀 Quick start

1. Click **Try for free / Start**.
2. Add your **PDF URLs** — one per line:
   ```
   https://arxiv.org/pdf/1706.03762
   https://example.com/report.pdf
   ```
3. *(Optional)* Turn on **Include per-page text** for chunking, or set **Max pages**.
4. Click **Save & Start**, then export from the **Dataset** tab.

> 💡 **Tip:** Have a big list? Use **PDF URLs from file / list** to load thousands of URLs from a CSV or Google Sheet.

***

### 🎯 Use cases

| Use case | What it delivers |
|----------|------------------|
| 🤖 **AI / RAG pipelines** | Clean, chunked text ready for LLMs, embeddings and vector databases. |
| 🔎 **Document search** | Index PDF content for full-text search. |
| 📊 **Data extraction** | Pull text from reports, invoices, contracts and papers at scale. |
| 📚 **Research** | Extract text from academic papers and whitepapers. |
| 🗂️ **Content migration** | Convert PDF libraries into structured text. |
| 🧾 **Compliance & archiving** | Turn document sets into searchable text records. |

***

### ⚙️ Input reference

| Input | Type | Default | Description |
|-------|------|---------|-------------|
| **PDF URLs** | list | sample | PDF URLs to extract. |
| **PDF URLs from file / list** | list | — | Bulk-load URLs from a file or sheet. |
| **Include per-page text** | boolean | `false` | Add a `pages` array. |
| **Include document metadata** | boolean | `true` | Extract title, author, dates, etc. |
| **Max pages per PDF** | number | `0` | `0` = all pages. |
| **Download timeout (seconds)** | number | `60` | Per-PDF download timeout. |
| **Proxy / concurrency** | — | Datacenter / 5 | Sensible defaults. |

#### 📥 Example input

```json
{
  "pdfUrls": ["https://arxiv.org/pdf/1706.03762"],
  "splitPages": true,
  "includeMetadata": true,
  "maxPages": 0
}
```

***

### 📤 Example output

```json
{
  "url": "https://arxiv.org/pdf/1706.03762",
  "fileName": "1706.03762",
  "fileSizeBytes": 2215244,
  "pageCount": 15,
  "wordCount": 8231,
  "title": "Attention Is All You Need",
  "author": "",
  "producer": "pdfTeX-1.40.25",
  "creationDate": "2024-04-10T21:11:43.000Z",
  "text": "Provided proper attribution is provided, Google hereby grants permission to reproduce…",
  "pages": ["…page 1 text…", "…page 2 text…"],
  "scrapedAt": "2026-07-25T10:00:00.000Z"
}
```

***

### 💡 Tips & best practices

- ✅ **Use `splitPages`** for AI/RAG — page-by-page text is easy to chunk and embed.
- ✅ **Cap `maxPages`** for very large documents when you only need the first pages.
- ✅ **Bulk-load** URLs from a file to process large libraries.
- ✅ **Check the `error` field** to spot any URLs that weren't valid PDFs.
- ✅ **Scale concurrency** for big batches.

***

### ❓ FAQ

**What kinds of PDF work?**
Text-based (digitally created) PDFs. Scanned/image-only PDFs have no embedded text layer, so they return no text (OCR is not performed).

**Can I get per-page text?**
Yes — turn on **Include per-page text** to add a `pages` array.

**Can I extract metadata?**
Yes — title, author, subject, keywords, creator, producer and dates are included by default.

**Do I need to code?**
No. Add PDF URLs, click Start, export.

**In what format is the data?**
Structured JSON by default, exportable to CSV, Excel, HTML or via API.

***

### 📊 Output & integrations

Results are stored in a standard Apify dataset — preview as a **table**, export to **JSON, CSV, Excel, HTML**, pull via the **API**, or push to **Google Sheets, Make, Zapier** and more.

***

### ⚖️ Legal & responsible use

This Actor extracts text from PDFs you provide.

- Ensure you have the right to download and process each document.
- Respect copyright and the terms under which documents are published.
- You are responsible for how you use the extracted data.

***

### 🛟 Support

Found a bug, need an extra field, or want a tweak? **Open an issue** on the Actor's Issues tab.

<p align="center"><b>Happy extracting! 📄</b></p>

# Actor input Schema

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

One PDF URL per line. Each PDF is downloaded and its text + metadata extracted.

## `startUrls` (type: `array`):

Optional. Load many PDF URLs from a file, URL, Google Sheet or Request Queue.

## `splitPages` (type: `boolean`):

Add a `pages` array with the text of each page separately (useful for chunking into AI/RAG pipelines). The full `text` field is always included.

## `includeMetadata` (type: `boolean`):

Extract title, author, subject, keywords, creator, producer and dates from the PDF.

## `maxPages` (type: `integer`):

Only extract the first N pages of each PDF. Set 0 for all pages.

## `maxFileSizeMB` (type: `integer`):

Skip PDFs larger than this to keep runs fast and cheap. Set 0 for no limit.

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

How long to wait for each PDF to download before skipping it. Lower values keep runs cheaper by not waiting on slow or dead URLs.

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

Proxy settings for downloading PDFs. Datacenter proxies (the default) are usually enough.

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

How many PDFs to process in parallel. Higher finishes big batches faster and cheaper. Recommended: 8–15.

## Actor input object example

```json
{
  "pdfUrls": [
    "https://example.com/report.pdf"
  ],
  "startUrls": [],
  "splitPages": false,
  "includeMetadata": true,
  "maxPages": 0,
  "maxFileSizeMB": 50,
  "timeoutSecs": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 10
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Download every extracted PDF (JSON, CSV, Excel).

## `runUrl` (type: `string`):

Open this run in the Apify Console.

## `fileName` (type: `string`):

PDF file name

## `title` (type: `string`):

Document title

## `author` (type: `string`):

Document author

## `pageCount` (type: `string`):

Number of pages

## `wordCount` (type: `string`):

Extracted word count

## `text` (type: `string`):

Full extracted text

## `subject` (type: `string`):

Document subject

## `keywords` (type: `string`):

Document keywords

## `creator` (type: `string`):

Creating application

## `producer` (type: `string`):

PDF producer

## `creationDate` (type: `string`):

Creation date

## `modificationDate` (type: `string`):

Modification date

## `fileSizeBytes` (type: `string`):

File size in bytes

## `error` (type: `string`):

Error, if extraction failed

## `url` (type: `string`):

PDF URL

## `scrapedAt` (type: `string`):

ISO 8601 timestamp

# 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://arxiv.org/pdf/1706.03762"
    ],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/pdf-text-extractor").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://arxiv.org/pdf/1706.03762"],
    "startUrls": [],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/pdf-text-extractor").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://arxiv.org/pdf/1706.03762"
  ],
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/pdf-text-extractor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/bJaBJrpUX4NVjhvXz/builds/PSnJBcmkkYQhVkf0b/openapi.json
