Image to Text & Scanned PDF OCR to RAG Chunks avatar

Image to Text & Scanned PDF OCR to RAG Chunks

Pricing

from $2.80 / 1,000 ocr pages

Go to Apify Store
Image to Text & Scanned PDF OCR to RAG Chunks

Image to Text & Scanned PDF OCR to RAG Chunks

Image to text OCR for photos and scanned PDFs: text, Markdown and token-counted chunks with page numbers and a confidence score. Tesseract, 37 languages, no API key. Blank pages and failed files are free. Not affiliated with any OCR vendor.

Pricing

from $2.80 / 1,000 ocr pages

Rating

0.0

(0)

Developer

Muhammet Mustafa Dincer

Muhammet Mustafa Dincer

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

Image to text and scanned PDF OCR: a scanned memo becomes token-counted RAG chunks with page numbers and a confidence score

What is Image to Text & Scanned PDF OCR to RAG Chunks?

Image to Text & Scanned PDF OCR to RAG Chunks reads text from an image or a scanned PDF. Give it links to photos, screenshots, scans or scanned PDFs and you get back:

  • one row per file (recordType: "document") with the recognised text, LLM-ready Markdown with headings and lists, page counts, word count, token count and an overall confidence score;
  • one row per chunk (recordType: "chunk") with the chunk text, its token count, the page numbers it came from and its own confidence score, so your pipeline can cite a page and skip a chunk that was read badly.

It runs the open-source Tesseract OCR engine inside the Actor. There is no API key, no OCR account and no third-party service: the file is downloaded over plain HTTP and recognised on the machine that runs the Actor.

Quick answer: when should you (or an AI agent) pick this Actor?

Pick this Actor when the text you need is trapped in an image: a scanned contract, a photographed receipt, a screenshot of a table, a fax, an old manual, a folder of invoices exported as JPEG, or a PDF that is only pictures of pages. It is also the right tool when the next step is retrieval (RAG): the chunk rows are already inside a token budget, tagged with page numbers, and carry a confidence score you can filter on.

Pick something else when your PDF has a real text layer (one made from Word or LaTeX): it is cheaper and exact to read the text layer directly, for example with PDF to Markdown & RAG Chunks Extractor. Pick something else for handwriting, for pages that must keep a complex table structure, or when you need a cloud vision model's understanding of a picture rather than the characters in it.

Defaults that work: send {"urls": ["https://example.com/scan.jpg"]} and you get a document row and chunks of about 512 tokens, in a couple of seconds per page. For a vector store, send {"urls": [...], "mode": "chunks", "chunkSize": 512, "chunkOverlap": 64} and the dataset is exactly what you feed to embeddings. For German scans add "languages": ["deu"]; for a mix, "languages": ["eng", "deu"].

At a glance

DoesDownloads images and PDFs, straightens and cleans each page, runs OCR, and returns text, Markdown, quality numbers and token-counted chunks with page ranges
Inputurls (or datasetId to read links from another dataset). Optional: languages, mode, chunkSize, chunkOverlap, lowConfidenceBelow, startPage, maxPagesPerFile, pdfDpi, enhance, autoRotate, includeMarkdown, includePages, maxFiles, maxFileSizeMb, maxChunksPerFile, requestsPerSecond
OutputrecordType: "document" rows with text, markdown, confidence, quality, tokenCount, page counts, status; recordType: "chunk" rows with text, tokenCount, pageStart, pageEnd, headings, confidence, lowConfidence
File typesJPEG, PNG, WebP, GIF, BMP, TIFF (also multi-page) and PDF
Languages37, up to 4 per run: English, German, French, Spanish, Italian, Portuguese, Dutch, Turkish, Russian, Ukrainian, Polish, Czech, Swedish, Norwegian, Danish, Finnish, Romanian, Hungarian, Bulgarian, Croatian, Serbian, Slovak, Catalan, Estonian, Latvian, Lithuanian, Hebrew, Arabic, Hindi, Bengali, Indonesian, Vietnamese, Thai, Japanese, Korean, Chinese (Simplified and Traditional)
NeedsNo login, no API key, no browser, no proxy. Only a public http(s) link that returns the file itself
SpeedMeasured: a photographed memo in 1.2 s, a two-page scanned PDF in 2 s; 12 dense A4 pages in 46 to 67 s on 2 GB
PricingPay per event: $0.004 per OCR page and $0.0005 per GB of memory at start on the Free plan (cheaper on paid plans). Blank pages, failed downloads and unreadable files are free
Does notRead handwriting reliably, reconstruct tables as Markdown tables, open password-protected PDFs, or follow a link that shows a viewer page instead of the file

