Extraction that verifies: numbers, codes and IDs
Reading a page is a model job. Computing, decoding, validating and formatting are not, and Veralens does them in code afterwards. What that changes, field by field.
5 min readEvery extraction API can hand you a field called total with a number in it. The question nobody asks in a demo is where that number came from, and whether anything checked it.
If a language model read a page, decided which figure was the total, and wrote it into JSON, then the value is a judgement with no receipt. It is usually right. When it is wrong, it is wrong in a way that looks exactly like being right, which is the expensive kind.
Veralens splits that problem in two. Reading the page is a model job, and it stays one. Computing, decoding, validating and formatting are not model jobs, and we do not leave them to a model. They run afterwards, in code, on the values the model read.
What that changes, field by field
Most of it is default behaviour. The parts that must be guaranteed rather than judged, a decoded code, a checksum-verified IBAN, a date built mechanically from the parts, are switched on with one format keyword on the field. Full table in Schemas and formats.
The rule underneath all of it
Resolve or leave alone. Never fabricate.
An IBAN that fails its checksum comes back as the original text, not as a corrected IBAN. A currency word that maps to no ISO code stays the word. A QR field on a page with no QR code comes back null rather than filled with something that looks like a payload. A date whose parts are ambiguous is not rewritten into a confident wrong ISO string.
That sounds modest. In production it is the whole difference, because a value that quietly changed is undetectable and a value that stayed raw is obvious.
One post per guarantee
Each of these is a specific thing that goes wrong in document pipelines, and what we do about it:
- Stop letting a language model do your arithmetic**: why totals, subtotals and tax lines should not be mental maths, and how to get money fields on exactly two decimals.
- QR codes and barcodes, decoded and not guessed**: a model looking at a QR code is guessing at a dense grid of squares. Ours reads it with a decoder.
- IBANs, countries and dates: normalized or left alone**: ISO codes, mod-97 checksums, and why an unrecognized value must come back exactly as printed.
Why this is not just polish
Two things follow from it that matter more than they sound.
You can check our work. A decoded barcode either matches the sticker or it does not. A total either equals the sum of the line items or it does not. A validated IBAN either passes mod-97 or it does not. These are verifiable claims, unlike an accuracy percentage on a vendor page.
Your application gets smaller. The date parsing, the currency mapping, the checksum library, the rounding helper and the per country special cases stop being your code. That is usually a few hundred lines and a permanent maintenance surface.
Try one field
The fastest way to see the difference is to send a document you already know the answer for, and ask for a calculated number and a code:
The quickstart has you sending that in a few minutes, and every job comes back with exactly what it cost.