PDF & Image to Text OCR for AI Agents - No Login icon

AI & documents · Live on Apify

PDF to Text OCR: Turn PDF and Image Links into Clean Text

Give a link to a PDF or an image. You get its text back, page by page. Normal PDFs are read directly, and scanned pages go through OCR.

About $2.50 for 1,000 documents$0.0025 per document + $0.005 per run. Apify bills you, not us.Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed.

Run it on Apify Opens apify.com, the website where our tools run. Sign up free with Google or email, no card needed.

Apify links on this page are affiliate links. We may earn a commission. You pay the same price. Affiliate disclosure

How to use it: 3 steps

  1. Make a free Apify accountApify is the cloud platform where our tools run. The free plan gives you $5 of usage every month, no credit card needed. You pay Apify, not us.
  2. Paste your input and press StartNo code needed: you fill in a form (the input). It already has a working example. For example: https://www.irs.gov/pub/irs-pdf/fw9.pdf in PDF or image URLs. Each start is one run.
  3. Download the resultsWhen the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

This tool is an Apify Actor: a small program that runs on Apify. You can also run it on a schedule, for example every Monday. New to it? Read how it works, step by step and the 8 words you need first.

What it does

Turn public PDF and image URLs into clean text or Markdown. The Actor reads the PDF text layer when a page has one, and runs Tesseract OCR on scanned pages and images, page by page. No login, no API key. A run with one text PDF costs about $0.0075; each OCR page adds $0.012.

  • Downloads the file and checks its real type from the file content (not from the URL).
  • Reads every selected page of a PDF:
  • Text layer: if the page has real text, it is read directly. This is fast and exact.
  • OCR: if the page is a scan (no usable text), it is rendered at 300 DPI and read with Tesseract OCR.
  • Reads images (PNG, JPG, TIFF, GIF, BMP, WEBP) with OCR.
  • Saves the text as plain text or Markdown to the Dataset, with page numbers, method (text or ocr) and OCR confidence.
  • Deletes the downloaded file. Documents and page images are never stored.

Good for

  • AI agents and RAG pipelines: get clean text from a PDF link, one row per page, ready for chunking.
  • Scanned archives and forms: read old scans that have no text layer.
  • Mixed batches: text PDFs, scans and photos of documents in one run, with clear status per file.

Who uses it

AI agent builders

Let your agent read a PDF link and get text it can use.

Archive and records teams

Turn old scans without a text layer into searchable text.

Developers with mixed files

Send text PDFs, scans and photos in one run and get a status for each.

Price

Pay per event: you pay for each result the tool saves, plus a small start fee for each run. The price includes Apify platform costs. Apify bills you, not us. Prices below are for the Apify free plan.

What you pay forPriceWhen
Start fee$0.005Charged once per run. This tool uses 1 GB of memory or less by default; more memory costs more.
Document (text layer)$0.0025 (from $0.0022 on paid Apify plans)One document with at least one page read from the PDF text layer, or a PDF checked with OCR off that has no text layer. In page mode, one event per started 50 text-layer page rows. Failed and not-found documents are not charged.
OCR page$0.012 (from $0.0105 on paid Apify plans)One page (or image) read with OCR, charged once per selected OCR language. Failed pages are not charged.

Examples

  • One document: about $0.0075.
  • 1,000 documents: about $2.50.
  • Every day 100 documents, for 30 days: about $7.65 a month.

Free to try: the Apify free plan gives you $5 of usage every month, no credit card needed. That is enough for about 1,900 documents.

Prices checked on 24 October 2026. See the current price on Apify.

Questions

Can it read handwriting?

Not well. OCR here reads printed text. Handwriting gives poor or empty results.

Do you keep my files?

No. The file is deleted after reading. Only the text is saved in your dataset.

Will my tables stay as tables?

No. Table text comes out as lines, without columns. Try our PDF to Markdown tool for tables.

Can I upload a file from my computer?

No. It works with public links only. Put the file online first, then paste the link.

Do I need a login or an API key for the documents?

No. The Actor reads public URLs only. It does not send cookies or passwords, and it does not open private network addresses.

Do you keep my documents?

No. Each file is downloaded to a temporary folder and deleted after it is read. Only the extracted text is saved to your Dataset. Make sure you have the right to process the documents you send.

Why did I pay for OCR on a PDF?

In auto mode, pages without usable text (scans, or pages with fewer than 25 visible characters or mostly broken glyphs) are read with OCR. Use ocr: never if you want the text layer only. With ocr: never a PDF is still charged as one document, also when it turns out to have no text layer.

Is OCR 100% correct?