Key terms used in this README

  • OCR (optical character recognition): turning the picture of text into text you can search, copy and embed.
  • Scanned PDF: a PDF whose pages are pictures. It has no selectable text, so a normal PDF parser returns nothing; OCR is the only way to read it.
  • Document row: a dataset row with recordType: "document". One per file, always written, even when the file failed — the reason is in the row.
  • Chunk row: a dataset row with recordType: "chunk". A slice of the document of roughly chunkSize tokens, with pageStart, pageEnd and a confidence.
  • Confidence: the engine's own estimate (0 to 100) of how sure it is about the words it read, averaged over the page and weighted by word length. It is a signal for ranking and filtering, not a measured accuracy.
  • Token count: the number of tokens the text becomes in cl100k_base, the tokenizer used by OpenAI's embedding and chat models. It is counted, not estimated from characters.
  • Overlap: how much of the end of one chunk is repeated at the start of the next, so a sentence that straddles a boundary is still retrievable.
  • OCR page: the billing unit. One image is one page; a PDF is one page per PDF page that contained text.

What can you use it for?

Searchable archives of scanned documents

Turn a shared drive of scanned letters, contracts and forms into text you can search. Keep the document rows and you have a full-text dump with fileName, pageCount, quality and confidence as filters.

RAG over documents that are only pictures

The mode: "chunks" output is a ready-made embedding input: one row per chunk, inside your token budget, with the source URL and page range as metadata. Store pageStart/pageEnd next to the vector and your answer can cite "page 2" instead of guessing.

Receipts, invoices and forms

Small, dense documents read best with a smaller chunk size (256) and languages set to the language printed on the page. The Markdown keeps headings and list items on separate lines, which is what a downstream extraction prompt wants.

Screenshots and photographs of text

Slides, whiteboard photos, signs, error dialogs and screenshots of chat or code. Small images are enlarged before recognition and photographs are straightened by their EXIF orientation, so a phone photo that is sideways still reads.

Agents that can see files but not read them

Point an agent at this Actor through MCP, give it an image URL, and it receives plain text with a confidence it can reason about instead of a binary it cannot open. Chunk rows are flat and identical in shape to the other RAG Actors from this developer.

Crawl, then read what you crawled

Run a crawler or screenshot Actor into a dataset, then pass its dataset ID in datasetId. The Actor finds the image and PDF links in the rows and returns text; you never copy links by hand.

How does it work?

  1. The URL list is built from your urls and, if you set one, from the links found in datasetId. Duplicates are removed and every URL is validated; non-http links and links with a username and password are rejected.
  2. Each file is downloaded directly, with a timeout, a size cap and a retry for transient errors. A 403 or 429 is treated as a refusal: the file is reported as blocked, no more files are requested from that host, and the Actor moves on rather than trying to get around it.
  3. The file type is detected from the bytes, not the URL, so a .jpg that is really HTML is reported as unsupported instead of crashing.
  4. Each page is prepared: EXIF rotation is applied, transparency is flattened onto white, the page is turned grey, its contrast is stretched and small images are enlarged. PDFs are drawn page by page at pdfDpi (200 by default).
  5. Tesseract reads the page. If the result is poor, the Actor checks whether the page is sideways or upside-down, turns it and reads it again. This costs nothing extra.
  6. The word positions are turned into Markdown: lines become paragraphs, large text becomes # and ## headings, bullets and numbered items become lists and hyphenated line breaks are joined.
  7. Pages are packed into chunks until the token budget is reached, and every chunk gets its own confidence. A page with no text, or one that reads as noise, is marked blank or unreadable and is not charged.
  8. Rows are written. Only pages with text are charged; chunk rows are free, so chunk size never changes the bill.

How to OCR an image or scanned PDF (step by step)

  1. Open the Actor and paste one or more image or PDF URLs in the input, one per line, for example https://example.com/scan.jpg.
  2. Set Languages to the language printed on the page. English is the default; add a second language only if the page really mixes two.
  3. Leave What to return on Document and chunks for a first look, or choose Chunks only if you are feeding embeddings.
  4. Set Chunk size to 512 for general retrieval. Use 256 for receipts and narrow facts and 1024 or more for long arguments.
  5. For a long PDF, set First page and Maximum pages per file so you only pay for the pages you need.
  6. Click Start. In the Output tab open the Documents view to read the text and quality, or the Chunks view for the embedding input.
  7. Download the dataset as JSON, JSONL, CSV or Excel, or read it from the API; recordType tells the two kinds of row apart.

