Dossier Intelligence

Reading the documents
was the easy part.

Extraction hands you fields. A case file needs a verdict. Holofin assembles every document into one dossier, checks it is complete for every participant, checks the documents agree with each other, and names what is still blocking. One answer per case, not one JSON per file.

2 verdicts
completeness and consistency
1 API call
to open a case and push its data
0 rules in code
the business owns them
LOAN-2026-0481Business loan
INCOMPLETECOHERENCE KO
Exhaustivity9 / 12
Identity documentMarie Dupont
1 / 1
Bank statements3 distinct months
3 / 3
Proof of addressPaul Martin
missing
ID holder = bank statement holder
KO
Married name, sent to an agent
in review

The verdict is recomputed on every new document, every corrected value, and every registry lookup that lands.

Beyond document processing

Where document processing stops,
the work starts.

Frontier models classify and read almost anything now. That commoditised the hard part of IDP and left the expensive part untouched: nobody applies for a loan, opens an account, or files a claim with one document. They send a pile, over days, from several people, and someone has to decide whether the pile holds up.

What IDP answers

  • What type of document is this?
  • What are its fields, and how confident is the model?
  • Where on the page did each value come from?
  • Does this one document contradict itself?

Output: one payload per file. The case still lives in a checklist, a spreadsheet, or somebody's head.

What a dossier answers

  • Is everything here, for every participant, including the ones who have sent nothing yet?
  • Do the documents agree with each other, and with what the customer declared?
  • Which check failed, on which values, from which file?
  • What do we ask the customer for next, in one message instead of four?

Output: one status per case, with the reason attached. The checklist is the product, not a habit.

This is not a second product. The dossier layer sits on top of the workflows you already run: classification, segmentation, extraction, fraud analysis. Documents keep being processed one at a time. The case is what reads them together.

How it works

Declare the case once.
It judges itself from then on.

A case configuration is the shape of a file: who takes part, what each of them owes, and what has to be true across the whole thing. It is written by the people who own the policy, in a form they can read back.

01

Describe the file

Expected documents and how many of each, the participants who provide them, and the data the customer submits with the application. No code, no template to train.

02

Let the paperwork land

Files arrive by API, email, or portal, in any order, over days. They are classified, split, extracted, and matched to the requirement they actually satisfy, not the first one that looks close.

03

Get two verdicts

Exhaustivity says what is still missing and from whom. Coherence says what does not add up. Both are recomputed every time anything about the case moves.

04

Decide, and keep the trail

A human validates or rejects. The decision is stamped with the exact policy version and the exact values it was taken on, and it reopens by itself if the facts change afterwards.

Case configurationBusiness loan, one borrower and up to one guarantor
What the dossier collects
Identity document1 per participant
Bank statements3, distinct months
Proof of addressinvoice or utility bill
Host identity documentonly if hosted
What makes it acceptable
The ID is still valid on the day we look at it
@identity.expirydate > TODAY
The borrower is the account holder
@identity.holdername == @statement.client_name
Three months of balances cover a year of instalments
SUM(@statement.balance) > @case.amount / 12

Exhaustivity

A checklist knows what is expected.
This one knows who owes it.

Requirements belong to participants, not to the file. A co-borrower brings their own identity document. A guarantor brings a different set entirely. The same policy therefore expects a different pile depending on who is actually on the case, and it works that out on its own.

Participants are declared as a type and a count

One borrower, who may be one or two people. One host, only ever one. Three borrowers on a case capped at two is a gap the file states out loud, not something a reviewer notices on a Friday.

Counts are real, and so is distinctness

Three bank statements means three different months, not the same month sent three times. A twelve-page bundle holding three statements counts as three, because segmentation splits the content and the case counts the parts.

Some documents are only required sometimes

Ask for the host's identity document only when the proof of address turns out to be a hosting certificate. The condition is part of the policy, so nobody has to remember the follow-up rule.

One document can satisfy two requirements

A company registration extract proves the company exists and identifies the legal entity. Asking for it twice is how a customer decides you are not worth the trouble.

Marie DupontBorrower
Complete
Identity document1 / 1
Bank statements3 / 3
Paul MartinCo-borrower
1 missing
Identity document1 / 1
Proof of address0 / 1
GuarantorExpected

1 participant provided, 2 expected. Nothing has been sent for the second one, so there is no row to tick and no document to chase. The case says so anyway.

Coherence

Every document is genuine.
The story still does not add up.

Most bad files are not forged. They are inconsistent: the salary on the payslip does not match the credit on the account, the address on the ID is two moves old, the company on the invoice was struck off last year. No single document is wrong. The case is.

Rules in your words

Describe the check in plain language and it is compiled into Hololang, our validation language. The compiled line is shown back to you, so a rule is never a black box a vendor owns.

The declared income holds up against the account
ASSERT @payslip.net_salary <= @statement.monthly_credit * 1.05

Across documents, and across people

A check that names two participants is evaluated over every pairing, and returns one verdict per person. A guarantor who passes can never hide a co-borrower who does not.

Sums, counts and arithmetic over the whole case
ASSERT SUM(@statements.balance) > @case.amount / 12

Compared on normalised values

Addresses are resolved against the national address base, companies against the trade register. Two addresses match because they are the same place, not because they are the same string.

Same address, written two different ways
@id.enriched.address.provider_id == @bill.enriched.address.provider_id
Agent review

When a failure deserves a second look

A strict comparison says Marie Dupont and Marie Bernard are different people. A human would ask whether one is a married name. You choose which checks get that treatment: on failure, an AI agent adjudicates with the surrounding evidence and writes down its reasoning.

