Was this receipt submitted before?
Upload it to check. Receipt Audit compares it with every receipt checked here before, by you or by anyone else, and says when it was first seen. Re-saved, cropped and re-photographed copies still match. Free for 5 receipts a day, no account.
The result says "Seen before" with the date it was first seen and whether someone else sent it, or "Not seen before by anyone using Receipt Audit". The same check also looks for edits and AI generation.
How matching works
Each check makes two kinds of fingerprint. The network looks them up before it adds them, so a receipt's first check never matches itself.
Image fingerprint
A 64-bit perceptual hash (dHash) of the picture, taken after scaling it down. When the receipt sits inside a plain border, such as a screenshot's bars or a desk, a second hash covers just the receipt. Two hashes at most 3 bits apart count as the same image. This catches re-saved, re-compressed and resized copies, and some screenshots.
Key-fields fingerprint
SHA-256 hashes of what the receipt says: merchant, date, total, currency and receipt number, plus a few other combinations of merchant, date, time, total, receipt number and line amounts. Each combination is specific enough on its own, so one misread field doesn't hide a copy. This catches the same purchase in a different file: cropped, rotated or photographed again.
PDFs get key-field fingerprints only. A copy matches on its fields only when the model reads the same values from it, so a copy too blurred to read can slip through.
What the result says
Every check returns a duplicate object. image and fields each hold the earlier match on that fingerprint, or null. kind is exact for the same hash and near for an image a few bits away (distance). firstSeen is a Unix time in milliseconds. A match also adds a verifiable signal: duplicate_other_submitter when someone else sent it, duplicate_same_submitter when it was your own account.
{
"duplicate": {
"image": null,
"fields": {
"kind": "exact",
"distance": 0,
"firstSeen": 1791969120000,
"timesSeen": 1,
"seenBySameOwner": false,
"seenByOtherOwners": true
},
"seenBefore": true
},
"signal": {
"code": "duplicate_other_submitter",
"weight": 0.6,
"message": "Someone else submitted this receipt before (first seen 2026-10-14).",
"kind": "verifiable",
"field": "whole_document"
}
}One network across every customer
Every API account and every visitor to the free checker feeds the same network. A receipt filed with one company and then with another is a match. The result says whether the earlier check was yours or someone else's, never who.
How this differs from a duplicate check inside one account
A duplicate check inside one account only sees that account's receipts. It catches an employee who files the same receipt twice. It can't see the same receipt filed with another employer, a rebate program or a returns desk. Receipt Audit reports both: seenBySameOwner is your own history, seenByOtherOwners is everyone else's.
The network is young
It only knows receipts checked on Receipt Audit since the site launched in October 2026. A receipt that was never checked here can't match, however often it was used elsewhere. The network grows with every check.
How well it matches
On RA-Bench's held-out set (run of 2026-10-18, preliminary), Receipt Audit recognised 98.9% of resubmitted copies (n=30; 95% interval 86.8–99.9%). The copies were re-saved, resized, cropped, rotated, screenshotted or re-photographed versions of receipts checked earlier. It wrongly matched 4.5% of look-alike receipts from the same shop, template or day (n=22), and 0.0% of other genuine receipts (n=59). The benchmark's network starts empty for each run, so these numbers measure matching, not the size of the live network.
Privacy: hashes only
The network stores hashes, never the image or what the receipt says, and a hash can't be turned back into the receipt. With each hash it keeps when it was first and last seen, how many times, and which accounts sent it: an account id, or a hash of the IP address for the free checker. Privacy policy
Duplicate detection API
Every API check returns the duplicate object, at no extra cost: there is no separate call. Agents can get a key on their own.
# Once: a key with 50 free checks, no sign-up
curl -X POST https://receiptaudit.com/api/v1/keys
# → { "api_key": "raud_…", "credits": 50, "claim_url": "…", … }
# Check a receipt by URL
curl -X POST https://receiptaudit.com/api/v1/receipts/check \
-H "Authorization: Bearer raud_…" \
-H "Content-Type: application/json" \
-d '{"image_url": "https://example.com/receipt.jpg"}'
# or send the file itself
-d '{"image_base64": "'"$(base64 < receipt.jpg)"'"}'Frequently asked questions
What does it mean when a receipt is duplicate?
Two different things. A store's "duplicate receipt" is a reprint of your own receipt, often marked DUPLICATE or COPY. In expense, refund and rebate checks, a duplicate is the same receipt submitted twice, by the same person or by someone else. This page checks for the second kind.
How to detect a duplicate invoice?
Compare what it says, not only the file: the same supplier, date, total and number. Receipt Audit fingerprints those fields, so an invoice exported again or scanned still matches. Invoices sent as PDFs are matched on their fields only.
Can fake receipts be detected?
Often, not always. A reused receipt is the easiest to prove: if the same receipt was checked here before, the result says so and gives the date. Edited and AI-made receipts leave other traces, covered on the AI-generated receipt checker page.