PDF to AI-Ready Data (Markdown, Tables, RAG Chunks, OCR) avatar

PDF to AI-Ready Data (Markdown, Tables, RAG Chunks, OCR)

Pricing

from $1.00 / 1,000 page processeds

Go to Apify Store
PDF to AI-Ready Data (Markdown, Tables, RAG Chunks, OCR)

PDF to AI-Ready Data (Markdown, Tables, RAG Chunks, OCR)

Convert PDFs into clean Markdown, JSON/CSV tables and RAG-ready chunks with page metadata. Built-in OCR for scanned PDFs. No AI API calls, no proxies.

Pricing

from $1.00 / 1,000 page processeds

Rating

0.0

(0)

Developer

Loris Barce

Loris Barce

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 hours ago

Last modified

Categories

Security

Limited permissions

Share

PDF to AI-Ready Data — Markdown, Tables, RAG Chunks & OCR

Turn any PDF into clean Markdown, tables as JSON/CSV and RAG-ready chunks with page metadata — in seconds, with built-in OCR for scanned documents.

Everything runs locally inside the Actor: no AI APIs, no proxies, no browser. You only pay for the pages you actually process.

Why use it

  • 🧱 Structure preserved — headings (#, ##) rebuilt from font sizes, bulleted and numbered lists, clean paragraphs.
  • 🧹 Noise removed — running headers/footers and page numbers repeated on ≥ 50% of pages are stripped; words hyphenated across line breaks are re-joined.
  • 📊 Tables extracted — fully gridded tables, tables drawn with horizontal rules only (papers, reports) and borderless financial statements made of aligned number columns all become JSON (array of rows) and CSV, and are embedded in the Markdown as GitHub tables.
  • ✂️ Chunks ready for embeddings — split on paragraph and sentence boundaries with configurable size and overlap, each chunk tagged with pageStart, pageEnd, chunkIndex, sourceUrl and docTitle.
  • 🔍 OCR for scans — pages without a text layer are OCR'd automatically (Tesseract, 300 DPI) in English, Italian, German, French and Spanish.
  • 🛡️ Robust — one broken PDF never stops the batch; every failure is reported with a clear reason. Memory stays flat even on 300+ page documents.

Use cases

  • RAG chatbots and AI agents over your documents — manuals, policies, contracts, knowledge bases.
  • Table extraction from reports and invoices — financial statements, price lists, invoices to CSV/JSON.
  • Digitising scanned archives — make old scanned PDFs searchable and embeddable.
  • Pre-processing for LLM pipelines — feed Markdown instead of raw PDF text to get better answers and fewer tokens.

Input

FieldTypeDefaultDescription
pdfUrlsarray of strings–Direct links to PDF files.
uploadedFilesarray of strings–Uploaded files: a file/record URL, a key in the run's default key-value store, or storeIdOrName/key.
outputsarray["markdown"]Any of markdown, text, tables, chunks.
ocrModestringautoauto (OCR only pages without text), always, never.
ocrLanguagesarray["eng","ita"]eng, ita, deu, fra, spa.
chunkSizeinteger1000Max characters per chunk (overlap included).
chunkOverlapinteger150Characters repeated from the previous chunk. Must be < chunkSize / 2.
pageRangestringall pagese.g. 1-10,15 or 20-.
maxPagesinteger500Cost guard: max pages processed per document.
maxFileSizeMbinteger50Larger files are rejected before processing.

Example:

{
"pdfUrls": ["https://www.rfc-editor.org/rfc/pdfrfc/rfc2119.txt.pdf"],
"outputs": ["markdown", "tables", "chunks"],
"ocrMode": "auto",
"ocrLanguages": ["eng"],
"chunkSize": 1000,
"chunkOverlap": 150
}

Output

Dataset (one row per document)

{
"sourceUrl": "https://example.com/annual-report.pdf",
"docId": "annual-report-3f2a91bc",
"title": "Annual Report 2025",
"pages": 42,
"totalPages": 42,
"ocrPages": 0,
"markdown": "# Annual Report 2025\n\n## Highlights\n\n...",
"markdownUrl": "https://api.apify.com/v2/key-value-stores/.../records/annual-report-3f2a91bc.md",
"text": null,
"textUrl": null,
"tablesCount": 7,
"tablesUrl": "https://api.apify.com/v2/key-value-stores/.../records/annual-report-3f2a91bc-tables.json",
"chunksCount": 118,
"status": "succeeded",
"error": null,
"warnings": []
}
  • markdown / text are inlined when ≤ 1 MB; larger documents only get the …Url link.
  • status is succeeded, failed (with error, e.g. password protected, not a PDF (content-type: text/html, missing %PDF header), file too large (…), HTTP 404 while downloading), partial (spending limit reached mid-document — what was processed is saved) or skipped (spending limit reached before the document started).

chunks dataset (one row per chunk)

{
"text": "## Highlights\n\nRevenue grew 12% year over year, driven by ...",
"pageStart": 3,
"pageEnd": 4,
"chunkIndex": 5,
"sourceUrl": "https://example.com/annual-report.pdf",
"docTitle": "Annual Report 2025"
}

The chunks dataset belongs to the run; its ID is in OUTPUT.chunksDatasetId and it is listed under the run's storages.

Key-value store

KeyContent
{docId}.mdMarkdown
{docId}.txtPlain text (if text requested)
{docId}-tables.jsonAll tables: [{tableIndex, page, nRows, nCols, rows}]
{docId}-table-N.csvTable N as CSV (N starts at 1)
OUTPUTRun summary: {documents, succeeded, failed, partial, skipped, pagesProcessed, ocrPages, tables, chunks, stoppedBySpendLimit, durationSec}

Connect it to a vector database

  1. Run this Actor with outputs: ["chunks"].
  2. Add an integration to the run: Pinecone Integration, Qdrant Integration (or Weaviate, Milvus, Chroma…) from Apify Store.
  3. Point the integration at the chunks dataset, map text as the field to embed and keep sourceUrl, docTitle, pageStart, pageEnd as metadata.

Each vector then cites the exact pages it came from — perfect for answers with sources.

The same dataset works with LangChain / LlamaIndex Apify loaders, n8n, Make and Zapier.

Pricing (pay per event)

EventPriceWhen
page-processed$0.001 / pageeach page extracted from the text layer
ocr-page$0.005 / pageeach page that needed OCR (instead of page-processed)
table-extracted$0.002 / tableeach table, only when tables is in outputs

A 20-page text report with 3 tables costs $0.026. Failed downloads, non-PDF files and password-protected files are never charged.

When your run reaches its maximum cost, the Actor stops cleanly: pages already paid for are saved (status partial), remaining documents are marked skipped, and the run still finishes as SUCCEEDED.

Limits

  • Password-protected PDFs are not supported — they are reported as failed: password protected. The Actor never tries to unlock them.
  • OCR quality depends on the scan — resolution, skew and contrast matter. Handwriting is not supported.
  • Borderless tables are detected when they are numeric (amounts, years, percentages in aligned columns — e.g. income statements). Borderless tables of pure text with no lines at all are kept as text. Very narrow sub-columns under a spanning header may be merged into one cell.
  • Multi-column layouts are read line by line across the page; complex magazine layouts may mix columns.
  • Max file size and page count are capped by maxFileSizeMb and maxPages.
  • Downloads from private/internal network addresses are blocked for security.

FAQ

Does it send my documents to OpenAI or another AI service? No. Extraction and OCR run entirely inside the Actor container.

Can I process files that aren't public? Yes — upload them to a key-value store (or use the file upload in the input) and list them in uploadedFiles.


🇮🇹 In breve (italiano)

Converte PDF in Markdown pulito (titoli, elenchi, paragrafi), tabelle JSON/CSV e chunk pronti per RAG con numero di pagina, con OCR automatico per i PDF scansionati (eng, ita, deu, fra, spa). Nessuna API AI esterna: tutto gira dentro l'Actor.

  • Prezzi: 0,001 $ a pagina, 0,005 $ a pagina OCR, 0,002 $ a tabella (solo se richiedi tables). I file non validi non vengono addebitati.
  • Limite di spesa: al raggiungimento del limite l'Actor si ferma in modo pulito, salva quanto elaborato e termina in SUCCEEDED.
  • Limiti: niente PDF protetti da password; la qualità OCR dipende dalla scansione; le tabelle senza linee vengono riconosciute se sono numeriche (es. conti economici), quelle di solo testo restano come testo.
  • Vector DB: collega il dataset chunks alle integrazioni Pinecone/Qdrant di Apify usando text come campo da indicizzare.