PDF Security Blog

PDF Fraud Detection in Loan Origination: Choosing the Stage

HTPBE Team··10 min read
PDF Fraud Detection in Loan Origination: Choosing the Stage

This article is a snapshot – content was accurate as of May 2026 (code examples tested against the API as of October 2026). The product evolves actively; specific counts, examples, and detection rules may have changed since publication – see the changelog for the current state.

A loan file collects the same four or five PDFs from almost every borrower: bank statements, pay stubs, a W-2 or tax return, sometimes an employment or asset letter. Each one is a file the borrower held, and could open in an editor, before it reached you.

This article is about one narrow question: at which points in the origination flow does it make sense to check whether those files were edited, and what do you do with the answer? It is not about verifying income or identity. Those controls stay where they are. A file check adds one more fact to the loan file: whether the document looks like the original output of the system that supposedly produced it, or like something that was changed afterwards.

It is written for the lending-operations or LOS owner who has to choose the stage: intake, pre-underwriting or post-closing. The product-level overview for lenders is fintech lending fraud detection; the same question seen from a digital onboarding flow, where an identity check has already passed, is in what your KYC flow does not check.

What a file check does and does not tell you

A check reads the PDF itself, not the numbers printed on its pages. It answers a single question: does this file’s internal history look like an original export, or like an original that was modified later?

That is different from the controls you already run:

  • Content extraction (OCR and bank-data aggregators) reads what the page says and compares it with stated income or transaction data.
  • Source-of-truth checks (payroll-provider lookups, tax transcripts, a call to the employer) corroborate the facts against a record the borrower never touched.
  • Identity verification confirms the person applying is who they claim to be.

A file check is none of these. It cannot tell you that a borrower earns what the pay stub says, and it cannot tell you who the borrower is. It can tell you that the pay stub in the file is probably not the file the payroll system produced. For how this layer relates to identity checks, see KYC vs document forensics.

Where it fits in the origination flow

There are three natural points. You do not need all three; most teams start with one.

1. Application intake

The check runs the moment a borrower uploads a document, before it is attached to the loan file. The borrower is still in the session, so a problem can be handled in the cheapest way possible: ask for a fresh download directly from the bank or payroll portal.

Best for: high-volume digital channels, where nobody reads the file until much later.

2. Pre-underwriting

The check runs when the file is assembled and ready for an underwriter, usually as a batch over everything the borrower submitted. Findings arrive together with the rest of the file, and the underwriter sees them before spending time on the numbers.

Best for: teams with an existing underwriting queue and no real-time intake. It also catches documents that were swapped or re-uploaded later in the process.

3. Post-closing quality control

The check runs on a sample of closed loans, or on every loan flagged by an existing QC rule. The goal is not to stop a loan but to measure how often edited documents reach closing and to find patterns by channel, broker or product.

Best for: a first look at your own exposure. A sample of recently closed files is a low-commitment way to see whether the problem exists in your book before changing any intake logic.

Choosing the stage: a volume example

The three stages cost different amounts of checking and teach you different things. The figures below are illustrative: a lender that receives 300 applications a month, collects four institutional PDFs per application, takes 60% of applications through to underwriting and closes 75 loans a month.

StageChecks a monthPlan that covers itWhere a problem is cheapest to fixWhat you learn
Application intakeabout 1,200 (300 × 4)Pro covers 1,500The borrower is still in the session; a fresh download takes minutesHow often edited files are uploaded, by channel
Pre-underwritingabout 720 (180 files × 4)ProBefore the underwriter spends time on the numbersWhich files an underwriter should read first
Post-closing sampleabout 30 (a 10% sample of 75 closings × 4)Starter covers 30Not at all; the loan has closedWhat your exposure was, without touching intake

Plan allowances and prices are on the pricing page: Starter 30 checks, Growth 350, Pro 1,500 a month, and Enterprise above that.

Two readings follow. Intake is the most expensive stage and the cheapest place to fix a problem. The post-closing sample costs almost nothing and tells you whether the problem exists in your book before you change anything. For that reason the usual order is sample first, then decide.

Reading a post-closing sample

Record the verdict mix per channel and per document type, not one overall rate. A bank statement with a modified verdict from a broker channel and the same result from a direct digital channel are different findings. Treat each modified file as a question for the file, not as a count of fraudulent loans: some will turn out to be a borrower who cropped or annotated a statement. The useful output is the shortlist of channels and document types where intake checking would pay back first.

What to keep with the loan file

For each checked document keep the check ID, the verdict and the stated reason for an inconclusive result, the time of the check, and the reviewer’s action. If an investor, an insurer or an auditor later asks what was done about a document, the record answers it. What you must keep, and for how long, is a matter for your compliance team and your investor agreements, not for this article.

Which documents to run

Not every file in a loan package claims to come from a bank or a payroll system. Run the check where the document purports to be an output of an institutional system:

DocumentPurports to come fromWorth checking
Bank statementsThe bank’s statement systemYes, the highest-value target
Pay stubsA payroll platformYes
W-2s and tax formsPayroll or tax software, or a tax authorityYes
Employment and asset lettersAn employer or institutionYes
Borrower-written letters (explanation, gift letter)The borrowerResult is expected to be inconclusive; do not treat it as a finding

