How it works
Whether you build the template yourself, generate one from samples, or hand it to our team, every extraction follows the same path. Walk through it below.
01
Different documents need different approaches.
02
Layout-based methods, AI-based methods, or both.
03
The ten stages every document moves through.
04
Webhook, REST, SDK, MCP, spreadsheet, database.
05
Validations, review queue, live dashboard.
Whether you're building this in-house, with a different vendor, or with us, every extraction project starts the same way: by reviewing the documents you're trying to parse. Click any question to see why it matters.
Stable forms work well with layout templates. Free-text fields need AI. But the most complex documents often want layout methods: a loss run with repeating headers or an EOB with merged cells needs a deterministic table parser, since AI would hallucinate rows.
Define the fields you need, the types your code expects, and what's required up front. The rest of the build is just satisfying that contract on every document. No mapping layer, no transformation logic, no busy work after extraction.
Some fields are advisory (a category tag on an invoice). Others are decision-critical (a loan amount on a packet that's about to be approved). Knowing which is which up front sets the right confidence thresholds, the right validation rules, and decides what gets queued for human review.
A real-time application processing thousands of docs daily integrates differently than an ops team running 50 packets a week. Where the data lands also matters: a queue, a database, a spreadsheet, an MCP-aware editor, an API your code consumes.
Based on what you found in step 1, you'll mix and match. Layout methods are fast and deterministic. Use them where the field is stable and labeled. AI methods handle free-text, variable layouts, or fall-backs when layout misses. Same field, two ways below.
Anchor on a row containing "Closing Date" and pull the value from the same horizontal band. Works for table-style layouts where the value sits next to a labeled row, even when it isn't the next token.
{ "fields": [ { "id": "closing_date", "anchor": { "match": [ { "text": "Closing Date", "type": "includes" } ] }, "method": { "id": "row", "position": "right" }, "type": "date" } ] }
More layout-based methods beyond row — anchor, region, label, paragraph, signature, and others. See the full set: Layout-based methods →
Ask an LLM, scoped to the most relevant page. Use when the label moves between lender versions, when the field is free-text, or as a fall-back when the layout method misses.
{ "fields": [ { "method": { "id": "queryGroup", "searchBySummarization": "page", "queries": [ { "id": "closing_date", "description": "What is the closing date of this loan?", "type": "date" } ] } } ] }
More AI-based methods beyond queryGroup — query, single-line, line-aware extraction, and others. See the full set: LLM-based methods →
Ten stages, in order, every time. Some run only when needed. Click through to see what happens at each one.
The document hits the API. Sensible figures out what it's working with: PDF, image, Word doc, spreadsheet, email, or a mixed packet. Where a page already contains digital text (most modern PDFs do), the text is extracted directly. Where it doesn't, the page is queued for OCR in the next stage. The routing decision happens page by page, not per file.
PDF, PNG, JPG, TIFF, DOCX, XLSX, CSV, EMLFor pages that arrived as images (full scans, photos, or scanned sections of a mixed packet), Sensible runs OCR. The engine is configurable per document type: Amazon, Google, or Microsoft. OCR returns confidence per character, not per page, so a smudged signature or a low-res stamp can't silently produce a confident wrong answer.
Loan applications often arrive as portfolios: the application packet plus tax returns plus paystubs, all bundled in one upload. Sensible detects boundaries between documents and segments them by page range. From here on, each segment is processed independently with its own config.
Each segment is classified to determine which extraction config to run. Classification can be LLM-based (matching against the names and descriptions of your configured document types) or layout-based (matching against anchor patterns unique to each type). LLM classification works even when a document type doesn't have a reference document yet, because the model can match against the description alone.
loan_packet.ymltax_return.ymlEach document type can specify a preprocessor pipeline that runs in the order you define. Preprocessors handle the practical messiness of real documents: scans tilted a few degrees, watermarks blocking text, lines that wrapped mid-sentence, multicolumn pages that need to be read column-wise rather than left-to-right.
deskew rotated page 3 by +2.4° to verticalwatermarkRemoval stripped "CONFIDENTIAL" from page 2mergeLines rejoined 4 sentences that wrapped across page breaksmulticolumn read page 4 column-wise instead of row-by-rowheaderFooter excluded repeating page numbers from extractionThis is where Sensible actually pulls the data out. Each field in your config specifies a method. Layout-based methods (anchor on a label, pull from a region, parse a table) are fast and deterministic, and handle most fields in most documents. AI-based methods are used when a field is free-text, when its position varies, or as a fall-back when a layout method misses. Many fields use a chain: try layout first, fall back to AI when it fails.
row method anchored on "Borrower" and returns "Jordan A. Park" on the first tryrow but the anchor moved in this lender's version. Falls back to queryGroup (an LLM query scoped to the relevant page) and returns "Aug 12, 2026"Extracted values come out as strings. This stage normalizes them to the types your schema expects. Currency strings become numbers with currency tags. Date strings become ISO format. Addresses get parsed into structured components. Computed fields combine multiple extractions into new values, like full_name from first plus last, or total from a sum of line items.
"$485,000.00"→485000.00 USD"Aug 12, 2026"→"2026-08-12""360 months"→360"CA 94705"→{ state: "CA", zip: "94705" }Confidence catches uncertain extractions. Validations catch certain extractions that don't make sense in context. Rules are written in JsonLogic and check things like cross-field math (total equals sum of line items), date ordering (closing date after application date), and enum membership (state in the list of valid US states). When a rule fails, the document is flagged.
loan_amount > 0passesclosing_date >= application_datepassesproperty_state in valid_statespassesclosing_date.confidence >= 0.85fails at 0.83, document queued for reviewEvery field comes back with a confidence score. For OCR'd content, two signals are reported: anchor confidence (how sure Sensible is about where on the page the field lives) and value confidence (how sure about what was extracted). For AI-based queryGroup fields, additional confidence signals are returned from the model itself. Your code uses these scores against the per-field thresholds you set: above clears, below queues for review.
The response is shaped exactly like the schema you defined. Each field carries its typed value and the page plus bounding box where Sensible found it. For multi-document portfolios, the response is structured per-document with page ranges.
Webhook, REST, SDK, MCP, spreadsheet, database. Each field comes back with its value, type, and the page it came from.
Real-time push. Connects to Zapier, n8n, your queue.
Submit, poll, get JSON. Useful for batch jobs.
Native libraries: Node and Python.
CSV or Excel export to Google Sheets, ops tools.
Connect via Sensible's MCP server in Claude Code, Cursor, or any MCP-aware editor.
Anything else. Webhook into your queue and route from there.
Three things keep the pipeline honest day-to-day. The same three regardless of whether you built the template or our team did.
JsonLogic rules run on every document. Cross-field math, date ordering, enum membership, format checks. When a rule fails, the document is flagged before it reaches your downstream systems.
loan_amount > 0Passclosing_date >= app_datePassconfidence >= 0.85FlagWhen a confidence score or rule trips, the document goes to a review queue with one-click accept, correct, or reject. Corrections feed your reference set so the same edge case stops reaching review next time.
Browse every extraction across production and development, filterable by date range. Click into any document to inspect field-by-field results and trace each value back to its source coordinates.
If extraction is critical to your product but isn't what your team wants to focus on, our solutions engineering team handles each step on your behalf. You see clean JSON in your API response.
Trusted by teams turning documents into production data