Input

FieldTypeDefaultWhat it does
urlslist of texttwo example filesDirect links to image files or PDFs, up to 200 per run. A link that shows a web page instead of the file is reported as unsupported_type
datasetIdtextemptyRead links from an existing Apify dataset. Looks for imageUrl, fileUrl, pdfUrl, screenshotUrl, url, link and similar fields
languageslist of choicesengUp to 4 languages that appear in the text. The first matters most. Each extra language slows recognition
modechoicebothboth writes document and chunk rows; chunks writes only chunks; document skips chunking
chunkSizenumber512Token budget per chunk (64–4096), counted in cl100k_base
chunkOverlapnumber64Tokens repeated from the previous chunk, in whole paragraphs, at most half of chunkSize
lowConfidenceBelownumber70Chunks under this confidence get lowConfidence: true. Nothing is removed
startPagenumber1First page of a PDF or multi-page TIFF to read, 1-based
maxPagesPerFilenumber50Pages read from one file, up to 200
pdfDpinumber200Resolution a PDF page is drawn at (100–300). Use 300 for small type, 150 for faster reads
enhanceyes/noyesGrey, contrast and enlarge before recognition. Turn off only for clean scans at a good size
autoRotateyes/noyesFix sideways and upside-down pages when the first read is poor
includeMarkdownyes/noyesAdd the markdown field to the document row
includePagesyes/nonoAdd a pages array with status, confidence, size and text of every page
maxFilesnumber100Upper bound on files read in one run
maxFileSizeMbnumber50Skip files larger than this instead of downloading them
maxChunksPerFilenumber1000Safety cap on chunk rows for one file
requestsPerSecondnumber2Download rate per host. Lower it to 1 when every file comes from one small server
concurrencynumberby memoryPages read at the same time. Default is about one per GB of run memory
proxyConfigurationproxyoffOnly needed when an image host blocks data-centre IPs

Output

Every run writes one dataset with two kinds of rows. Filter on recordType.

Document row. Real output for a photographed memo (text and Markdown shortened here):

{
"recordType": "document",
"url": "https://example.com/memo.jpg",
"fileName": "ocr-sample-memo.jpg",
"status": "processed",
"failureReason": null,
"message": null,
"fileType": "image",
"contentType": "image/jpeg",
"fileSizeBytes": 208663,
"pageCount": 1,
"pagesProcessed": 1,
"pagesWithText": 1,
"pagesWithoutText": 0,
"pagesNotProcessed": 0,
"languages": "eng",
"confidence": 93.3,
"quality": "good",
"charCount": 930,
"wordCount": 156,
"tokenCount": 207,
"chunkCount": 1,
"text": "Harbor Lane Cooperative\n\nOperations memo: winter dispatch schedule\n\nTo all depot leads. From 3 December…",
"markdown": "# Harbor Lane Cooperative\n\n## Operations memo: winter dispatch schedule\n\nTo all depot leads. From 3 December…",
"pages": null,
"durationMs": 1184,
"processedAt": "2026-11-04T11:21:56.607Z"
}

Chunk row. From a run with chunk size 128:

{
"recordType": "chunk",
"url": "https://example.com/memo.jpg",
"documentTitle": "ocr-sample-memo.jpg",
"chunkIndex": 1,
"text": "## Why we are doing this\n\nLast winter 41 percent of late deliveries were caused…",
"tokenCount": 89,
"charCount": 391,
"pageStart": 1,
"pageEnd": 1,
"headings": ["Why we are doing this"],
"isPartial": false,
"confidence": 95.4,
"lowConfidence": false
}

Sample output: document rows with page and confidence, and chunk rows with page ranges, token counts and per-chunk confidence