For document-specific context, see bank statements, pay stubs, tax documents and employment letters.

One document, start to finish

A borrower uploads a bank statement as part of a purchase application. In the intake service, the file is stored and its URL is sent to HTPBE?. The result comes back as a verdict and a short list of named markers. There is no numeric score:

{
  "id": "4e2a1b9f-7c3d-4f8e-b2a1-5d0c9e3a7f2b",
  "status": "modified",
  "modification_confidence": "high",
  "modification_markers": ["HTPBE_EDITING_TOOL_FINGERPRINT", "HTPBE_MULTIPLE_REVISION_LAYERS"]
}

The routing logic reads the verdict and the document type, and writes the check ID to the document record. The same ID is how anyone on your team with access to the account opens the full report later, whether an underwriter, a QC reviewer or someone preparing a repurchase response.

import os
import httpx

BASE_URL = "https://api.htpbe.tech/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['HTPBE_API_KEY']}"}

# Documents that purport to come from an institutional system
INSTITUTIONAL = {"bank_statement", "pay_stub", "w2", "tax_return",
                 "employment_letter", "asset_letter"}


def route_document(pdf_url: str, doc_type: str) -> dict:
    submit = httpx.post(f"{BASE_URL}/analyze", headers=HEADERS,
                        json={"url": pdf_url}, timeout=30)
    submit.raise_for_status()
    check_id = submit.json()["id"]

    result = httpx.get(f"{BASE_URL}/result/{check_id}", headers=HEADERS, timeout=30)
    result.raise_for_status()
    data = result.json()

    status = data["status"]
    if status == "modified":
        return {"queue": "pre_underwriting_review", "check_id": check_id,
                "markers": data.get("modification_markers", [])}
    if status == "inconclusive" and doc_type in INSTITUTIONAL:
        return {"queue": "request_original", "check_id": check_id}
    return {"queue": "underwriting", "check_id": check_id}

The endpoint, fields and error codes are in the API documentation. Test keys are available for building this against synthetic results before any live borrower document is involved.

What each verdict means in practice

The verdict describes the file, not the borrower. These are example outcomes and the action a lender might attach to each:

intact – The file shows no sign of having been changed after it was created. On a bank statement or pay stub this is what an original download looks like. The document proceeds to normal underwriting, where the content is still checked the way it always was. intact is not a statement that the figures are true.

modified – The file was changed after creation, and the response names what it found. For example, a bank statement returning HTPBE_MULTIPLE_REVISION_LAYERS is a file that was modified after it was created. The document goes to pre-underwriting review with the markers attached. A reasonable next step is to ask the borrower for a fresh download straight from the portal, and to compare the new file with the old one. A single modified result is a reason to ask, not a conclusion about intent: a borrower may have annotated or cropped a statement without any wish to mislead.

inconclusive – The check cannot confirm the file’s integrity. Typical reasons are a scan or photo saved as PDF, a filled-in form, or a file made with general-purpose software; the reason is returned in the status_reason field. On a borrower-written letter this is normal. On a document that purports to be a bank statement or payroll output, the file’s integrity is simply unconfirmed. That is not evidence of forgery: a borrower who printed and scanned a genuine statement lands here too. The sensible next step is to request the file directly from the issuer, then check that one.

What a file check cannot do

Be clear with underwriting, compliance and the business about these limits:

  • It does not verify income. A pay stub can be perfectly intact and still wrong, for instance when it was produced by a real payroll account the borrower controls. Payroll lookups, tax transcripts and employer contact remain the controls for the figures.
  • It does not verify identity. Whether the applicant is who they say they are is a KYC and identity-verification question. A file check says nothing about the person.
  • It does not read the content. It does not extract, compare or validate amounts, names or account numbers.
  • It cannot find an edit that never happened. A document fabricated without ever being edited leaves no edit history to find, so figures still need to be corroborated at the source.
  • It cannot assess password-protected files. They are not accepted for analysis; ask the borrower or the issuer for an unprotected download.
  • It does not decide a loan. A verdict is one input to a human review, not an approval or denial.

Starting small

The least disruptive way to try this is the post-closing sample from the flow above: pick a slice of recently closed loans, run their bank statements and pay stubs through the web tool at htpbe.tech, and see what comes back. Plans and credit packs are on the pricing page. If the results justify intake or pre-underwriting automation, the API is self-serve, and registering for API access takes a few minutes.

For the document-level view of bank statement and income fraud in lending, see bank statement fraud in lending and altered pay stubs and W-2s in mortgage underwriting. For the product page covering lending teams, see fintech lending fraud detection and mortgage document fraud detection.

Share This Article

Found this article helpful? Share it with others to spread knowledge about PDF security and fraud detection.

https://htpbe.tech/blog/pdf-fraud-detection-loan-origination

Secure your workflow

Create your account – check PDFs on the web or with an API key, both ready on signup.
No sales call. Cancel any time.