Page Reading
Page reading turns phone photos and scanned PDF pages into searchable text, using your own answer models.
- Reads .jpg, .png, .heic (iPhone), .webp and the PDF pages that have no text layer.
- Turns photos upright, lifts dark photos, and reads a page taken sideways or upside down.
- Your original file is never changed.
- Needs one answer model on the account. Nothing to switch on for documents.
Settings
| Setting | Default | What it does |
|---|---|---|
enabled | false | true also reads photo files in media store feeds. Off so a folder of product photos is not turned into text and model spend unasked. |
models | [] | Up to 3 of your answer models, cheapest first. Empty: your answer models, cheapest first. |
- Console: Models → Answer Models, Read photos in feeds.
- API:
PUT /page-reading/{account}. MCP:page_reading_set.GETshowseffective: the models that would read a page now. - Applies to documents indexed and feeds synced after the change.
How a page is read
- The cheapest model reads the page twice. The reading stands when no word is marked
[illegible]and the two readings agree word for word. - Otherwise the next model reads it, and stands when it agrees with an earlier reading.
- When no two readings agree, the page is marked
hard_to_read: its words are kept but never presented as certain. - A page the model sees on its side is turned and read once more.
- Tokens count against each answer model’s monthly budget.
Where it applies
| Path | What is read |
|---|---|
| Index a document | Always: a photo, or a PDF’s scanned pages. A photo that is not a page stays an image record. more_pages adds more photos of the same letter, in page order (up to 30): one document, a page number per photo. |
| Media store feed | Always: scanned PDF pages. Photos only with enabled: true; otherwise they stay image records. |
- Records carry
first_pageandlast_page, so an answer can cite a page. - A scanned PDF has its first 300 blank pages read; later ones are listed as warnings.
- No answer model: indexing a photo fails with that reason, and a scanned page becomes a warning.
Pages that can’t be read
- Never indexed silently: each becomes a warning on the import run, e.g. Page 2 of 'letters/p1.heic' has no readable text: The photo is too dark…
- Webhook
document.pages-unreadablecarries each page and its problems.
Quick check after a photo
Call POST /page-reading/{account}/check (MCP page_reading_check) with {"image": "<base64>"} right after a photo is taken. It answers in 2 to 4 seconds.
retake: truemeans ask for another photo. Show each problem’smessage.readable: falsemeans no words could be read. A readable page can still need a retake, such as when its bottom is cut off.POST /page-reading/{account}/read(MCPpage_reading_read) returns the page’s text as well.- Both work whatever the settings, store nothing, and need
searchresult:create.
| Code | What the person is told |
|---|---|
too_dark | The photo is too dark. Turn on a light or move nearer a window. |
too_bright | The photo is too bright. Move out of direct light. |
blurry | The photo is blurry. Hold the phone still and tap the page to focus. |
too_small | The page is too small in the photo. Move the phone closer. |
glare | There is a shiny glare on the page. Tilt the phone a little. |
cut_off_top, cut_off_bottom, cut_off_left, cut_off_right | The bottom of the page is cut off. Move the phone back so the whole page fits. (Names the edge.) |
covered | Something is covering part of the page. Move your fingers or anything else off it. |
not_a_page | This doesn’t look like a page of writing. Take a photo of the letter itself. |
no_text | No writing could be found on this page. |
hard_to_read | Some words can’t be read. Try again in better light, holding the phone still. |
not_an_image | This file isn’t a photo that can be opened. Try taking the photo again. |
Cost
Measured on 345 photos and scans of 115 pages of real EHCP papers (about 94,000 words), at list price on your own key:
- Every word read correctly, numbers and dates included.
- Haiku 5.5 read 97% of pages; Sonnet 5.5 or Opus 5.5 read the rest, where two readings disagreed.
- About $3.30 per 1,000 pages, both readings included.
- Each response reports
cost_usd. A quick check costs about $0.0006.
Webhooks
page-reading.changed—enabledormodelschanged.document.pages-unreadable— pages of an indexed document gave no text:list_name,media_name,run_id, andpageswith eachpageand itsproblems.