Document OCR & Data Consistency
Extract structured data from documents and verify consistency with declared information
The Document OCR module extracts structured data from uploaded documents (identity cards, passports, driver's licenses, utility bills, tax notices) and compares it against declared information. It combines 2D-DOC cryptographic verification with OCR and fuzzy matching to produce a consistency report.
How it works
Documents go through a two-tier extraction pipeline:
| Tier | Method | Trust level | When used |
|---|---|---|---|
| 1. 2D-DOC | Barcode detection + cryptographic verification | 2ddoc_verified | Document contains a signed 2D-DOC barcode |
| 2. OCR | AI-powered document OCR with structured extraction | ocr | Any document: PDFs, photos, scanned documents |
2D-DOC fields are cryptographically signed by the document issuer and take precedence. OCR fills any remaining gaps.
Extraction
2D-DOC (cryptographic proof)
Documents are scanned for 2D-DOC barcodes using a neural network detector. When a barcode is found, it is decoded and cryptographically verified against the ANTS trust store. Fields extracted from the barcode are guaranteed authentic; any tampering with the visible document content is detectable.
Common documents with 2D-DOC: utility bills (ENGIE, EDF), tax notices (DGFIP), new French CNI (ANTS), administrative attestations.
OCR (structured extraction)
For fields not covered by 2D-DOC, documents are processed with AI-powered OCR that returns structured fields directly. Supports any document format (PDF, JPEG, PNG), including scanned documents, photos of ID cards, and handwritten receipts.
The extraction schema is configured per document category, specifying which fields to extract and whether they are required.
Matching
Once fields are extracted from all documents, the system compares each declared field against the best available extraction.
Field matching
For each field, the system picks the best extraction based on document category and trust tier, then applies fuzzy matching:
| Strategy | Confidence | Example |
|---|---|---|
| Exact match (normalized) | 1.0 | Léa-Marie = LEA-MARIE |
| Containment | 0.9 | DUPONT found in MR ET MME DUPONT MARTIN |
| Address abbreviation | 0.9 | 12 cité Verte = 12 CITE VERTE |
| Close spelling (Levenshtein) | 0.8 | MARTIN vs MARTNI (edit distance: 1) |
| Partial word match | 0.6-0.85 | Word-level overlap between declared and extracted |
| No match | 0.0 | Values are unrelated |
Date matching
Dates receive special handling to detect common errors:
| Scenario | Confidence | Flag |
|---|---|---|
| Exact match | 1.0 | none |
| DD/MM swap | 0.0 | date_dd_mm_swap |
| Wrong day, month, or year | 0.2-0.4 | Component mismatch flagged |
| Completely different | 0.0 | none |
Date formats are normalized: 05.07.1990, 05/07/1990, 05-07-1990, and 05071990 are all equivalent.
Cross-document consistency
When the same field appears in multiple documents, the system checks whether the documents agree with each other. If two documents agree on a value but it differs from what was declared, a declared_vs_docs_mismatch flag is raised.
Scoring
The overall score is a weighted average of per-field confidence. Fields, weights, and thresholds are configurable per organization via the dashboard.
| Result | Condition |
|---|---|
pass | Score above pass threshold, no flags requiring review, no missing required fields |
review | Score above review threshold, or any flag requiring human review |
fail | Score below review threshold |
Flags that require human review: date_dd_mm_swap, declared_vs_docs_mismatch, spelling_close.
Missing required fields always cap the result at review.
Flags
| Flag | Meaning |
|---|---|
date_dd_mm_swap | Day and month appear swapped between declared and document values |
spelling_close | Name is very close but not identical; requires human verification |
partial_address | Address partially matches; some components are missing |
cross_doc_mismatch | Two documents disagree on the same field |
declared_vs_docs_mismatch | Documents agree with each other but differ from declared data |