# PDF & Invoice Data Extractor — Text, Metadata, Amounts, Dates (`dev_craft/pdf-invoice-data-extractor-text-metadata-amounts-dates`) Actor

Extract text, metadata, page count, emails, dates, and financial amounts from PDFs in bulk — with automatic OCR fallback for scanned pages. No paid AI APIs required.

- **URL**: https://apify.com/dev\_craft/pdf-invoice-data-extractor-text-metadata-amounts-dates.md
- **Developed by:** [Harsh](https://apify.com/dev_craft) (community)
- **Categories:** Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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 & Invoice Data Extractor

Bulk-extract text, metadata, and key data points from PDFs — from URLs, a single upload, or a ZIP of many PDFs. Works well on invoices, bank/account statements, and general business documents. No paid AI APIs required for the core extraction, so it's fast and predictable to run at volume.

### What you get, per PDF

- **Full text**
- **Metadata** — title, author, subject, creator, producer, creation/modified dates
- **Page count** and **file size**
- **Emails** found in the document
- **Dates** found in the document (multiple common formats)
- **Financial amounts** — both currency-marked ($, €, £, ₹, ¥, USD/INR/EUR/etc.) and plain table-style numbers (e.g. "1,500.00"), which is how amounts usually appear in bank/account statements
- **Links** written in the text

### Scanned PDFs — automatic OCR fallback

Most PDFs (invoices, statements, reports) have a real text layer and are read directly — fast, and free of any OCR cost. Only the leftover PDFs that have **no** text layer (true scans/photos) get run through OCR (Tesseract, local, no paid API) automatically. If even OCR can't read a page (blank page, very low quality), that record is clearly flagged instead of returned empty.

Status values you'll see per record:
- `success` — read directly, no OCR needed
- `success_via_ocr` — had no text layer, OCR recovered it
- `scanned_pdf_ocr_failed` — no text layer, and OCR couldn't read it either

### Optional: AI-structured bank statement transactions (bring your own key)

For documents that look like a bank/account statement, you can optionally provide your own API key for **Gemini, OpenAI, or Claude**. All the extraction above still happens locally and for free — the AI is only used to organize the already-extracted text into a clean `structuredTransactions` array (date, description, withdrawal, deposit, balance). We never charge for or store this key; it's encrypted by Apify and only ever used inside your own run — any AI usage bills go straight to your own provider account.

- No key provided → actor behaves exactly as described above (free, local, no AI).
- Key provided, but the document isn't detected as a bank statement → AI is skipped, no cost incurred.
- Key provided and the AI call fails for any reason (bad key, rate limit, etc.) → that record still returns all the normal fields, plus an `aiStructuringError` message. Nothing else in the run is affected.

### Input

- `urls`: array of public PDF links
- `pdfFile`: upload a single PDF, or a ZIP containing many PDFs
- `aiProvider` *(optional)*: `gemini` (default), `openai`, or `claude`
- `aiApiKey` *(optional)*: your own API key for the chosen provider
- `aiModel` *(optional)*: leave blank for a sensible per-provider default

### Output example

```json
{
  "source": "invoice.pdf",
  "status": "success",
  "metadata": {
    "title": "Invoice INV-2026-0042",
    "author": "Acme Corp Billing System",
    "pageCount": 1,
    "creationDate": "..."
  },
  "meta": { "characterCount": 399, "fileSizeBytes": 17519, "ocrUsed": false },
  "extractedText": "...",
  "emails": ["billing@acmecorp.com"],
  "dates": ["2026-08-01"],
  "financialAmounts": ["$1,250.50", "1,363.05"],
  "links": ["https://acmecorp.com/invoices/inv-2026-0042"]
}
````

Every field is available for CSV/Excel export directly from the Apify dataset view — no extra setup needed.

# Actor input Schema

## `pdfFile` (type: `string`):

Upload a single PDF, or a ZIP file containing many PDFs.

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

Paste public PDF links here (you can add more than one).

## `aiProvider` (type: `string`):

Only used for bank/account statement PDFs. Choose which AI to use, based on the API key you provide below.

## `aiApiKey` (type: `string`):

Optional. If you provide your own API key for the selected provider, bank/account statement transactions will be organized into clean structured JSON. Your key is stored encrypted, we never save or see it, and we never charge for its use — any AI usage is billed directly to your own provider account. Without a key, everything still works exactly as before (free, local extraction only).

## `aiModel` (type: `string`):

Leave blank to use a sensible default for the selected provider. Only change this if that default model becomes unavailable, or you want to use a specific model.

## Actor input object example

```json
{
  "urls": [
    "https://www.orimi.com/pdf-test.pdf"
  ],
  "aiProvider": "gemini"
}
```

# 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.orimi.com/pdf-test.pdf"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dev_craft/pdf-invoice-data-extractor-text-metadata-amounts-dates").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.orimi.com/pdf-test.pdf"] }

# Run the Actor and wait for it to finish
run = client.actor("dev_craft/pdf-invoice-data-extractor-text-metadata-amounts-dates").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 '{
  "urls": [
    "https://www.orimi.com/pdf-test.pdf"
  ]
}' |
apify call dev_craft/pdf-invoice-data-extractor-text-metadata-amounts-dates --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "PDF & Invoice Data Extractor — Text, Metadata, Amounts, Dates",
        "description": "Extract text, metadata, page count, emails, dates, and financial amounts from PDFs in bulk — with automatic OCR fallback for scanned pages. No paid AI APIs required.",
        "version": "0.0",
        "x-build-id": "LfFhvdQtNHx66Hhso"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dev_craft~pdf-invoice-data-extractor-text-metadata-amounts-dates/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dev_craft-pdf-invoice-data-extractor-text-metadata-amounts-dates",
                "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/dev_craft~pdf-invoice-data-extractor-text-metadata-amounts-dates/runs": {
            "post": {
                "operationId": "runs-sync-dev_craft-pdf-invoice-data-extractor-text-metadata-amounts-dates",
                "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/dev_craft~pdf-invoice-data-extractor-text-metadata-amounts-dates/run-sync": {
            "post": {
                "operationId": "run-sync-dev_craft-pdf-invoice-data-extractor-text-metadata-amounts-dates",
                "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",
                "properties": {
                    "pdfFile": {
                        "title": "Upload PDF or ZIP File",
                        "type": "string",
                        "description": "Upload a single PDF, or a ZIP file containing many PDFs."
                    },
                    "urls": {
                        "title": "Bulk PDF URLs List",
                        "type": "array",
                        "description": "Paste public PDF links here (you can add more than one).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "aiProvider": {
                        "title": "AI provider (optional)",
                        "enum": [
                            "gemini",
                            "openai",
                            "claude"
                        ],
                        "type": "string",
                        "description": "Only used for bank/account statement PDFs. Choose which AI to use, based on the API key you provide below.",
                        "default": "gemini"
                    },
                    "aiApiKey": {
                        "title": "AI API Key (optional)",
                        "type": "string",
                        "description": "Optional. If you provide your own API key for the selected provider, bank/account statement transactions will be organized into clean structured JSON. Your key is stored encrypted, we never save or see it, and we never charge for its use — any AI usage is billed directly to your own provider account. Without a key, everything still works exactly as before (free, local extraction only)."
                    },
                    "aiModel": {
                        "title": "AI model (advanced, optional)",
                        "type": "string",
                        "description": "Leave blank to use a sensible default for the selected provider. Only change this if that default model becomes unavailable, or you want to use a specific model."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