Field notes:

  • status is processed, empty or failed. Only pages with text inside a processed file are charged.
  • failureReason when a row is not processed: invalid_url, unsupported_type, too_large, blocked, stopped_after_block, http_error, network_error, password_protected, corrupt, ocr_error, budget_reached or no_text_found.
  • confidence on the document is the mean over its pages with text; quality is a plain band for it: good (85 or more), fair (60 to 84), poor (under 60). The bands are ours, not the engine's.
  • A page with fewer than three letters or digits is blank; a page whose confidence is under 25 is unreadable. Both are listed in pagesWithoutText and are free.
  • pagesNotProcessed counts pages cut off by startPage or maxPagesPerFile.
  • pageStart and pageEnd on a chunk are the pages of the text inside it. A chunk that spans a page break reports both, which is why the citation is a range.
  • headings lists the nearest heading before the chunk plus any heading inside it. Headings are inferred from text height, so they are right for typical memos, reports and forms and are a hint rather than a guarantee.
  • isPartial is true when a paragraph had to be cut to respect the chunk size.
  • text and markdown are null when the file failed or the option is off. pages is null unless includePages is on.
  • Page headers and footers are not removed: a "page 1 of 2" footer at the foot of a page appears in the text where it sits on the page.

How much does it cost?

You pay per OCR page, never per chunk, so changing the chunk size never changes the bill.

EventWhenFree plan price
Actor startonce per run, one event per GB of memory (2 GB by default)$0.0005 per event
OCR pageeach page in which text was found and recognised$0.004

Paid Apify plans get a lower per-page price: $0.0036 (Bronze), $0.0032 (Silver) and $0.0028 (Gold and above). Blank pages, pages that read as noise, failed and blocked downloads, unsupported and corrupt files, and pages outside your startPage/maxPagesPerFile window are free.

Examples

  • One receipt photo: $0.001 + $0.004 = $0.005.
  • A 20-page scanned contract: $0.001 + 20 × $0.004 = $0.081.
  • 1,000 single-page scans: $0.001 + 1,000 × $0.004 = $4.00.
  • 1,000 scans of which 100 are blank or unreadable: $0.001 + 900 × $0.004 = $3.60.

Set a maximum cost per run in the run options to cap spending. The Actor checks the remaining budget before each file and stops cleanly at the limit; files it did not reach are reported as budget_reached and cost nothing.

Measured cost. Runs on this Actor, 2026-11-04, default 2 GB of memory:

RunPagesChunksWall clockPlatform usage
Example input (1 photo, 1 two-page PDF)3210.6 s$0.0012
12 dense A4 pages, 2 pages at a time12—67 s$0.0076
12 dense A4 pages, 3 pages at a time12—46 s$0.0053

Recognition is CPU-bound, so the platform cost is about $0.0004 to $0.0007 per page on a dense page, with some variation from run to run. That is roughly 10 to 18% of the $0.004 list price on the Free plan.

Note on the numbers above: they were measured on runs on this Actor. As the Actor's owner, my own runs are not billed to a customer, so "list price" is what a customer would pay, not money this Actor has earned.

Image to text and scanned PDF OCR compared with other approaches

This ActorOther OCR Actors in the StoreYour own Tesseract setupCloud OCR API
OutputText, Markdown, token-counted chunksUsually text onlyYou build itText and layout, JSON
Page numbers on every chunkYesRarelyYou build itPer page
Confidence per chunk, with a flagYes (lowConfidence)RarelyRaw per-word numbersPer word or line
Blank pages and failures chargedNoVariesYour timeUsually yes
Reads links from another datasetYes, datasetIdSometimesYou build itYou build it
Needs an API key or cloud accountNoNoNoYes
HandwritingNoMostly noNoOften better
Price per 1,000 pages$4.00 on the Free planAbout $2 to $15Your servers and timeAbout $1.50 and up