No. Tesseract is good on clean printed text and weaker on low-quality scans, small print, handwriting and complex layouts. Check ocrConfidence.

Is the output the same as other PDF text extractors?

The text is similar, but field names are different (for example text and status). Map the fields when you switch.

Details

Step by step on Apify
  1. Open the Input tab.
  2. Keep the two prefilled urls (an IRS W-9 form and a small test image), or add your own PDF or image URL.
  3. Keep OCR mode auto and OCR languages English.
  4. Click Start.
  5. Open the Documents view in the Output tab and check status, textPages, ocrPages and text.
Use cases
TaskInputYou getKey fieldsNext step
Give an AI agent the text of a PDF linkurlsdocument rowtext, pageCount, titleMCP tool call, LLM prompt
Split documents into pages for RAGurls, outputMode: pagepage rowpageNumber, text, methodChunking, vector database
Read a scanned archiveurls, ocr: auto, languagesdocument rowocrPages, pages[].ocrConfidence, textSearch index, review queue
Get headings and lists as Markdownurls, outputFormat: markdowndocument rowtext, formatNotes, knowledge base
Read only part of long reportsurls, pages: "1-3"document rowpagesProcessed, textSummaries, alerts
Tips for better results
  • Use a page range for long reports. You pay OCR only for the pages you read.
  • Check the OCR confidence on each page. Low numbers mean you should check the page by hand.
  • Use PDF, not multi-page TIFF, for long scans. A TIFF is read in one OCR call with a time limit.
Limits and good to know

In document mode, a document gets status: partial when some pages were read and others failed (for example one OCR page timed out) or the run stopped in the middle of it (deadline or cost limit). Read pages keep their text; failed pages have pages[].error. Only read pages are charged. In page mode there is no partial status: each page row is complete or error, and a stop is listed in warnings and RUN_SUMMARY.

  • No handwriting. Tesseract reads printed text; handwritten text gives poor or empty results
  • Tables are not rebuilt. Table text comes out as lines, without columns
  • No Chinese, Japanese or Korean OCR. PDFs in these languages still work if they have a text layer
  • No files behind a login, cookies or a private network. No uploads: only URLs
  • No DOCX, HTML or EPUB. An HTML page gives the error UNSUPPORTED_FILE_TYPE
  • A multi-page TIFF is read with one OCR call, which must finish within the time limit of one OCR page (50 seconds at 1 GB). Use PDF for long scans
  • Up to 100 URLs per run. 100 text PDFs took 31 seconds in our test
  • Up to 300 pages per document (maxPages). A 300-page text PDF took about 17 seconds

For developers

Sample result

One result from a real test run, in JSON. Real values change from run to run. In Excel or CSV each field is a column.

one result · JSON
[
  {
    "url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf",
    "finalUrl": "https://www.irs.gov/pub/irs-pdf/fw9.pdf",
    "status": "complete",
    "fileType": "pdf",
    "contentType": "application/pdf",
    "fileSizeBytes": 140815,
    "pageCount": 6,
    "pagesProcessed": 6,
    "pagesTruncated": false,
    "textPages": 6,
    "ocrPages": 0,
    "format": "text",
    "ocrLanguages": null,
    "charCount": 37820,
    "text": "W-9\n\nForm\n(Rev. March 2024)\nDepartment of the Treasury\nInternal Revenue Service\n\nRequest for Taxpayer\nIdentification Number and Certification…",
    "pages": [
      { "pageNumber": 1, "method": "text", "charCount": 5703, "ocrConfidence": null, "text": "W-9\n\nForm\n(Rev. March 2024)…", "error": null }
    ],
    "title": "Form W-9 (Rev. March 2024)",
    "metadata": { "subject": "Request for Taxpayer Identification Number and Certification", "creator": "Designer 6.5", "pdfVersion": "1.7" },
    "encrypted": false,
    "error": null,
    "warnings": [],
    "fetchedAt": "2026-10-13T05:23:31.200Z",
    "processedAt": "2026-10-13T05:23:31.254Z"
  },
  {
    "url": "https://raw.githubusercontent.com/tesseract-ocr/tessdoc/main/images/eurotext.png",
    "status": "complete",
    "fileType": "png",
    "pageCount": 1,
    "textPages": 0,
    "ocrPages": 1,
    "ocrLanguages": ["eng"],
    "charCount": 414,
    "text": "The (quick) [brown] {fox} jumps!\nOver the $43,456.78 <lazy> #90 dog\n& duck/goose, as 12.5% of E-mail\nfrom [email protected] is spam.…",
    "pages": [
      { "pageNumber": 1, "method": "ocr", "charCount": 414, "ocrConfidence": 90.2, "text": "The (quick) [brown] {fox} jumps!…", "error": null }
    ],
    "title": null,
    "metadata": null,
    "error": null,
    "warnings": []
  }
]

