Sensible reads the bank formats you see most with layout-based configurations written for that exact statement, and sends everything else through a general LLM configuration. Both return the same fields in the same shape, so your code never has to know which one ran.

cascade_checking_apr2024.pdf · 1 page · 11 transactions
Layout + LLM
Blended extraction pipeline
One schema
The same output from either path
SOC 2 + HIPAA
Certified infrastructure
Page + box
Source location on every value
Trusted by teams turning documents into production data






A sample checking statement with eleven transactions and a table that breaks across a page. Four things happen to it on the way to JSON.
Header and account metadata located and typed from the top block.
All 11 transactions anchored across the table, including a page break mid-cycle.
A validation in the configuration checks beginning balance plus deposits minus withdrawals against the printed ending balance.
Typed JSON returned with a bounding box on every single value.
Built for teams who reconcile real money.
Write the arithmetic into the configuration as a validation. A statement that doesn’t add up comes back with the error attached.
Every extracted value carries its exact page and bounding box, back to the original PDF.
Mapped banks get a fast template. New layouts flow through an LLM template with the same output schema.
Agentic parsers are fast to demo and slow to trust: they hallucinate pennies, lose rows past a context window, and hand you a number with no way to check it. Sensible runs a layout configuration when one exists for the format and a general LLM configuration when it doesn’t, and puts both through the same schema and validations.
For the banks you see often, a SenseML configuration anchors on that statement’s own headers and columns, so the table reads the same way every time.
SenseML table methods track table headers across page boundaries without dropping rows on multi-page statements.
Every single transaction row retains its exact bounding box and page index for compliance audits.
This is the pipeline underneath every extraction. Known formats are read by layout rules and everything else by the general LLM configuration. Both paths finish in the same validation step.
Native text and scanned pages are both normalized into a coordinate-anchored layout tree; every character keeps its page and pixel position.
SenseML anchors locate the header block, balance summary, and transaction table using structural rules matched to the bank’s known format.
A statement with no matching configuration is read by an LLM configuration that returns the same fields as the layout path.
Fields are cast to their declared types and run through the validations you wrote before the JSON comes back.
Long tables, sign conventions and combined accounts are where generic parsing goes wrong.
Statements frequently span 10, 30, or 100+ pages with repeated headers, variable column widths, multi-line wire descriptions, and footnote breaks. Deterministic SenseML table anchors parse transactions continuously across breaks without losing row alignment.
Do all transaction credits and debits equal the stated period change? Does the running balance reconcile after every single row? Validations in the configuration check both, so an OCR misread shows up as an error instead of a wrong number downstream.
One bank prints debits in their own column, another adds DR, another uses parentheses, and on a UK statement 04/05 means 4 May. Sensible returns one signed amount and one date format however the bank printed them.
Banks frequently bundle commercial checking, operating reserves, and money market schedules into a single PDF packet. Sensible isolates each account schedule and extracts them into discrete, cleanly keyed sub-ledgers.
A single OCR typo in a transaction amount ruins downstream debt-to-income and cash flow modeling. The checks are validations written into the configuration: beginning balance plus credits minus debits has to equal the ending balance, and each running balance has to follow from the row above it. A statement that fails comes back with the error attached.
I like the coding nature of Sensible’s interface because it makes it really easy to understand why an extraction is or isn’t doing what I expect. Their support team is excellent at helping with models, and they were really good at assisting us through the quite involved setup process.
G2 review, bank statement extraction customer
Delivering verified financial feeds directly to underwriting models, ERPs, and risk engines.
Calculate Debt Service Coverage Ratios (DSCR), monthly revenue velocity, average daily balances, and NSF instances directly from verified transaction feeds.
Lending & CreditFeed cleared transaction tables directly into NetSuite, QuickBooks, or Xero with continuous bank reconciliation and double-entry validation.
Accounting & ERPInstantly verify borrower cash reserves, check deposit sourcing, and validate recurring payroll income without human line-item reviews.
Mortgage & VOIConsolidate multi-bank balances across dozens of institutions into a unified cash visibility ledger with automated sweep auditing.
Treasury OpsStarting with the one everyone's actually asking now that LLMs can read PDFs.
You can, and it'll work great on page one of a demo. It also has no way to prove a balance is right, no fixed output schema across runs, and it silently drops or merges rows on long tables. Sensible uses LLMs too: statements from banks without their own configuration go through a general LLM configuration. Its output lands in the same schema as the layout path and runs through the same validations, so a number that doesn’t add up comes back flagged.
The configuration includes validations that compare beginning balance, total credits, total debits and ending balance, and that check each running balance against the row before it. If OCR reads a $1,200.00 charge as $1,700.00, the totals stop matching and the extraction returns a validation error naming the check that failed.
Sensible uses deterministic SenseML table definitions paired with layout-aware anchors. It recognizes column boundaries, multi-line transaction narratives, and page break headers, stitching rows together into a single continuous transaction array without skipping lines or misaligning debits and credits.
It goes to the general LLM configuration and returns the same schema as every other statement. If that format shows up often in your volume, you or our team can write a layout configuration for it in SenseML, and Sensible routes those statements to it from then on.
Yes. Commercial banking statements frequently package checking, savings, payroll, and sweep accounts into a single file. Sensible classifies and partitions the document into individual account schedules, returning discrete JSON objects with their own account numbers, balance summaries, and transaction tables.
Sensible is SOC 2 Type II certified and HIPAA compliant.