/// REFERENCE

How do I run OCR on a scanned PDF?

OCR for scanned PDFs with confidence scores and per-word bounding boxes, a choice of installed languages, and an optional plain-text sidecar file.

Published: Last updated:

Answer: POST /api/v1/tools/ocr runs OCRmyPDF with Tesseract on an uploaded PDF and returns a searchable PDF; three credits. Every option is optional and the defaults reproduce the original behaviour — OCR every page, English, no optimisation — so a request that sends none behaves exactly as before. A bad option is a 422 whose code and message name the field.

Request

Send the file as multipart files= and the options as a JSON options field. language (singular) is the field the dashboard and the published code samples send; languages is its plural form and wins when both are present.

bash
curl -X POST https://www.ashdocs.com/api/v1/tools/ocr \
  -H "X-API-Key: ash_test_xxxxxxxx" \
  -F "files=@scan.pdf" \
  -F 'options={"language":"eng+deu","fix_scan":{"deskew":true},"output":{"text_sidecar":true}}'

Options

Generated from the OCR engine's command builder.

Sent inKeyWhat it does
optionslanguagesTesseract language codes, as a list or a string joined by + or ,. Default eng. A code not installed on the server is refused by name.
optionslanguageSingular alias of languages — the field the dashboard and the published code samples send. languages wins when both are present.
optionsmodeauto, skip, force or redo. Default force — OCR every page even if it already has text.
optionsoptimizeOutput optimisation level 0–3. Default 0.
optionsfix_scan.rotatetrue rotates pages to the detected orientation.
optionsfix_scan.deskewtrue straightens skewed scans.
optionsfix_scan.cleantrue cleans the page before OCR (needs unpaper on the server; refused by name when absent).
optionsfix_scan.oversample_dpi0 (off), 300 or 400 — upsample low-resolution scans before OCR.
optionsoutput.typepdf (default) or pdfa.
optionsoutput.text_sidecartrue also returns the recognised text as a .txt file.
optionsoutput.words_jsontrue also returns per-word positions as JSON, for documents up to 50 pages.
optionspagesPage range such as 1-3,7. Default all pages.
optionspsmTesseract page segmentation mode, 1 or 3–13. Default 3.
optionsjpeg_quality1–100. Unset by default.
optionsskip_big_mpixelsSkip OCR on images larger than this many megapixels. Unset by default.

Frequently asked questions

Which languages can I use?

Any Tesseract code installed on the server. A code that is not installed is refused by name rather than ignored.

Can I get the text on its own?

Yes — output.text_sidecar: true returns a .txt alongside the PDF, and output.words_json: true returns per-word positions.

Will it OCR pages that already have text?

By default yes (mode force). Use mode skip to leave pages with text alone, or redo to replace an existing OCR layer.