Skip to content
Search/
CyberMax › Answers

How to convert PDF, Word and PowerPoint files to text and Markdown in bulk

Updated 2026-11-12 · Data and API builders · by CyberMax

Short answer

Send the document links to a converter that reads the PDF text layer page by page, keeps headings, lists and tables as Markdown and reads two-column papers in order. Pageshuck on Apify does this for PDF, Word and PowerPoint files at $0.003 per document, with no start fee; failed and scanned files are not charged.

  1. List the document URLs (PDF, DOCX or PPTX), one per row. Files up to 100 MB and 500 pages work by default.
  2. Pick the output: formats ["markdown", "text"], one row per document, or outputMode "pages" for one row per page with page numbers.
  3. For RAG, set chunkSize (for example 1500 characters): chunks end at paragraph and sentence breaks.
  4. Check status: ok, no-text (a scan, flagged needsOcr) or error (404, password-protected, too big). Only ok rows are charged.
  5. Schedule the same input with monitor on to get only new or changed documents later.

Copy-paste code

Python (pip install apify-client): PDF links in, Markdown files out

import os, pathlib
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("cybermax/pdf-to-text").call(run_input={
    "urls": ["https://www.irs.gov/pub/irs-pdf/fw9.pdf", "https://arxiv.org/pdf/1810.04805"],
    "formats": ["markdown", "text"],
    "chunkSize": 1500,
})
out = pathlib.Path("md"); out.mkdir(exist_ok=True)
for i, r in enumerate(client.dataset(run["defaultDatasetId"]).iterate_items()):
    if r["status"] == "ok":
        (out / f"doc{i}.md").write_text(r["markdown"])
    print(r["url"], r["status"], r.get("pageCount"), r.get("words"))

JavaScript / Node (npm i apify-client)

import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('cybermax/pdf-to-text').call({
  urls: ['https://example.com/contract.docx', 'https://example.com/pitch.pptx'],
  outputMode: 'pages',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const r of items) console.log(r.url, 'page', r.page, (r.text || r.error || '').slice(0, 80));

No code: n8n, Make or Zapier

n8n: HTTP Request node (or the Apify node, action "Run an Actor and get dataset")
Method:  POST
URL:     https://api.apify.com/v2/acts/cybermax~pdf-to-text/run-sync-get-dataset-items
Auth:    Header Auth  ->  Authorization: Bearer <your Apify token>
Body:    JSON  {"urls": {{ $json.pdfLinks }}, "formats": ["markdown"]}
Output:  one n8n item per document (markdown, text, pageCount, words, metadata)

Make:    Apify app -> "Run an Actor" (Actor: cybermax/pdf-to-text, wait for finish = yes)
         -> Apify "Get Dataset Items" (dataset = the run's defaultDatasetId) -> your next module
Zapier:  Apify app -> action "Run Actor" (cybermax/pdf-to-text, input JSON as above)
         -> trigger "Finished Actor Run" -> "Fetch Dataset Items" -> your app
Runs longer than 5 minutes: start with POST /v2/acts/cybermax~pdf-to-text/runs and read the dataset when the run finishes.

From an AI agent (MCP)

# Any MCP client (Claude Desktop, Claude Code, Cursor, VS Code): Apify's hosted MCP server
{
  "mcpServers": {
    "pdf-to-text": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.apify.com/?tools=cybermax/pdf-to-text",
               "--header", "Authorization: Bearer ${APIFY_TOKEN}"],
      "env": { "APIFY_TOKEN": "<your Apify token>" }
    }
  }
}
# The agent sees one tool, cybermax--pdf-to-text, with the Actor's input schema.
Real run on Apify (10 Nov 2026: 5 links, 3 documents and 23 pages in 2.9 s; the 403 and 404 links were not charged)
DocumentTypePagesWords
IRS Form W-9 (fw9.pdf)pdf66,525
BERT paper (arXiv, two columns)pdf1610,654
calibre demo.docxdocx31,650

Source: Pageshuck (Apify Actor cybermax/pdf-to-text) README, real Apify run on 10 Nov 2026

Run Pageshuck on ApifyDocsieve: website to Markdown

PDF to Markdown for RAG and LLMs

Plain text loses the structure a model needs. Markdown keeps headings, bullet lists and tables, so chunks split on real sections and tables stay readable. Pageshuck also rejoins words split across lines and puts two-column research papers back in reading order.

Word and PowerPoint in the same run

DOCX and PPTX links go in the same list as PDFs and come back in the same shape: Markdown, text, page or slide count, words and document metadata.

Scanned PDFs need OCR

A scan has no text layer. Pageshuck flags it with needsOcr and does not charge a fully scanned file; export those pages as images and read them with Inkscry, the CyberMax image-to-text OCR Actor.

Good to know

Price on Apify: $0.003 per document ($3 per 1,000), no start fee and no per-page fee. Failed, password-protected and fully scanned files are free. Apify's free plan includes $5 of usage each month.

Use it on documents you own or are allowed to process; it converts only the files you link to.

Docsieve icon

Docsieve: Websites to clean Markdown for RAG

$0.001 per page, no start fee

Converting web pages rather than files? Docsieve crawls a website or docs site into clean Markdown, RAG chunks and llms.txt at $0.001 per page.

Runs on your own Apify account, pay per result; failed results are not charged.

Questions

Does it keep tables?

Yes. Tables come out as GitHub Markdown tables in the markdown field, and as tab-separated cells in text.

Can I get one row per page?

Yes. Set outputMode to pages for one row per page with its page number, useful for citations.

How big can a file be?

Up to 100 MB and 500 pages by default; raise maxFileSizeMb (300 max) and maxPages (5,000 max). The price per document stays the same.

Can an AI agent use it?

Yes. Apify's MCP server exposes it as cybermax--pdf-to-text for Claude, Cursor and other MCP clients.

Free: the Free API Starter Kit

Copy-paste calls for 4 APIs with free daily tiers (CVE priority, VIN recalls, US duty rates, email checks), then 5 short emails on KEV/EPSS, MCP and free data.

You get one email to confirm first. Then the kit, and 5 short emails over two weeks. One-click unsubscribe in every email; we never share your address.

Related answers

How to convert a whole website to Markdown for RAG, with llms.txtCrawl a website or docs site into clean Markdown, heading-aware RAG chunks with token counts, and llms.txt filHow to extract text from images in bulk with an image to text OCR APIRead the text in screenshots, scans, photos and receipts in 100+ languages, with confidence and line boxes. Ge