PDF to Markdown avatar

PDF to Markdown

Pricing

from $1.70 / 1,000 pages

Go to Apify Store
PDF to Markdown

PDF to Markdown

Turn PDF links and uploads into clean Markdown or plain text for AI use, with headings, lists and simple tables, per document or per page. No browser or paid API. Scanned pages are flagged, with no OCR.

Pricing

from $1.70 / 1,000 pages

Rating

0.0

(0)

Developer

Ishaan Pare

Ishaan Pare

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Turn PDF files into clean Markdown or plain text, ready for AI tools, search and analysis, at $2 per 1,000 pages. Give it links or upload files, and get back headings, paragraphs, lists and simple tables in reading order. You don't need a browser, a login or an API key.

What you get

  • One row per document, or one row per page if you need to cite page numbers
  • GitHub-style Markdown, or plain text with table cells separated by tabs
  • Headings worked out from font size, plus lists, paragraphs and simple tables worked out from text position
  • Multi-column pages read one column at a time
  • Title, author, page count, word count and table count
  • A clear flag or free status row when a page has no text to read, such as a scan

Sample output

{
"recordType": "document",
"sourceUrl": "https://example.com/annual-report.pdf",
"fileName": "annual-report.pdf",
"title": "Annual Report",
"author": "Jane Writer",
"pageCount": 1,
"pagesReturned": 1,
"pageNumber": null,
"part": 1,
"partCount": 1,
"markdown": "# Annual Report\n\n## Overview\n\nThis paragraph has plenty of ordinary words in it...\n\n## Results\n\n| Region | Sales | Growth |\n| --- | --- | --- |\n| North | 1,200 | 5% |\n| South | 950 | 3% |",
"text": null,
"wordCount": 107,
"tableCount": 1,
"hasTextLayer": true,
"noTextLayerPages": [],
"possiblyGarbled": false,
"status": null,
"reason": null,
"fetchedAt": "2026-11-02T12:48:47.489Z"
}

This comes from a small test PDF, with the Markdown shortened here. With the output format set to text, the text field is filled and the markdown field is empty.

How to use it

  1. Add links to PDF files, one per line, or upload files.
  2. Choose Markdown or plain text, and one row per document or per page.
  3. If you only need part of each file, set a page range, such as 1-5 or 1,3,7-9. Then press Start.

Maximum pages per file defaults to 100, so a longer file needs a higher setting. A status row tells you when a file was cut short. Maximum file size defaults to 50 MB. If you are reading very large files, raise the run's memory too.

Pricing

You pay only for pages returned, and Apify platform usage is included.

EventPrice
Each page returned$0.002 ($2 per 1,000)
Each run started$0.00005

Status rows are free. So are pages with no text layer, pages that could not be read, and files that could not be opened. A 100-page PDF costs about $0.20. If a document is too long for one row and is split, you still pay by the page, not by the row.

If you set a maximum cost for the run, you get only the pages it pays for, and a status row tells you it stopped. A document cut off this way has pagesReturned set to the pages you received.

On the free Apify plan, each run returns up to 100 pages, and a status row tells you when you reach that limit. Any paid Apify plan removes it.

Status rows

The Actor always tells you what happened. Problems never stop the rest of the run. Each one gives a free row with recordType set to status, and reason says what went wrong in plain words.

StatusMeaning
no_inputNo links or files were given
invalid_inputThe page range could not be understood
invalid_urlNot a valid http or https link
blocked_urlThe link points to a private or reserved address, so it was refused
not_foundThe server has no file at this link
access_deniedThe server refused access
http_errorThe server returned another error
download_failedThe download could not be completed
too_many_redirectsThe link redirected too many times
too_largeThe file is over your maximum file size
not_pdfThe link returned something that isn't a PDF
encryptedThe PDF needs a password
corruptThe file is damaged and could not be read
too_complexReading the file took too long or used too much memory
no_text_layerSome or all pages have no text, and noTextLayerPages lists them
page_failedSome pages could not be read, and reason lists them
no_pages_selectedThe page range matches no pages in this file
max_pagesThe file has more pages than your maximum pages per file
spending_limitThe run reached your maximum cost
free_limitThe run reached the free plan limit

If you only want content, filter out rows with recordType set to status.

What it can't do

  • No OCR. Scanned pages have no text to read, so they are flagged and not charged. A scan with a small stamp of real text counts as text, and you get only the stamp.
  • Complex tables may be imperfect. Tables are found by how text lines up, not by their borders. Merged cells, cells with long running text and tables with no clear gaps between columns can come out wrong, or as ordinary text. Small labels in a chart can look like a small table.
  • Multi-column pages are worked out from positions, so unusual layouts can read in the wrong order.
  • Headings come from font size only, so a bold heading in the same size as the body text stays a paragraph.
  • Images and charts are not described, and rotated text goes at the end of the page.
  • Page headers, footers and page numbers stay in the text.
  • A paragraph that runs over a page break stays as two paragraphs.
  • Some PDFs have fonts with no usable letter mapping. When that shows up as symbols, possiblyGarbled is true, but gibberish made of ordinary letters can't be detected.
  • Password-protected files can't be read, and there is no input for a password. A file that opens with no password but restricts copying is read as normal, so make sure you have the right to use its content.

Long documents

Apify limits each dataset row to 9 MB. A longer document or page is split across rows, at page breaks first, then at paragraph breaks. The part and partCount fields show the order, and the other fields repeat on each part. The word and table counts describe the whole document or page, so count them once per document.

Using it with AI agents

The main inputs are lists, every field is optional, and no credentials are needed. An agent can send many links in one call and read status rows to see what went wrong.

Data and use

This Actor reads only the files you point it to. It refuses private and internal network addresses, including after a redirect, and it keeps no copy beyond this run's own storage. You are responsible for having the right to process each file. Text is extracted with the open-source PDF.js library. This Actor is not affiliated with or endorsed by Adobe, Mozilla or the publisher of any PDF.

Support

Open an issue on the Issues tab with your input and what you expected.