Every guide to spotting an edited PDF — including ours — ends with the same admission: the most reliable check is comparing the file against the original. Banks hold the statements they issued. Employers hold the payslips. Lenders keep the copy from the first application. Yet almost everyone does the comparison by eyeballing two open windows. This page is about doing it properly: what byte-level comparison can prove, in decreasing order of strength, and where it honestly runs out.
Direction matters. Everything below compares a candidate — the file being verified — against an original you already trust: one you generated, received first-hand, or hold on record. Comparing two files you trust equally answers a different, weaker question.
Tier 1: hash them — the only proof
Two commands, one answer
$ shasum -a 256 statement-on-record.pdf statement-resubmitted.pdf
8f2c…a91b statement-on-record.pdf
8f2c…a91b statement-resubmitted.pdf
Equal hashes end the investigation: every byte matches, so content, metadata and structure are all unchanged. This is the only comparison result in this entire field that is a proof rather than a signal, which is exactly why it is worth building workflows where you keep originals. Unequal hashes, though, prove almost nothing by themselves — a re-download through a different pipeline, a re-save, an added signature all change bytes without touching a single visible character. The next two tiers are about reading what kind of difference it is.
Tier 2: the original inside the candidate
PDF has a property no other common document format shares: edits made
in place are appended. An incremental update adds new
objects, a new cross-reference section and a new %%EOF to
the end of the file — and leaves every original byte exactly where it
was. Which means a file edited in place literally contains the
document it was edited from, verbatim, as a prefix ending at a
revision boundary.
Is the original a byte prefix of the candidate?
$ cmp -n "$(stat -f%z statement-on-record.pdf)" \
statement-on-record.pdf statement-resubmitted.pdf \
&& echo "candidate = original + appended bytes"
When this holds — and the join lands on a %%EOF the
candidate's own revision chain recognises — you know something
remarkably strong: the candidate is your original, plus a
recorded edit. Not "similar to". Not "probably derived from". The
unmodified original is sitting inside the file being questioned, and
the appended bytes are the complete, inspectable edit. The reverse
direction is just as informative: a candidate that is a prefix of your
original is an earlier revision — someone submitted the
document as it looked before a later change, such as before it was
signed.
What the appended bytes touched
"Appended revision" is not yet a finding — signing a document appends a revision, and so does filling a form field. The question that decides severity is which objects the appended revision overwrites. An update that adds a signature object touches nothing that was visible. An update that re-writes an object number which already existed in your original — and that object carries page, content-stream or image data — changed what the document shows after you issued it. That distinction is readable from the cross-reference sections, mechanically: this is the strongest form of the incremental-updates signal, because with the original in hand there is no ambiguity about what the earlier revision looked like.
Tier 3: when both files were rewritten
Ancestry breaks the moment either file is re-saved whole — a print-to-PDF, an export, most online tools. The bytes then share no prefix, and the honest comparison degrades to parsed structure, field by field:
- Metadata, both stores. Info dictionary and XMP, compared field by field — producer, creator, title, both date pairs. See PDF metadata forensics for what each divergence means.
-
The
/IDpair. The first entry is assigned at creation and required to survive every save; two files whose permanent IDs match claim descent from the same original. Self-declared, so supporting evidence — never proof. - Page count and page geometry. Re-exports preserve how many pages there are and their physical size; a changed MediaBox on page 2 is a fact demanding an explanation.
- The font sets. A font present in one file and absent in the other means text was re-set by a different tool — or new text arrived in a new face, the same mechanism as the font-anomalies signal.
Every one of these is a fact about difference, not a verdict about intent. Multi-stage document pipelines produce structural divergence legitimately and constantly.
What no byte comparison can prove
That two rewritten files look identical. Proving rendered appearance requires actually rendering both documents and comparing pixels — which means running a full PDF renderer over untrusted input, with the false positives of anti-aliasing and font substitution on top. Acrobat's Compare Files feature lives in that tier, and for a visual side-by-side of two specific documents it is the right tool. A byte-level comparison stops one honest step earlier: it tells you whether and where the files differ structurally, and says plainly that structural cleanliness is not visual identity.
Automating it: one API call
Tamperlens runs all three tiers as a single request:
POST /api/v1/compare with the file on record and the file
being verified. The report leads with the relationship —
identical, candidate-extends-original,
candidate-truncates-original or rewritten —
then the appended-revision classification, the metadata diff and the
structural diff, each as evidence-carrying findings.
Verify a resubmitted statement against the one on record
curl -s https://tamperlens.com/api/v1/compare \
-H "Authorization: Bearer $TAMPERLENS_KEY" \
-F [email protected] \
-F [email protected]
Both files are parsed in memory and never stored; a comparison is metered as two documents against the monthly quota. Details, the full report schema and error codes are in the API quickstart.
Hold originals? Verify against them.
An API key with 25 documents a month — twelve comparisons — is free: create an account or start with the API quickstart. No card required.
Tamperlens reports risk signals and byte-level facts, not authenticity verdicts. Only byte identity is a proof; everything else needs your judgment.
Related reading
- How to detect if a PDF was edited The single-file version of this question: metadata, revisions, /ID pairs and signatures.
- PDF fraud signals field guide All ten signal families, their benign causes and the severity logic.
- Bank statement fraud signals The lender/BNPL/proptech view: screening documents you do not hold originals for.
- API quickstart Auth, curl examples, the report JSON annotated, quotas and pricing.