Duplicate & Similarity Detection
Surface potential repeat submissions — including modified receipts — with similarity scores for review and workflow decisions.
Resubmitted receipts are a common type of receipt fraud: the same receipt claimed twice by one user, shared between users, or lightly edited to slip past exact-match checks. When the check runs, Taggun compares a submission against prior stored receipts and returns accepted candidates with similarity scores for your workflow to review.
Availability
AvailabilityDuplicate & Similarity Detection is part of the fraud detection suite, included on the Advanced plan and above. Enable Receipt Similarity in your account Feature Settings when it is available on your plan. See Plans & Feature Access.
How It Works
- Data extraction — Taggun extracts text and supporting data from the image.
- Similarity analysis — the extracted data is compared against eligible prior stored receipts in the applicable account-wide scope (or campaign, for validation endpoints).
- Scoring — a similarity score between 0 and 1 is generated for each match found, and any scores over a threshold of 0.8 are eligible for entry into the response.
- Match decision — a prior receipt is flagged as similar when its score clears Taggun's similarity thresholds and key fields line up. Thresholds are fixed, not adjusted per merchant.
Reading the score
| Score | Interpretation |
|---|---|
1.0 | The maximum returned similarity score. It is not proof that two files or physical receipts are identical or genuine. |
Close to 1.0 | A strong similarity signal among candidates returned by Taggun. Review the matched receipt and business context. |
| Lower returned score | The candidate passed Taggun's internal match gates; use it as a review signal rather than an automatic safe/fraud decision. |
A high score alone is not the complete match decision. Taggun applies fixed similarity-score gates together with exact field or metadata conditions. Do not assume that changing one field guarantees that a prior receipt will not be returned. Treat returned matches as review signals.
This check needs stored receiptsDuplicate and similarity detection compares the current submission against eligible previously stored receipts. See Security, Privacy & Data Residency for storage and retention choices.
Scope of Comparison
| Scope | Extraction endpoints | Validation endpoints |
|---|---|---|
| Account-wide | ✅ Uses eligible prior stored receipts in the applicable account-wide scope when containerId is omitted | 🚫 Not supported |
containerId | ✅ Restricts comparison to the specified container | 🚫 Not supported |
campaignId | 🚫 Not supported | ✅ Automatically scoped to the campaign in the request |
When checking runs without a containerId, Taggun uses eligible prior stored receipts in the applicable account-wide scope. A containerId restricts that scope. On validation endpoints, a configured similarity check is scoped to the campaign. Same-referenceId candidates are excluded as documented below.
Request
On extraction endpoints, no request changes are needed once the feature is enabled. On validation endpoints, opt in per campaign via the fraud detection rule:
{
"fraudDetection": {
"allowSimilarityCheck": true
}
}referenceId and userId are accepted on extraction and validation requests; see Common Request Parameters and Validate Receipts for their contract declarations. containerId is extraction-only and is defined in Common Request Parameters:
| Field | Type | Purpose |
|---|---|---|
referenceId | string | Your ID for the submission (maximum 50 characters). When intentionally resubmitting the same receipt, reuse its original referenceId. Candidates with that same value are excluded when duplicate/similarity checking runs, so the resubmission does not trigger a duplicate-receipt flag against the original. This applies to enabled extraction and configured validation flows. |
userId | string | Optional end-user identifier associated with the submission and returned with matched receipts, when available, so cross-user reuse can be investigated. Maximum 50 characters. |
containerId | string | Extraction endpoints only. Scopes similarity comparison to scans sharing the same containerId (e.g. one campaign, event, or client); omit it to compare account-wide. A container is not something you create first — it's whatever value you send, applied at scan time. The extraction-side equivalent of campaignId. |
Common Scenarios
1. Two different images of the same receipt
Two users photograph and submit the same physical receipt — an innocent shared-household mistake or a deliberate double claim.
Example input pair: two photographs of one physical receipt. The image alone does not establish who submitted it or why.
{
"trackingId": "T-001",
"entities": {
"similarReceipts": [
{ "referenceId": "R-001", "userId": "U-001", "trackingId": "T-002", "similarityScore": 1 }
]
}
}2. Attempted bypass with slight modification
A user edits one detail (e.g. the transaction date) and resubmits. The API may return a high similarity score; the value below is illustrative, not a guaranteed result for an edit.
Example input pair: the transaction date differs between the two versions. This does not guarantee a particular score or response.
{
"trackingId": "T-003",
"entities": {
"similarReceipts": [
{ "referenceId": "R-002", "userId": "U-002", "trackingId": "T-004", "similarityScore": 0.98 }
]
}
}3. Multiple similar submissions by the same user
One user submits the same receipt several times — forgetfulness or repeated claiming. Returned matches that pass Taggun's internal gates appear in similarReceipts; the public contract does not promise an exhaustive or unbounded candidate list.
{
"trackingId": "T-005",
"entities": {
"similarReceipts": [
{ "referenceId": "R-003", "userId": "U-003", "trackingId": "T-006", "similarityScore": 1 },
{ "referenceId": "R-004", "userId": "U-003", "trackingId": "T-007", "similarityScore": 1 }
]
}
}4. Multiple similar submissions by different users
Near-identical receipts arriving from several userIds suggests coordinated fraud.
{
"trackingId": "T-008",
"entities": {
"similarReceipts": [
{ "referenceId": "R-005", "userId": "U-004", "trackingId": "T-009", "similarityScore": 0.97 },
{ "referenceId": "R-006", "userId": "U-005", "trackingId": "T-010", "similarityScore": 0.96 },
{ "referenceId": "R-007", "userId": "U-006", "trackingId": "T-011", "similarityScore": 0.95 }
]
}
}5. Lower-scoring match that needs review
Two legitimate purchases can still be similar. This example was returned as a match with a score of 0.82, so Taggun's configured similarity gates were met; use the returned match as a review signal rather than assuming a lower score is automatically safe.
Example input pair: different receipts from the same merchant can share a strong visual pattern. The image alone does not establish authenticity.
{
"trackingId": "T-012",
"entities": {
"similarReceipts": [
{ "referenceId": "R-008", "userId": "U-007", "trackingId": "T-013", "similarityScore": 0.82 }
]
}
}Presence in similarReceipts means the match logic accepted the candidate. Do not invent a universal customer-side "safe band" from the score alone.
Response
Both similarity properties are optional and may be omitted. When present, verbose extraction uses entities.similarReceipts and Receipt Validation uses root similarReceipts. A property may be empty or present without usable match data. Guard for an array before iterating and treat an empty array as no returned candidates.
Verbose extraction returns similarity matches under entities.similarReceipts. Receipt validation returns them at root as similarReceipts; the validation schema permits either an array or null. Compare the other fraud-result shapes in Data Fields That Taggun Extracts.
| Field | Verbose extraction path | Receipt validation path | Description |
|---|---|---|---|
| Similar receipts | entities.similarReceipts | similarReceipts | Similar receipts found. Validation permits an array or null. |
| Similarity score | entities.similarReceipts[].similarityScore | similarReceipts[].similarityScore | Numeric similarity signal from 0 to 1; 1.0 is the maximum returned score, not proof of identity or authenticity. |
| Matched tracking ID | entities.similarReceipts[].trackingId | similarReceipts[].trackingId | Taggun's trackingId of the similar receipt. |
| Matched reference ID | entities.similarReceipts[].referenceId | similarReceipts[].referenceId | Your referenceId for the similar receipt, or null if it was not provided. |
| Matched user ID | entities.similarReceipts[].userId | similarReceipts[].userId | The userId on the similar receipt, or null if it was not provided. |
When no similar receipts are found, verbose extraction can return:
{
"trackingId": "T-20241001-8439425",
"entities": {
"similarReceipts": []
}
}Receipt validation can return:
{
"trackingId": "T-20241001-8439425",
"similarReceipts": []
}The validation schema also permits "similarReceipts": null.
Use Cases
- Promotions — surface potential repeat submissions for review or campaign decisions.
- Expense management — surface potential duplicate reimbursement claims.
Best Practices
- Send
userIdwhen you want matched receipts, when available, to retain an end-user association for cross-user investigation. - Route flagged receipts to a review process rather than hard-rejecting at moderate scores.
FAQ
Will Taggun flag two different people submitting the same receipt?
Similarity matching can return prior matches. Include userId when you want returned matches, when available, to carry the end-user association needed for cross-user investigation; do not assume that userId changes candidate selection.
What if receipts from one merchant are always very similar?
Similar layouts alone are not the full match decision. Taggun also applies fixed similarity-score gates together with exact field or metadata conditions. Do not assume that changing one field guarantees that a prior receipt will not be returned. Review returned matches in business context.
Need something not covered here? Contact [email protected] — see Contacting Support.
Updated 7 days ago