Use it from code

Actor ID: cliqtomedia/pdf-text-ocr. You need your Apify API token from Apify Console → Settings → API & Integrations.

Python · apify-client
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cliqtomedia/pdf-text-ocr").call(run_input={
    "urls": [
        "https://www.irs.gov/pub/irs-pdf/fw9.pdf"
    ],
    "ocr": "auto"
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
cURL
curl -X POST "https://api.apify.com/v2/acts/cliqtomedia~pdf-text-ocr/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://www.irs.gov/pub/irs-pdf/fw9.pdf"], "ocr": "auto"}'
LangChain · langchain-apify
# pip install langchain-apify
# set APIFY_TOKEN in your environment
from langchain_apify import ApifyActorsTool

tool = ApifyActorsTool("cliqtomedia/pdf-text-ocr")
result = tool.invoke({"run_input": {"urls": ["https://www.irs.gov/pub/irs-pdf/fw9.pdf"], "ocr": "auto"}})
print(result)

The cURL call waits for the results, up to 300 seconds. For longer runs, start a run (/runs) and get the results with a webhook or by checking the run. Apify API docs. LlamaIndex, MCP for AI agents and the JavaScript client: AI agents & MCP.

Data fields (26)
FieldTypeMeaning
urlstringInput URL as given.
finalUrlstringURL after redirects; null when the file was not downloaded.
statusstringcomplete, partial (some pages failed or were not processed), not_found (HTTP 404/410) or error.
fileTypestringDetected type from the file content: pdf, png, jpg, tiff, gif, bmp or webp.
contentTypestringContent-Type header sent by the server (document rows).
fileSizeBytesintegerDownloaded size in bytes (document rows).
pageCountintegerTotal pages in the document (1 for single images); null if unknown.
pagesProcessedintegerPages read successfully (document rows).
pagesTruncatedbooleantrue when maxPages cut the page selection (document rows).
textPagesintegerPages taken from the PDF text layer (document rows). In document mode all of them together are charged as one document event.
ocrPagesintegerPages read with OCR, each charged as one ocr-page event per selected OCR language (document rows).
pageNumberintegerPage number, 1-based (page rows).
methodstringHow the page was read: text (PDF text layer), ocr, or none (no text found with OCR off) (page rows).
ocrConfidencenumberTesseract mean word confidence 0–100 for OCR pages; null for text-layer pages (page rows).
formatstringtext or markdown.
ocrLanguagesarrayOCR languages used, when any page was OCRed (document rows).
charCountintegerCharacters in text.
textstringExtracted text of the document (document rows, pages joined) or of the page (page rows). null on error.
pagesarrayPer page: pageNumber, method, charCount, ocrConfidence, text, error (document rows).
titlestringTitle from the PDF metadata; null when the PDF has none.
metadataobjectPDF metadata as reported by the file: author, subject, keywords, creator, producer, creationDate, modificationDate, pdfVersion. Not verified (document rows).
encryptedbooleantrue when the PDF is encrypted (it may still be readable) (document rows).
errorobjectError for this row: {code, message}, e.g. NOT_FOUND, FILE_TOO_LARGE, UNSUPPORTED_FILE_TYPE, PDF_PASSWORD_REQUIRED, DOWNLOAD_TIMEOUT, DEADLINE_REACHED, TOO_MANY_FAILURES; null when there is none.
warningsarrayNotes such as truncated pages or pages without a text layer.
fetchedAtstringWhen the file was downloaded (ISO 8601).
processedAtstringWhen the row was written (ISO 8601).
Input settings (9)

The main fields of the input form. With the API you send them as JSON.

SettingName in the APITypeExample value
PDF or image URLs requiredurlsarray["https://www.irs.gov/pub/irs-pdf/fw9.pdf", "https://raw.githubusercontent.com/tesserac…
OCR modeocrstring"auto"
OCR languageslanguagesarray["eng"]
Pagespagesstring
Max pages per documentmaxPagesinteger50
Text formatoutputFormatstring"text"
RowsoutputModestring"document"
Keep column layout (text layer)preserveLayoutbooleanfalse
Max file size (MB)maxFileSizeMbinteger50

Use cases with this tool

Each guide shows all the steps and the other tools.

Start on Apify

Make a free Apify account: you get $5 of free usage every month. Missing a tool? Suggest it. We read every idea, but we do not promise to build it.

Apify links on this page are affiliate links. We may earn a commission. You pay the same price. Affiliate disclosure