Skip to main content
Back to Blog
EngineeringArchiving & ComplianceSeptember 2026

Creating Searchable PDFs from Scanned Document Archives at Scale

How text layer overlays preserve original signatures, stamps, and paper texture while enabling full-text search and e-discovery across thousands of files.

What is a searchable PDF and how does FastOCR generate it?

A searchable PDF (also called a sandwich PDF) consists of two synchronized layers: the original high-resolution scanned image on the visual surface, and an invisible, selectable OCR text layer positioned directly beneath each word. FastOCR generates searchable PDFs via its asynchronous REST API: you submit the PDF, trigger processing, and retrieve the file using format=pdf. The resulting document retains 100% of original visual elements—such as signatures, physical stamps, and margin notes—while enabling Adobe Acrobat search, copy-paste, and enterprise indexing systems to find keywords instantly across 100+ languages.

Visual Preservation vs. Pure Text Extraction

In legal, medical, and banking compliance, modifying the visual layout of a signed document is strictly prohibited. You cannot simply discard the scanned image and replace it with re-rendered text.

A searchable PDF solves this constraint by maintaining the exact bitmap of the scan while embedding an invisible vector font layer mapped to identical coordinates. When a user highlights text or presses Ctrl+F, the PDF reader references the invisible coordinate layer.

Automating Batch Conversions with Python

With the FastOCR Python SDK (pip install fastocr), processing an entire folder of scanned documents into searchable PDFs requires just a few lines:

from pathlib import Path
from fastocr import FastOCR

client = FastOCR()
input_folder = Path("./incoming_scans")
output_folder = Path("./searchable_archive")
output_folder.mkdir(exist_ok=True)

for scan_path in input_folder.glob("*.pdf"):
    print(f"Processing {scan_path.name}...")
    job = client.documents.process(scan_path)
    
    target_path = output_folder / f"searchable_{scan_path.name}"
    client.documents.download_searchable_pdf(job.id, target_path)
    print(f"Archived {target_path.name} (Pages billed: {job.pages_billed})")

Scale your document processing

Explore the full REST API documentation and start converting documents today.