PDF to Markdown and Text Converter with OCR
Pricing
from $2.40 / 1,000 pdf documents
PDF to Markdown and Text Converter with OCR
PDF to Markdown and text converter. Turns PDF files into Markdown with headings, plain text and tables as rows. Scanned pages use Tesseract OCR, Arabic included. Returns title, page count, metadata and optional RAG chunks for embeddings.
Pricing
from $2.40 / 1,000 pdf documents
Rating
0.0
(0)
Developer
Malik Said
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
16 hours ago
Last modified
Categories
Share
PDF to Text, Markdown & Tables (OCR, RAG)
This Actor converts PDF files to plain text and Markdown. It finds headings, paragraphs, bullet lists and simple tables. Scanned pages are read with Tesseract OCR, including Arabic. You get one record per PDF with metadata such as title and page count. You can also get chunks sized for embeddings, ready for RAG and vector databases.
What it does
- Reads PDFs from URLs you give, or from your own Apify key-value stores.
- Returns plain text and Markdown with
#,##and###headings. Heading levels come from font sizes. - Finds simple tables and returns them as rows and as Markdown tables.
- Drops running headers and footers, such as page numbers, that repeat on many pages.
- Reads scanned pages with Tesseract OCR. English and Arabic ship with the Actor. 13 more languages are available.
- Turns Arabic presentation-form letters back into normal letters, so Arabic text can be searched and embedded.
- Splits the Markdown into chunks with page numbers and the section heading, if you set a chunk size.
- Returns title, author, subject, dates, language, page count and the file's SHA-256.
The Actor runs pdf.js and Tesseract inside the container. Your files are not sent to any outside service.
What you get
| Field | Meaning |
|---|---|
url | The PDF URL, or kv://store/KEY for a file in a key-value store |
status | ok, or failed with the reason in error. Failed files are free |
title | Title from the PDF metadata. If there is none, the first top-level heading on page 1 |
author, subject, keywords, creator, producer, language | PDF metadata. Empty when the file does not set them |
creationDate, modificationDate | Dates from the PDF metadata, ISO 8601 |
pageCount, pagesProcessed, truncated | Pages in the file, pages read, and whether a page limit cut the file short |
ocrPages, ocrPagesSkipped | Pages read with OCR, and scanned pages skipped because of a limit |
text | Plain text. Table cells are separated by tabs |
markdown | Markdown with headings, paragraphs, lists and tables |
headings | Level, text and page of each heading |
tables | Page, row count, column count and rows of each table |
chunks | Only with a chunk size above 0: text, page range and section of each chunk |
pages | Only with Include each page separately: text and Markdown per page |
charCount, wordCount | Size of the text |
fileName, fileSizeBytes, sha256 | File details |
passwordProtected | true when the PDF needed a password, false when it opened without one |
Sample record from a test run on IRS Form W-9 (a US government work in the public domain). Long fields are shortened here:
{"url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf","source": "url","status": "ok","error": null,"fileName": "fw9.pdf","fileSizeBytes": 140815,"title": "Form W-9 (Rev. March 2024)","subject": "Request for Taxpayer Identification Number and Certification","language": "en-US","creationDate": "2024-03-06T13:18:13.000Z","pageCount": 6,"pagesProcessed": 6,"truncated": false,"ocrPages": [],"charCount": 37544,"wordCount": 6481,"headings": [{ "level": 1, "text": "Request for Taxpayer Identification Number and Certification", "page": 1 },{ "level": 1, "text": "General Instructions", "page": 1 },{ "level": 2, "text": "Purpose of Form", "page": 1 }],"markdown": "Form W-9 (Rev. March 2024)\n\n# Request for Taxpayer Identification Number and Certification\n\nDepartment of the Treasury ..."}
A table from IRS Publication 15-T, page 6, as the Actor returned it:
{"page": 6,"rowCount": 8,"columnCount": 2,"rows": [["Payroll period", "Add additional"], ["Weekly", "$226.90"], ["Biweekly", "453.80"], ["Semimonthly", "491.70"]]}
A chunk from IRS Publication 1 with Chunk size 1500:
{"index": 1,"text": "communications from the IRS, and to speak to a supervisor about inadequate service.\n\n### 3. The Right to Pay No More than the Correct Amount of Tax\n\nTaxpayers have the ri...","charCount": 1356,"pageStart": 1,"pageEnd": 1,"section": "3. The Right to Pay No More than the Correct Amount of Tax"}
How to use it
- Paste the PDF links into PDF URLs. Each link must point straight to a PDF file.
- For files stored in Apify, pick the stores in PDFs in your Apify key-value stores. Add record keys, or leave the keys empty to read every PDF in the stores.
- For RAG, set Chunk size for embeddings to 1,000 or 2,000.
- For scanned Arabic documents, add Arabic to OCR languages.
- Run the Actor. Download the results as JSON, CSV or Excel, or read them through the API.
Input
| Field | Default | Meaning |
|---|---|---|
startUrls | IRS Form W-9 | PDF links |
pdfPassword | none | PDF password. Opens password-protected PDFs. It is tried on every PDF in the run and never saved |
keyValueStores, keyValueStoreKeys | none | Your Apify stores and record keys |
ocrMode | auto | auto reads pages that have almost no text layer and hold a large image. off skips OCR |
ocrLanguages | ["eng"] | OCR languages. Each extra language makes OCR slower |
extractTables | true | Find simple tables |
removeHeadersFooters | true | Drop running headers and footers |
includeText, includeMarkdown | true | Turn either output off to save space |
includePages | false | Add text and Markdown per page |
chunkSize, chunkOverlap | 0, 150 | Chunk length and overlap in characters. 0 turns chunks off |
maxItems | 100 | Maximum PDFs per run. 0 means no limit |
maxPagesPerPdf | 500 | Pages read per PDF, from page 1 |
maxPagesPerRun | 5,000 | Pages read per run |
maxOcrPagesPerRun | 50 | OCR pages per run |
maxFileSizeMb | 50 | Larger files are skipped |
Pricing
You pay per event:
| Event | Price |
|---|---|
| Actor start | $0.02 per run |
| PDF document, first 20 pages included | $0.003 per PDF ($3 per 1,000 PDFs) |
| Extra page, above 20 pages in a PDF | $0.0002 per page ($0.20 per 1,000 pages) |
| OCR page | $0.01 per scanned page ($10 per 1,000 pages) |
Failed files are free. Pages with a text layer are never charged for OCR. Examples:
- 100 text PDFs of up to 20 pages: $0.02 + $0.30 = $0.32.
- One 71-page text PDF: $0.02 + $0.003 + 51 x $0.0002 = $0.033.
- One 10-page scan: $0.02 + $0.003 + 10 x $0.01 = $0.123.
The Actor never does work it cannot charge for. When your maximum cost per run is close, it reads fewer pages and lists the skipped scanned pages.
Limits and good to know
- Each download is capped at 60 seconds and retried at most twice.
- Only fetch files you have the right to use. The Actor reads robots.txt before each download and skips blocked files. It refuses private network addresses.
- Heading levels come from font sizes. Documents that use bold text of the same size for headings get fewer headings.
- Table detection works for tables whose cells line up in columns. Merged cells and multi-row headers can come back split. Tables on OCR pages come back as text.
- The Actor runs with 1,024 MB of memory. OCR of one dense 300 dpi page took about 35 seconds on the platform at 512 MB. It should take about half that at 1,024 MB, which is not yet measured. Large scans are scaled to at most 2,500 pixels on the long side. OCR stops 2 minutes before the run timeout, so finished work is saved.
- English uses Tesseract's fast model. Arabic and the other languages use the more accurate integer model.
- Password-protected PDFs open when you give the password. Without it, they fail with a clear, free error. Very large results go to the run's key-value store, and the record keeps the first 200,000 characters with a pointer in
fullOutputKey. - Right-to-left text comes back in reading order. Lines that mix Arabic and Latin, such as URLs, can come back partly reordered.
FAQ
Can it read password-protected PDFs? Yes. Put the password in PDF password. The Actor tries it on every PDF in the run. PDFs without a password open as usual. A missing or wrong password gives a failed row with the reason, and failed rows are free. The password never appears in the output or the log.