Several image and PDF OCR Actors already exist, so this is not an empty niche — compare before you pick. Where this one is different is narrower than "we are the only ones": the output is shaped for retrieval (token-budgeted chunks with page ranges, the same row format as this developer's other RAG Actors), every chunk carries a confidence you can filter on, pages that are blank or unreadable are not charged, and a sideways or upside-down page is turned and read again automatically. It uses an open-source engine, so on handwriting and very poor photographs a cloud vision service will read better; this Actor is for printed text.

Competitor prices change; the figures above are from the Store listings on 2026-11-04 and are a range, not a quote.

Tips for best results

  • Set the language. The wrong language is the most common reason for poor reads. Pick what is on the page; add a second only for genuinely mixed pages.
  • Use 300 DPI for small type. pdfDpi: 300 is slower and reads six-point print better; 150 is faster for large, clean headings.
  • Keep enhance on unless your images are already clean scans at 300 DPI. Phone photos and small screenshots gain the most.
  • Filter on lowConfidence. Drop or review chunks under your threshold before embedding; a badly read chunk is worse than a missing one.
  • Use mode: "chunks" for a production embedding job: the dataset then contains only chunk rows and your loader needs no filter.
  • Skip the cover and the index of long PDFs with startPage; each page with text is one charged page.
  • Look at quality on the document rows after a first small run before you pay for a thousand files.

Limits and good to know

  • Printed text only. Handwriting is read poorly or not at all. Confidence will be low and lowConfidence will say so.
  • Not a table extractor. Table cells are read as text lines; the content is there but the grid is not rebuilt as a Markdown table.
  • Multi-column pages are read in the engine's layout order, which is correct for most reports and papers and can interleave columns on busy magazine layouts.
  • Repeated headers, footers and page numbers are left out when the same short line sits at the top or bottom of at least half the pages (two or more). A one-page image is unchanged, so a title is not removed. The document row says how many lines were left out.
  • Password-protected PDFs are not opened. They are reported as password_protected and are not charged.
  • A viewer link is not a file link. If the URL returns an HTML page, the row says unsupported_type; open the link in a browser, use the download button and copy the direct file URL.
  • Size limits. Up to 200 pages per file, 100 MB per file (50 MB by default) and images are shrunk when a side exceeds 4,500 pixels.
  • Confidence is an estimate, not a measured accuracy. A clean scan scores 90 or more; a blurred phone photo can score 60 and still be mostly right.
  • Text is not summarised, translated or corrected. What the engine reads is what you get, including its mistakes.

Use it from AI agents, the API and code

Apify MCP server (ChatGPT, Claude, Cursor and other MCP clients). Connect https://mcp.apify.com, then:

  1. search-actors with a query such as image OCR to text RAG chunks.
  2. fetch-actor-details for mmdincer/image-ocr-rag to read the input schema.
  3. call-actor with the input below.
  4. get-dataset-items with the returned dataset ID and recordType: "chunk" as your filter.
{
"actor": "mmdincer/image-ocr-rag",
"input": {
"urls": ["https://example.com/scan.jpg"],
"languages": ["eng"],
"mode": "chunks",
"chunkSize": 512,
"chunkOverlap": 64
},
"callOptions": { "maxTotalChargeUsd": 0.5 }
}

To give an MCP client this Actor as its own tool (no search step), connect https://mcp.apify.com?tools=mmdincer/image-ocr-rag.

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('mmdincer/image-ocr-rag').call(
{ urls: ['https://example.com/scan.jpg'], mode: 'chunks', chunkSize: 512 },
{ maxTotalChargeUsd: 0.5 },
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const reliable = items.filter((row) => row.recordType === 'chunk' && !row.lowConfidence);

Python

import os
from decimal import Decimal
from apify_client import ApifyClient
client = ApifyClient(token=os.environ['APIFY_TOKEN'])
run = client.actor('mmdincer/image-ocr-rag').call(
run_input={'urls': ['https://example.com/scan.jpg'], 'mode': 'chunks', 'chunkSize': 512},
max_total_charge_usd=Decimal('0.5'),
)
items = client.dataset(run['defaultDatasetId']).list_items().items
reliable = [row for row in items if row['recordType'] == 'chunk' and not row['lowConfidence']]

HTTP (one request, returns the rows)

curl -X POST "https://api.apify.com/v2/acts/mmdincer~image-ocr-rag/run-sync-get-dataset-items?maxTotalChargeUsd=0.5" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls": ["https://example.com/scan.jpg"], "mode": "chunks", "chunkSize": 512}'

The synchronous endpoint waits for the run, so use it for a handful of files. For a large batch, start the run asynchronously and read the dataset when it finishes.

Automation recipes

Scanned archive to vector store. Save the input as a task. After each run, send the chunk rows that are not lowConfidence to your embedding endpoint and upsert them keyed on url + chunkIndex.

Crawl, then OCR. Run a crawler or screenshot Actor into a dataset, then run this Actor with datasetId set to that dataset's ID. Image links are found in the rows and the text lands in a new dataset.

Review queue in a spreadsheet. Fetch the dataset as CSV and sort by confidence. status, failureReason and quality make it obvious which files need a better scan before you rely on them.

Zapier or Make. Use Apify as the trigger for a finished task run, add the step that gets dataset items, filter recordType equal to chunk, then send the rows on. See the Apify Zapier integration and the Apify Make integration.

Budget guard. Set a maximum cost per run on the task. The Actor stops with stoppedForBudget: true in the run summary instead of overspending.

The Actor downloads the files you point it at, one at a time, at a low request rate, with a normal browser User-Agent. It does not crawl a site on its own, does not guess URLs, does not log in, does not read anything behind a paywall, and does not try to get around a 403, a 429 or a bot challenge: it reports the refusal in the dataset and stops asking that host.

That makes the legal question mostly about the files you choose, not about the tool. Documents you own, documents your organisation produced, public-domain material and openly licensed images are the normal case. An image you are not allowed to copy is not made lawful by recognising its text. Check the terms of the site you take it from and the licence of the document itself.

Personal data. Scans of IDs, medical records, payslips and similar documents contain personal data. The text goes to your dataset in your Apify account and nowhere else, but you remain responsible for having a lawful basis to process it and for how long you keep the dataset.

Copyright. Recognised text is a copy of the document. Indexing it for your own search is one thing; republishing it is another. The Actor claims no rights over the content and gives you none.

No affiliation. This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by Google, the Tesseract project, ABBYY, Adobe or any OCR vendor; product names are used only to describe what the Actor does and what it is built on. Tesseract is open-source software released under the Apache License 2.0.

If you are the owner of a file and want a source removed from your own runs' data, delete the run's dataset in your Apify account; the Actor itself stores nothing outside your run.

FAQ

How do I extract text from an image?

Paste the image URL in Image and PDF URLs, set Languages to the language on the picture and click Start. The document row has the text and Markdown, and the chunk rows have the same text cut for retrieval.

Does it work on scanned PDFs?

Yes. A scanned PDF is drawn page by page at pdfDpi (200 by default) and each page is read like an image. If your PDF has a selectable text layer, a text-layer extractor is cheaper and exact; this Actor will still read it, as a picture.

Which languages are supported?

37, listed in the table above, up to four per run. Add the language printed on the page; combining two (for example English and German) works for mixed documents but is slower.

Why is the confidence low?

Blur, a small image, a decorative font, handwriting, a heavy background or the wrong language. Try a larger image, pdfDpi: 300 for PDFs, enhance on, and make sure Languages matches the page. Chunks under your lowConfidenceBelow threshold are flagged, never silently dropped.

Why did my page come back as blank or unreadable?

A page with almost no letters or digits is blank; a page the engine could barely read is unreadable. Both are free. If you expected text, check the image at full size and the language setting.

How do I get chunks for a vector database?

Set What to return to Chunks only, choose a Chunk size that matches your embedding model's budget (512 is a good default) and leave the overlap at 64. Every chunk row has text, tokenCount, pageStart, pageEnd, headings and confidence.

Are the token counts real?

Yes. They are counted with cl100k_base, the tokenizer behind OpenAI's embedding and chat models, not estimated from characters. A different model family tokenizes slightly differently, but the numbers stay close enough to plan a budget.

The URL returned something that is not an image or a PDF — usually an HTML page. This happens when the link opens a viewer, when the file needs a login or when the site shows a cookie wall. Open the link in a browser, use the download button and copy the direct file URL.

Yes, that is what Read links from a dataset is for. Give the dataset ID and the Actor looks for imageUrl, fileUrl, pdfUrl, screenshotUrl, url, link and similar fields. Both the pasted list and the dataset are merged and deduplicated.

Can I process only some pages?

Yes. First page and Maximum pages per file limit what is read and what is charged. A 200-page manual you need three pages from costs three pages.

Does it read handwriting?

Not reliably. The engine is built for printed text. Handwriting usually comes back with low confidence, and the flag tells you so.

What happens if one file fails in a batch?

Nothing else stops. The failed file writes its own row with failureReason and a readable message, the run continues with the next link, and the run summary lists the first failures. The run only fails when no file could be read at all.

How much does a run cost?

A single-page scan is about $0.005 on the Free plan; 1,000 one-page scans about $4.00. Pages with text are what drive the price, so maxPagesPerFile is the lever. Set a maximum cost per run to hard-cap it.

Do I need a proxy?

Normally no. Files are downloaded directly. Use Apify Proxy only when a host blocks data-centre IPs, and note that the Actor still stops at a refusal instead of trying to defeat a challenge.

Can I use the output commercially?

The Actor gives you recognised text; whether you may use that text commercially depends on the document's licence and the site's terms, not on this tool. See the legal section above and take your own advice.

These are other Actors by the same developer. They are separate tools; this README does not depend on them.

RAG family: the same chunk format for other sources

Other tools