One OCR output shape.
OpenParser parse routes and @openparser/adapters return one ParsedDocument graph. Swap Paddle, Mistral, Azure Document Intelligence, Google Document AI, or AWS Textract without rewriting extractors, citation logic, or eval harnesses downstream.
{
"output_format": "openparser@1",
"document_id": "doc_3f9a2c",
"page_count": 1,
"markdown": "## Payment Authorization\n| Item | Amount |\n| --- | --- |\n| Total | $4,318.20 |",
"blocks": [
{
"index": 0,
"page_number": 1,
"kind": "text",
"text": "## Payment Authorization"
},
{
"index": 1,
"page_number": 1,
"kind": "table",
"table_html": "<table><tr><th>Item</th><th>Amount</th></tr><tr><td>Total</td><td>$4,318.20</td></tr></table>",
"bbox": {
"left": 14,
"top": 53,
"right": 146,
"bottom": 123
},
"confidence": 0.98
}
],
"regions": [],
"contents": [],
"chunks": []
}OCR vendors return incompatible JSON
Every OCR provider returns a different JSON shape: Azure Document Intelligence, AWS Textract, Google Document AI, Mistral OCR, and Paddle each invent their own pages, lines, tables, and boxes.
If your pipeline parses those payloads directly, swapping engines means rewriting extractors, citation resolvers, and eval harnesses. openparser@1 is the normalization layer so consumers depend on one contract.
The hosted OpenParser API runs the same adapters server-side. Local adapters under @openparser/adapters emit the identical graph when you self-host OCR.
ParsedDocument fields from /parse
Top-level keys on a successful sync parse. Extraction wraps this graph under parsed_document and adds grounded citations into blocks[].index.
{
"output_format": "openparser@1",
"document_id": "doc_3f9a2c",
"page_count": 1,
"markdown": "## Payment Authorization\n| Item | Amount |\n| --- | --- |\n| Total | $4,318.20 |",
"blocks": [
{
"index": 0,
"page_number": 1,
"kind": "text",
"text": "## Payment Authorization"
},
{
"index": 1,
"page_number": 1,
"kind": "table",
"table_html": "<table><tr><th>Item</th><th>Amount</th></tr><tr><td>Total</td><td>$4,318.20</td></tr></table>",
"bbox": {
"left": 14,
"top": 53,
"right": 146,
"bottom": 123
},
"confidence": 0.98
}
],
"regions": [],
"contents": [],
"chunks": []
}- output_format"openparser@1"Pin the contract version. Always set this on parse requests.
- document_idstringStable id for the parsed document inside OpenParser.
- page_countnumberNumber of pages that produced blocks.
- markdownstringReading-order markdown projection of the document.
- blocks[]Block[]Ordered layout units: text, table, and related kinds with optional bbox and confidence.
- blocks[].indexnumberZero-based block index. Extraction citations point here.
- blocks[].page_numbernumber1-based page the block came from.
- blocks[].kindstringDiscriminant, e.g. "text" or "table".
- blocks[].bboxBox?left / top / right / bottom in page coordinates when the model returns boxes.
- blocks[].confidencenumber?Model confidence in [0, 1] when available.
- regions / contents / chunksarrayReserved / extended slots. Empty on many models; keep reading them as arrays.
Normalize vendor JSON with @openparser/adapters
Install only the @openparser/adapters subpaths you need. Each adapter maps a vendor response into openparser@1 pages and blocks.
- Paddle HPS
@openparser/adapters/paddleNormalize Paddle HPS responses into openparser@1. - Mistral OCR
@openparser/adapters/mistralNormalize Mistral OCR responses into openparser@1. - Azure Document Intelligence
@openparser/adapters/azure-document-intelligenceNormalize Azure Document Intelligence responses into openparser@1. - Google Document AI
@openparser/adapters/google-document-aiNormalize Google Document AI responses into openparser@1. - AWS Textract
@openparser/adapters/aws-textractNormalize AWS Textract responses into openparser@1.
Install @openparser/schema and adapters
Schema and adapters are open source. Hosted parse still meters pages when you use the cloud API.
npm install @openparser/schema @openparser/adaptersimport { ParsedDocumentSchema } from "@openparser/schema";
import { mapLayoutResultsToParsedDocument } from "@openparser/adapters/paddle";
const doc = ParsedDocumentSchema.parse(apiResponse);Full field docs live in the schema guide. Adapter guides are under adapter guides.
openparser@1 FAQ.
Contract versioning, packages, adapters, and model switching.
What is openparser@1?
A versioned document-graph contract for OCR output: document_id, page_count, markdown, blocks[] (with kind, bbox, confidence), and related arrays. Hosted parse responses and local adapters share this shape.
What does @openparser/schema provide?
Zod schemas and TypeScript types for ParsedDocument and related types. Use it to validate API responses, CLI stdout, or adapter output in your own services.
What does @openparser/adapters provide?
Per-provider normalizers under subpaths like @openparser/adapters/paddle and @openparser/adapters/aws-textract. Each adapter maps vendor JSON into openparser@1.
Do I need the adapters if I use the hosted API?
No. OpenParser runs the adapters server-side. Install them when you self-host OCR, run on-prem batch jobs, or need to normalize vendor responses before they hit your pipeline.
Which OCR providers have adapters today?
Paddle HPS, Mistral OCR, Azure Document Intelligence, Google Document AI, and AWS Textract. Each has a dedicated @openparser/adapters subpath.
Will the schema break when I switch OCR models?
Field names stay stable across models. Individual blocks may differ in confidence or layout detail, but consumers keep reading the same graph shape.
Schema docs and adapter guides
Read @openparser/schema types and per-provider adapter docs. Validate local adapter output or responses from the hosted API.