01 · CLI
Run a command.
Parse a file, process a folder, compare saved outputs, or run a named strategy. The CLI returns structured JSON you can save and inspect.
Available in coreEvery provider fails somewhere · route around it
Every document-processing provider fails somewhere. Textract, Google Document AI, Reducto, PyMuPDF, Tesseract, all of them. openreading puts one API in front of the lot, and they all return the same result format. Switching, cascading or racing them is a config change.
Open-source today. Run it on your machine, with your choice of backend.
Available capabilities, plus one future direction.
How it works, in order: the output, the grid, strategies, agents.
Product · The output
One response contract, with content that depends on the backend. Text, pages, tables,
geometry, and confidence are optional; a field-only result can use typed_fields
without pages. Available bounding boxes use page-relative [0,1] coordinates.
A shared shape does not promise identical readings or complete content.
{
"schema_version": "0.3",
"status": {"state": "succeeded"},
"backend": {"id": "pymupdf", "type": "oss_library", "output_paradigm": ["block_tree"]},
"document": {
"page_count": 1,
"pages": [
{
"page_number": 1,
"width": 612,
"height": 792,
"unit": "pdf_point",
"blocks": [
{
"type": "text",
"native_type": "text",
"text": "First National Bank",
"reading_order": 0,
"bbox": {"x": 0.0588, "y": 0.0265, "w": 0.2085, "h": 0.0243, "page": 1}
}
]
}
]
},
"usage": {"pages_processed": 1},
"warnings": [{"code": "confidence_unavailable", "field": "block_confidence"}]
}
{
"schema_version": "0.3",
"status": {"state": "succeeded"},
"backend": {"id": "tesseract", "type": "oss_library", "output_paradigm": ["element_list"]},
"document": {
"page_count": 1,
"pages": [
{
"page_number": 1,
"width": 1275,
"height": 1650,
"unit": "pixel",
"blocks": [
{
"type": "text",
"native_type": "line",
"text": "First National Bank",
"confidence": 0.96,
"reading_order": 0,
"bbox": {"x": 0.0604, "y": 0.0327, "w": 0.2063, "h": 0.0133, "page": 1}
}
]
}
]
},
"usage": {"pages_processed": 1}
}
{
"schema_version": "0.3",
"status": {"state": "succeeded"},
"backend": {
"id": "aws-textract",
"type": "hosted_api",
"operation": "AnalyzeDocument",
"output_paradigm": ["block_graph"]
},
"document": {
"page_count": 1,
"pages": [
{
"page_number": 1,
"blocks": [
{
"type": "title",
"native_type": "LAYOUT_TITLE",
"text": "Loan Application",
"confidence": 0.994,
"reading_order": 0,
"bbox": {"x": 0.1, "y": 0.05, "w": 0.5, "h": 0.04, "page": 1}
}
]
}
]
},
"typed_fields": {"Total": {"value": "$4,400.00", "confidence": 0.965}}
}
PyMuPDF and Tesseract read the same bank statement. Textract uses separate test data. Responses are shortened and numbers rounded for readability. Other providers show capabilities, not extraction results. These are static examples, not live calls or accuracy benchmarks.
Learn more: Understand the response JSON ↗ · Tables and coordinates ↗
openreading does not make any provider better at reading your document.
It gives you a shared contract, and makes failure handling an explicit strategy.
Product · The 3×3
Parse reads documents through a supported backend. Compare shows where outputs agree or differ. Strategy runs the backend order and quality checks you specify. And each feature works for three audiences: a human at a terminal, a program, or an agent.
| CLI a human at a terminal | API Python · HTTP, one contract | Agent an LLM acting on typed output | |
|---|---|---|---|
| parse supported inputs, one schema | openreading parse on a file, a directory, a glob, or URLs |
run() / run_batch() · POST /v1/parse, /v1/batch |
uses the CLI or API; inspects status.state and warnings[] |
| compare where readings differ | openreading compare on files, or on two folder runs |
compare() · POST /v1/compare |
typed verdicts, built to be branched on |
| strategy the decision, encoded | parse --strategy + validate / plan / explain / replay / calibrate |
run(path, strategy="x") · backend.id: "strategy:x" for HTTP parse requests |
inspect attempts and decisions with explain; replay recorded decisions offline |
The CLI, Python API, and your HTTP server share the vendored JSON Schemas. Agents can use those interfaces today. Native MCP tools and triage are not shipped.
Learn more: Read a comparison ↗ · Process a folder ↗
Product · Strategies
A strategy is a named plan for trying backends and checking their results. For example, start with a PDF text parser, then run OCR when the quality check rejects its output.
version: 1
policy:
backends: [pymupdf, tesseract]
strategies:
scan_aware:
try: [pymupdf, tesseract]
escalate_when: looks_bad
max_time: "2m"A gate is a check that accepts a result or moves to the next backend. Here, looks_bad checks signals such as garbled text and mostly empty pages. It does not guarantee that extracted values are correct.
Install the Tesseract system binary before using this example. Validate the file with openreading strategy validate, then run openreading parse examples/1040-1988.pdf --strategy scan_aware. Follow the local-first tutorial ↗ for setup, traces, and replay.
Learn more: Read the trace ↗ · Race and compare ↗
Product · Agents
An agent uses the same CLI, Python API, or HTTP server as your application. openreading help serves the manual directly from the code, including examples and exit codes.
Status appears in status.state, warnings carry codes, and comparison reports expose headline.verdict: equivalent, divergent, or mixed. A strategy trace records attempts and decisions for inspection.
Native openreading mcp tools and triage are not shipped. Today, start with the CLI help chapter ↗ and CLI guide.
Learn more: Read status and warnings ↗
Product · Intent · Not shipped
The proposed intent layer would let you identify which extracted fields matter to your task. For example, you could ask for closer checking of an invoice total than its mailing address.
That layer is not available today. The OSS engine provides the parsing, comparison, and strategy mechanisms underneath it. Use explicit backends and quality checks you can inspect.
One open-source engine. Use the CLI, Python library, or your own HTTP server.
Open-source today. Run it your way.
01 · CLI
Parse a file, process a folder, compare saved outputs, or run a named strategy. The CLI returns structured JSON you can save and inspect.
Available in core02 · PYTHON
Use openreading.run, route, compare, and run_batch in your application. Bring your own documents and backend configuration.
03 · HTTP
openreading serve starts an HTTP process on your machine. Your application calls the parse, batch, route, comparison, and job endpoints.
LATER · COMMERCIAL
Hosted processing, managed deployments, and account-based products are not available. The current release is the open-source engine you operate yourself.
Not availableCore does not bundle a web UI or send documents through OpenReading infrastructure. A hosted backend is a vendor API, such as Textract, called with your credentials. Local backends run in your environment.
Learn more: Install core ↗ · Use Python and HTTP ↗
Start with a bundled example and a local backend. No provider key required.
Get started · CLI & Python
Use Git and uv to install the current checkout. PyMuPDF reads the bundled example locally; you do not need a provider account.
git clone https://github.com/openreading-ai/openreading-core
cd openreading-core
uv sync --all-extras --dev
uv run openreading backends
uv run openreading parse examples/john_smith_1000_2026_01.pdf --backend pymupdf > parsed.json
uv run openreading compare parsed.json parsed.json --format diffsimport openreading
doc = openreading.run(
"examples/john_smith_1000_2026_01.pdf",
backend="pymupdf",
)
print(doc["status"]["state"])
# succeededThe comparison above checks a saved result against itself without another backend call. Compare two different readings ↗ to compare different backends, add OCR, and build a strategy. Tesseract requires a separate system binary; hosted backends require your vendor credentials.
For an HTTP interface, run uv run openreading serve yourself. Core does not include serve-ui, managed hosting, or a commercial account.
Learn more: Your first parse ↗ · Build a Python consumer ↗
Everything in one place, for people and for the LLM helping them.
Reference
Response JSONAnnotated output, content paths, and one safe consumer across backends.Diagram atlasThe engine and its walkthrough, explained through resolution-independent artwork.Guided tutorialFrom installation to parsing, comparison, strategies, and your HTTP server.
OpenReading CoreThe OSS overview and the ordered path into the engine.
Documentation homeFind the code-owned guide for your task.
CLICommands, help topics, examples, and exit codes.
HTTP serverRun the server yourself and use its endpoints.
JSON SchemasThe versioned request and response contracts.
StrategiesValidate, execute, explain, and replay a plan.
CompareRead verdicts, channel differences, and saved reports.
Backend catalogDeclared formats, setup requirements, and output channels.The tutorial lives with this website. Reference guides and the self-documenting CLI live with the engine, beside the behavior they describe.
What is ready, and what is not. Never blurred.
Status · OSS release
| Feature | Status |
|---|---|
| Parse supported documents into a shared response schema | Available |
| Batch files, folders, and globs | Available |
| Compare saved outputs or run named backends for comparison | Available |
| Strategies: cascade, race, explain, replay, and calibrate | Available |
| Local backends and adapters for vendor APIs | Available |
| CLI, Python API, and an HTTP server you run | Available |
| Code-owned guides and the guided OSS tutorial | Available |
| Execution ledger, resume, and benchmark harness | Available |
| Native MCP tools and triage | Not shipped |
| Intent-driven extraction | Not shipped |
| Commercial hosting, managed deployments, and account-based products | Not shipped |
Install the current core checkout from source. Backend availability depends on its dependencies, credentials, and supported formats. openreading backends reports local setup; a configured backend is not proof that its vendor accepted your key.
Learn more: Check your backends ↗ · Resume a strategy run ↗
The questions everyone asks, answered the way they get asked.
FAQ
The CLI, Python library, and an HTTP server you start with openreading serve, plus backend adapters, strategies, comparison, and batch processing. Install the dependencies and configure the backends you want to use. A web UI is not bundled. Install and check core ↗
It is not a client for a service of ours. It calls the providers directly and nothing routes through us. What it leaves out is what only matters when someone else runs it for you: user accounts, provisioned provider keys, uptime and administration.
Not when you run it yourself. The package talks to the providers directly, and the local parsers do not leave your machine at all.
Commercial hosted editions are not available. If you choose a vendor API, that vendor receives your document directly. Review its terms and configure your own credentials. Bring your own key ↗
Do that, if you will only ever use one provider. The work shows up with provider two: converting a second output format, handling a second set of errors, a second async model, a second set of retries.
You still call the vendor directly through openreading, with your key and your account. You control where credentials are configured, such as environment variables or your local environment file. Core does not provision vendor accounts. Configure your backends ↗
Yes. Adapters normalize available geometry to page-relative coordinates and keep original coordinates in bbox_native when supplied. Numeric block confidence uses [0,1], but scores from different backends are not interchangeable probabilities. Extracted-field confidence can also retain vendor strings.
Sync, polling, and supported webhook workflows use one Job state machine. Missing output stays absent, and warnings explain some limitations. Check the content you need: neither an empty warning list nor the experimental channel_provenance map proves completeness. Explore the response contract ↗
The break lands in one connector, not in your code. Connectors are tested against recorded responses plus injected failures, and real API behaviour is checked in a separate keyed lane.
Adapter changes land in the open-source repository. Pin a revision for your application and run your own checks before upgrading. Find the reference guides ↗
After installation, pymupdf and tesseract can read local files without a key or network call. docling and qwen-vl send documents to the endpoints you configure. Operate those endpoints inside your environment if your documents must stay there.
Core certifies nothing on your behalf. The default backend list is a routing preference, not an access-control boundary. Configure default routing ↗
Keep it. If it has an adapter, run compare against another backend over your own documents. Otherwise, convert its output to the response schema before comparing saved results. The report shows where readings differ, not which one is correct.
Agreement is not proof of correctness. Use labeled ground truth to measure accuracy; comparison alone shows differences. Read comparison findings ↗
Parse the bundled example, inspect the result, and build a strategy you can explain. Commercial offerings will come later.
Your machine. Your backends. One shared contract.