Goal
Make PDFs and images searchable while keeping extraction state and failures independent from asset availability.Prerequisites
- A PDF or image asset
- An
assets:processtoken to start or retry extraction andassets:readto read results or search - The English language pack for the shipped
engruntime; additional Tesseract language data must exist before requesting another code
Workflow
1
Start extraction for one asset, or enable
auto_extract_text on a bucket for future PDF and image uploads.2
Poll the extraction until it is
ready or failed. Continue serving the original asset regardless of OCR state.3
Store or render
plain_text, then use ordered page blocks and normalized boxes for highlights or overlays.4
Search the existing Assets list with
query; key and original-name matching continue to work and ready extracted text participates in the same result set.5
Fix a visible failure cause and retry the extraction ID when necessary.
Provider behavior and supported input
- The production provider is
poppler_tesseract; its cache identity includes the installed Poppler and Tesseract engine versions. - For a PDF,
pdftotext -bbox-layoutfirst extracts embedded text and word boxes. If the document has no usable embedded text,pdftoppmrenders every page and Tesseract OCRs the PNG pages. - For an image MIME type, Tesseract processes one page directly.
- The default language is
eng. The only current option isdpifor rasterized PDFs; it defaults to 200 and is clamped to 72–400.
Start, read, and retry
Result schema and geometry
Extraction states arepending, processing, ready, and failed. A ready result includes plain_text, page_count, and ordered pages. Each page has a one-based number, source width and height, and ordered word blocks.
boxis[left, top, right, bottom], normalized to 0–1 relative to the page.- Tesseract confidence is normalized from 0–100 to 0–1. Embedded PDF words have confidence
1because no OCR probability is involved. - Page dimensions remain useful for projecting normalized boxes into pixels, canvas coordinates, or PDF viewer coordinates.
Automatic extraction, cache identity, and versions
- Bucket automation defaults off. Set
auto_extract_text: truethrough the revision-checked storage configuration endpoint; it applies to future supported uploads and replacements. - The cache key is tenant-scoped and includes asset SHA-256, provider, engine version, language, and canonical options hash. Identical content in one Assets space can reuse a result without cross-tenant disclosure.
- The extraction is linked to the current asset version. Replacing bytes changes the checksum/version and therefore creates or links the correct cache entry naturally.
- A failed extraction records
error_codeanderror_message, emits an OCR failure event, and remains retryable. It never changes asset readiness, scan state, visibility, or delivery.
Search extracted text
Use the existing Assets listquery filter. StackShift keeps the existing case-insensitive key and original-name search, then also matches ready current extraction text through PostgreSQL web-search syntax. The list and count queries use the same predicate, so pagination totals remain consistent.
Expected result
The asset exposes searchable plain text and page/word geometry without changing its bytes, current version, or delivery URL.
Common failures
Related guides
Upload UX and DAM
Build a durable upload and digital-asset-management workflow with resumable sessions, revision-safe mutations, search, collections, webhooks, and usage summaries.
Assets platform API, SDK, CLI, and operations
A complete interface and recovery reference for storage connections, S2, imports, relocation, OCR, browser capabilities, reports, scopes, events, billing, and durable worker behavior.
AI DAM and versioning
Use configured asset AI jobs, moderation, transcripts, derived images, collections, saved searches, and branching versions with explicit readiness and spend controls.