PDF Text Extractor - Markdown, Tables & RAG Chunks avatar

PDF Text Extractor - Markdown, Tables & RAG Chunks

Pricing

from $0.24 / 1,000 page extracteds

Go to Apify Store
PDF Text Extractor - Markdown, Tables & RAG Chunks

PDF Text Extractor - Markdown, Tables & RAG Chunks

Extract text from PDF to clean Markdown with real tables, headings and lists. Bulk PDF to text conversion for RAG, LLM and vector database ingestion, with optional context-aware chunking. Detects scanned PDFs, handles encrypted files and broken URLs. Pay only for documents extracted.

Pricing

from $0.24 / 1,000 page extracteds

Rating

0.0

(0)

Developer

HJL Analytics and AI development

HJL Analytics and AI development

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Convert PDFs into clean, structured Markdown that a language model can actually use. Headings, tables and lists survive the conversion. Optional retrieval-ready chunks come with their heading breadcrumb attached.

Built for RAG pipelines, vector databases and LLM ingestion, where the quality of your retrieval is capped by the quality of your text extraction.


Why most PDF extractors are not good enough for RAG

Most tools call extract_text() and hand you the result. That produces three problems you only notice after your retrieval quality is already bad:

ProblemWhat it does to your pipeline
Tables flattened into proseRegion North 1200 48000 South 900 36000 embeds as numeric noise. The relationship between a number and its column header is destroyed.
No heading structureA chunk reading "The limit is 40 hours." is unretrievable. Which limit? Which policy? The section title held that context and it was thrown away.
Running headers on every page"ACME Holdings Confidential — Page 4 of 60" repeated into 60 chunks, diluting every embedding.
Hard line wrapping keptSentences arrive broken mid-clause, so chunk boundaries land in the middle of ideas.

This Actor addresses each of them.


What it does

Real Markdown structure

Headings become #/##/### by comparing font sizes to the document's body size — not by guessing from capitalisation. Lists become - items. Paragraphs are rebuilt from wrapped lines, with hyphenation rejoined.

Tables that stay tables

Tables are detected, rendered as Markdown tables, and — crucially — their text is removed from the prose flow, so table content is never emitted twice.

Two detection paths run:

  • Ruled tables — standard grids with visible borders.
  • Borderless "booktabs" tables — the academic and analyst-report style with horizontal rules only and no vertical lines. Most extractors miss these entirely and flatten them into prose. Columns are recovered from the vertical whitespace corridors a human reader's eye uses.

Spurious grids are rejected: a bordered callout box is not a one-column table, and a dense figure is not a 59-column one. When a grid is rejected its text is still returned as prose — content is never silently dropped.

RAG chunking with context

Enable chunkForRag and each chunk arrives with the heading trail that locates it:

{
"index": 12,
"breadcrumb": "Employee Handbook > Leave Policy > Parental Leave",
"headings": ["Employee Handbook", "Leave Policy", "Parental Leave"],
"text": "Employees are entitled to 16 weeks...",
"page": 7
}
  • Chunks never cross a heading, so one chunk never mixes two sections.
  • Each carries its breadcrumb, so it stays meaningful once embedded.
  • Paragraphs and tables are never split mid-way.
  • Overlap keeps facts that straddle a boundary retrievable, and is never carried across a section break.

Clean-up you would otherwise write yourself

  • Running headers and footers detected and stripped (page numbers normalised, so "Page 1 of 12" and "Page 7 of 12" are recognised as the same furniture).
  • Rotated margin text — arXiv stamps, spine labels, watermarks — excluded rather than dropped mid-sentence into your abstract.
  • Multi-column pages read column by column, not straight across the gutter.
  • Word spacing repaired on tightly-kerned PDFs that otherwise return Providedproperattributionisprovided.

Built for batches

One row per document. A password-protected, corrupt, oversized or 404'd file returns a row with status: "error" and a reason — it never aborts the run. Scanned PDFs are flagged with isScanned: true and a warning rather than silently returning nothing.


How to use it

  1. Paste one or more direct PDF URLs into PDF URLs. Anything you can link to works — a file on your own server, an S3 or Drive direct link, a published report.
  2. Choose an output format: Markdown keeps headings, lists and tables; plain text strips all markup; Both returns each in its own field.
  3. Turn on RAG chunks if the text is going into a vector database. Each chunk carries the heading breadcrumb it sits under, so an embedding keeps its context.
  4. Start the run. Results appear as one dataset row per document.

Every run is a normal Apify run, so you can schedule it, trigger it from the API, or wire it into Make, Zapier, LangChain or LlamaIndex.

Pricing