The agent can only soften a mechanical failure, never invent a pass on its own, and its verdict is stored word for word with the values it saw. Reviewers read the argument, not a score.

KONames do not match
identity.holdernameMarie BERNARD
statement.client_nameMarie DUPONT
AgentAccepted

The identity document lists DUPONT as the maiden name and BERNARD as the married name. The account was opened under the married name. Same person.

Traceability

Why did this file pass
on the 3rd of March?

An auditor, a regulator, or your own risk committee will ask that question about a decision taken a year ago, under a policy that has changed twice since. Automation that cannot answer it moves the problem rather than solving it.

Every verdict is stamped

The policy version, the engine version, and the date the checks were pinned to. Re-reading an old decision shows the rules as they were, not as they are today.

Every value carries its source

Each compared value points back to the document, the extraction run, and the page it came from. A disputed number is one click from the pixels it was read off.

The history is append-only

Status changes, policy edits, agent verdicts, and the corrections your team made to an extracted value are all kept. Nothing is overwritten, so nothing has to be reconstructed.

A decision reopens when the facts move

Validate a case, then a corrected extraction changes a compared value: the validation is cleared and the case comes back with a reason. A stale approval is worse than no approval.

Case history
Case validated
by Camille R. · policy v.9f2c · engine c4.8
Agent accepted a failing check
married name, rationale stored
Value corrected by a reviewer
net salary 2 140 → 2 410 · case re-evaluated
Registry lookup landed
company active, head office confirmed
Case opened by API
12 requirements, 2 participants

Integration

One case id.
Everything else attaches itself.

Open a case with the data your customer typed into your own form. Upload documents against the same id, whenever they arrive. Read the verdict, or let a webhook push it to you when it changes.

POST/api/v1.1/cases/
{
  "case_id": "LOAN-2026-0481",
  "case_fields": {
    "amount": 480000,
    "duration_months": 120,
    "borrower": [
      { "first_name": "Marie", "last_name": "Dupont" },
      { "first_name": "Paul",  "last_name": "Martin" }
    ]
  }
}
GET/api/v1.1/cases/LOAN-2026-0481
{
  "case_status": "incomplete",
  "completion": false,
  "requirements": [
    { "key": "proof_of_address",
      "state": "missing",
      "required": 1, "provided": 0,
      "participant": "b2" }
  ],
  "missing_participants": [],
  "rules": [
    { "rule": "ID holder = statement holder",
      "status": "ko" }
  ]
}

Documents ride along

An upload carrying the case id joins the file and binds to the participant who sent it. Sending the same document twice changes nothing.

Values merge across calls

A first call with what you know, a second when the customer completes the form. Partial data is a normal state, not an error.

Or use no API at all

Cases open from documents arriving by email, and your team works them in the Holofin interface. The verdict is the same either way.

Where it pays

Any process where a file
is judged as a whole.

If your team keeps a checklist next to the screen, that checklist is a case configuration waiting to be written down.

Credit and leasing

Borrower, co-borrower, guarantor. Identity, income, bank statements, company registration. The file is complete when every participant is covered, and coherent when the declared income survives contact with the account.

Onboarding and KYC

Beneficial owners are participants too. Each one owes an identity document, and the registry says how many there should be. A file missing the third owner says so instead of looking finished.

Rental applications

Tenant, co-tenant, guarantor, and the hosting certificate that only becomes required once somebody proves their address with one. Income against rent is a rule, not a mental note.

Insurance claims

Report, invoices, photographs, expert assessment. The claimed amount has to agree with the invoices, and the dates with the incident. One verdict per claim, reopened if a late invoice changes it.

Supplier and tender files

Registration extract, insurance certificate, tax and social clearance, signed terms. Each has an expiry date, so the file goes back to incomplete on its own when a certificate lapses.

Subsidies and grants

Eligibility is a set of rules over several documents, and the burden of proof is on the file. The rules are written once by the people who own the scheme, and applied identically to every applicant.

Questions

Dossier intelligence, in short

Intelligent document processing judges one document at a time: what type it is, what its fields say, whether it contradicts itself. Dossier intelligence judges the case those documents belong to: whether everything expected has arrived, from every participant, and whether the documents agree with each other and with the data the customer declared. It is the layer that turns a stack of extractions into a decision.

Yes, and it names who owes it. The answer distinguishes a missing document, a missing data field, and a missing participant, which are three different messages to send a customer. Because the gap list is computed from the policy rather than typed by a reviewer, one relaunch email can carry everything that is still outstanding instead of arriving in four instalments.

The people who own the policy, not the engineering team. A check is described in plain language and compiled into Hololang, a small validation language built for this, and the compiled line is displayed next to the description so it can be read back and challenged. Rules are versioned, and a rule that stops making sense because the policy changed is reported rather than silently skipped.

That is the point of it. Participants are declared as a type and a count, so a policy can expect one borrower who may be two people and at most one guarantor. Requirements and checks are then evaluated once per participant, and each gets a verdict of its own. A passing co-borrower can never mask a failing one.

Every evaluation stores the policy version, the engine version, the date the checks were pinned to, and the value each comparison used together with the document it was read from. Decisions, policy edits and agent verdicts are kept append-only. A file judged a year ago can be re-read under the rules that applied at the time.

Dossier Intelligence

Bring us a case
your team dreads.

Send a real file, with its missing pieces and its contradictions. We will configure it live and show you the verdict it produces.

Sandbox environment
Hosted in Europe
Holofin