PDF to Markdown + OCR — Structured Document Extraction avatar

PDF to Markdown + OCR — Structured Document Extraction

Pricing

from $1.00 / 1,000 native text pages

Go to Apify Store
PDF to Markdown + OCR — Structured Document Extraction

PDF to Markdown + OCR — Structured Document Extraction

Convert public PDF URLs into clean structured Markdown. Born-digital pages extract natively; scanned or image-only pages are recovered by a built-in OCR engine — no key or setup required. Per-page mode, confidence and partialFailures for PDF to Markdown and scanned PDF extraction pipelines.

Pricing

from $1.00 / 1,000 native text pages

Rating

0.0

(0)

Developer

Heim AI

Heim AI

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Public PDF URL in → structured Markdown out. Born-digital pages extract natively; scanned / image-only pages go through a managed OCR engine. Built for PDF to Markdown, PDF OCR API, scanned PDF extraction, and structured document data pipelines (MCP / API / schedule).

Actor idkaz_kakyo/pdf-structured-ocr
Minimal input{ "pdfUrls": ["https://…/file.pdf"] }
Cost$0.001/native page · $0.012/OCR page · $0.005/document manifest · $0.00005 start
Outputtype: "page" rows + one type: "manifest" per document (or type: "error")

Call it (MCP / API)

{
"actor": "kaz_kakyo/pdf-structured-ocr",
"input": {
"pdfUrls": ["https://example.com/report.pdf"],
"ocr": "auto"
}
}

OCR is included — no setup, no key required. Native-text pages always succeed; if a page needs OCR and OCR capacity is unavailable, it is marked mode: "unavailable" and listed in partialFailures. Very large or image-heavy pages may return unavailable rather than being silently truncated. Billed only for pages actually delivered.

Because OCR capacity is shared across all users, each run caps OCR-billable pages (maxOcrPages, default 100, hard ceiling 200). Native (born-digital) extraction is unaffected by the cap and consumes no OCR capacity.

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('kaz_kakyo/pdf-structured-ocr').call(
{
pdfUrls: ['https://example.com/report.pdf'],
ocr: 'auto',
ocrMaxWaitSecs: 300,
maxPages: 50,
},
{ maxTotalChargeUsd: 1.0 },
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const manifest = items.find((i) => i.type === 'manifest');

Output contract

Page row (charged only when mode is native or ocr):

{
"type": "page",
"url": "https://example.com/report.pdf",
"pageNumber": 1,
"mode": "native",
"confidence": null,
"markdown": "## Introduction\n\n…",
"textCharCount": 1842
}
modeMeaning
nativeBorn-digital text extracted locally
ocrPage recovered by the managed OCR engine
unavailableNeeded OCR but capacity unavailable / OCR failed / budget exhausted — never charged

Manifest (charged only when ≥1 page was delivered):

{
"type": "manifest",
"url": "https://example.com/report.pdf",
"pageCount": 12,
"pagesDelivered": 12,
"markdown": "<!-- page 1 (native) -->\n\n…",
"pages": [{ "pageNumber": 1, "mode": "native", "confidence": null }],
"partialFailures": []
}

Pricing

EventPriceWhen
native-page-delivered$0.001Each saved native-text page
ocr-page-delivered$0.012Each saved OCR page
document-manifest-delivered$0.005Final manifest, only if ≥1 page delivered
apify-actor-start$0.00005Per run
Default dataset item$0Never billed separately

Charge order: budget-check → save dataset row → Actor.charge(). Unavailable / error rows are never billed. Cap spend with maxTotalChargeUsd.

Input

FieldNotes
pdfUrls / pdfUrlPublic http(s) PDF links only
maxPagesDefault 50 (hard cap 500)
ocrauto (default) · never · always
maxOcrPagesDefault 100 (hard ceiling 200); per-run OCR page cap
ocrMaxWaitSecsDefault 300 (max 900); OCR timeout → ocr_timeout, uncharged

Private / localhost / link-local / RFC1918 targets are rejected (SSRF guard, enforced at connect time and on every redirect hop). File size cap: 50 MB, enforced while streaming. PDFs are fetched over direct egress only — no proxy, because a proxy cannot enforce the connect-time address ACL. OCR processes the already-fetched PDF bytes; the source is never re-fetched.

Why this one

  • Structured Markdown, not a blob of OCR text — headings and crude tables from layout when native text exists.
  • Page-level honesty: every page reports mode + confidence; gaps go in partialFailures.
  • OCR only when needed (auto) so born-digital PDFs stay cheap.
  • Billed only for pages actually delivered — timeouts, failures, and capacity limits never charge OCR pages.