You are charged only for documents that extract successfully — a small per-document fee plus a per-page fee. Failed downloads, encrypted files, corrupt PDFs and 404s are not charged. A run that extracts nothing costs nothing.

Pricing per page rather than a flat fee per file means a two-page invoice costs a fraction of a 300-page annual report, instead of subsidising it.


Input

FieldTypeDefaultDescription
pdfUrlsarrayRequired. Direct links to the PDFs.
outputFormatstringmarkdownmarkdown, text, or both.
extractTablesbooleantrueDetect tables and render them as Markdown.
chunkForRagbooleanfalseAlso return retrieval-ready chunks.
chunkSizeinteger1500Soft character ceiling per chunk.
chunkOverlapinteger150Characters repeated between chunks.
includeMetadatabooleantrueReturn title, author, dates, producer.
maxPagesPerDocumentinteger0Stop after N pages. 0 = no limit.
passwordstringPassword for encrypted PDFs.

Example

{
"pdfUrls": [
"https://example.com/annual-report.pdf",
"https://example.com/policy.pdf"
],
"outputFormat": "markdown",
"extractTables": true,
"chunkForRag": true,
"chunkSize": 1200
}

Output

One dataset item per document:

{
"url": "https://example.com/annual-report.pdf",
"filename": "annual-report.pdf",
"status": "ok",
"error": null,
"pageCount": 15,
"tableCount": 4,
"isScanned": false,
"markdown": "# Annual Report\n\n## Executive Summary\n\n...",
"metadata": { "Title": "Annual Report 2026", "Author": "ACME" },
"chunks": [ { "index": 0, "breadcrumb": "...", "text": "...", "page": 1 } ],
"chunkCount": 37
}

Failed documents:

{
"url": "https://example.com/missing.pdf",
"filename": "missing.pdf",
"status": "error",
"error": "http 404"
}

Limitations — stated up front

  • Scanned PDFs are not OCR'd. If a page has no text layer there is nothing to extract. Those documents return isScanned: true and a warning so you can route them elsewhere, rather than silently returning nothing.
  • Dense interactive forms (tax forms, application forms) extract far less cleanly than reports, papers and manuals. Their content is laid out as positioned fields rather than as a reading flow.
  • Multi-row table headers are returned as separate rows rather than being merged into one header.
  • Text is extracted in the document's own language; nothing is translated.

Common uses

PDF for LLM and RAG pipelines: loading documentation, reports, contracts, research papers, manuals and policies into a vector database as PDF RAG chunks, each carrying the heading it sits under so a retrieved chunk keeps its context. Building a RAG knowledge base from a document set.

Also common: multi page PDF extraction across long manuals and reports; contract PDF extraction and form PDF extraction, where field labels and table cells have to survive; pulling invoice PDF text and line items as structured rows; extracting tables from PDFs; bulk PDF to Markdown conversion for static sites and wikis; and PDF to clean text when you want no markup at all.

Encrypted PDF files open with a supplied password. When one cannot be read it is reported with the reason and charged nothing.

Integrations

Standard Apify output: pull results via the API, export to JSON/CSV/Excel, schedule runs, or connect to Make, Zapier, LangChain, LlamaIndex and other Apify integrations.

FAQ

Is this legal? Yes. You supply documents you already have the right to use, and the Actor extracts them. No third-party website is accessed, no terms of service are involved, and no proxies are used.

How much will a run cost? You are charged per page successfully extracted. A 40-page report costs $0.016; a 300-page manual costs $0.12. Pricing is per page rather than per file on purpose — extraction cost scales with pages, so a flat per-file price would either overcharge short documents or lose money on long ones.

What happens if one document in my batch fails? Only that document. It appears in the dataset with status: "error" and the reason, the rest of the batch continues, and you are not charged for it.

It returned nothing for my PDF. Why? Check isScanned and the warning field. A scanned PDF is an image with no text layer, so there is nothing to extract without OCR. The Actor detects this and says so rather than silently returning an empty string.

How is this different from a plain text extractor? A naive extractor returns a wall of text: no headings, no tables, and words welded together across line breaks. On a real research paper this Actor recovers 16 headings and 4 tables where the naive baseline finds none, and removes several hundred welded words. Tables come out as real Markdown tables, not as scattered numbers.

Can I get the data out programmatically? Yes — the standard Apify dataset API, plus JSON, CSV and Excel export. Every output field is described in the dataset schema, so tools and AI agents can read the structure without guessing.

Other Actors by this author

ActorWhat it does
Audio & Video Transcriber — Speech to Text, SRT & TimestampsThe same idea for recordings: Whisper speech-to-text on your own audio and video, with timestamps, SRT/VTT subtitles and the same RAG chunking. Pairs naturally with this Actor when a knowledge base mixes documents and recordings.