Duplicate Expense Detection
Send it again. You will not break anything.

Duplicate expense detection that lets you safely resubmit

Most writing about duplicate expenses is about removing them. This page is mostly about the opposite problem — the receipt you never resent because you were afraid of double-counting.

Quick answer: How does duplicate expense detection work in ExpenseBot?

ExpenseBot treats a receipt as a duplicate only if that same receipt is already in your spreadsheet. Before adding anything it checks the sheet; if the receipt is already there it is skipped, and if it is not there — because it failed the first time, or the connection dropped — it is processed normally. That is the whole rule, which is why resubmitting a receipt you are unsure about is safe. Card statements are handled separately: the same charge appearing in two monthly statements is matched on merchant name, amount and date within ±1 day and suppressed, so a December 31 charge that posts in both December and January is counted once.

✓ 60-day free trial • ✓ No credit card • ✓ Your data stays in your Google Drive

There are two duplicate problems, and they are opposites

When people say “duplicate expenses” they almost always mean one of these. They are not variations of the same problem — they push your numbers in opposite directions, and only one of them is the one you should actually worry about.

Problem A — the same expense is in there twice

You forwarded a receipt email that also got picked up by a Gmail scan. You photographed something you had already uploaded. You imported two card statements that overlap at the month boundary. Your totals are now too high, and a category or a client is carrying spend that never happened. This one is visible, annoying, and — importantly — fixable after the fact.

Problem B — you were scared of Problem A, so you never resent it

A receipt failed, or you were not sure it went through. You decided not to risk sending it again, and it quietly never got captured. Nothing looks wrong — there is no duplicate row to notice, no error to investigate. The expense is simply missing, and a real deduction goes unclaimed. This is the more expensive problem precisely because it is invisible.

Problem A leaves evidence. Problem B does not. A duplicate row can be found and excluded in under a minute; an expense you never submitted is not on any list to be reviewed. So the rest of this page is written to make Problem A cheap enough to stop causing Problem B.

The rule, stated once and precisely

ExpenseBot considers a receipt a duplicate only if that same receipt is already in your spreadsheet.

Not “looks similar”. Not “same vendor”. Not “same day”. Not “same amount, roughly”. The check is against your sheet, and it runs in a specific order:

  1. Before a receipt is added, ExpenseBot checks your spreadsheet for a match.
  2. If the receipt is already there, it is skipped, so you do not get a double entry.
  3. If it is not there — because it failed the first time, or the connection dropped, or it never reached us at all — it is processed normally.

Everything else on this page is a consequence of that one rule. It is worth reading it twice, because the third line is the one that gives you permission to stop worrying: a receipt that is not in the sheet cannot be treated as a duplicate, no matter how many times you send it.

ExpenseBot is an expense tracking app that reads receipts from Gmail, photos and uploads into a Google Sheet you own, and it checks that sheet before writing a row so the same receipt is not entered twice. Because the sheet is the thing being checked, you can always audit the decision yourself — the record it compares against is the same record you can open in Google Sheets.

What this is not: ExpenseBot does not promise that duplicates can never occur — if two copies of the same receipt are submitted close enough together that the first has not landed in the sheet yet, both can be processed, which is exactly why the cleanup section below exists. It is also not a general ledger, does not do double-entry bookkeeping, and does not file anything for you.

So yes — resubmit it

These are the situations people actually hesitate over. The answer is the same for every one of them, and it is the same for a reason: they all reduce to the single question of whether the receipt is already in the sheet.

Your situationWhat happens if you send it again
It failed with a processing errorIt never reached the sheet, so it is processed normally. Send it.
The connection dropped part-waySame — nothing to match against, so it is processed normally. Send it.
I don't think it went through, but I'm not sureThis is the case the rule is built for. If it did go through it is skipped; if it did not, it is captured. Either way you end up correct. Send it.
I forwarded the same receipt email twiceThe second is skipped if the first already landed. If the first never landed, the second one saves you.
I photographed a receipt that Gmail also picked upThe later submission is skipped once the earlier one is in the sheet.

Should I resubmit?

  • I'm not sure it went through → Yes, resubmit. If it is already in the sheet the copy is skipped.
  • I can see it in my sheet → No need. Resubmitting will simply be skipped, so nothing happens either way.
  • I can see it twice in my sheet → Do not resubmit. Omit one of the two rows (next section).

The other kind of duplicate — the same charge on two card statements

This one is not about receipts at all. Statements overlap at the month boundary: a charge made on December 31 can post in both the December and the January statement, and importing both would count it twice. ExpenseBot matches these on merchant name + amount + date within ±1 day and suppresses the repeat.

That rule lives with the rest of the statement-import behaviour, alongside refunds, credits and chargebacks, which is where it makes more sense to read it in full. See refunds and credits tracking for the statement-level detail, and credit card reconciliation for the import flow itself.

Cleaning up duplicates that are already in your sheet

Open Review expenses from your dashboard, find the duplicate row, and use Omit. On a single row that is ⋯ More actionsOmit from reports & insights, then confirm Omit expense. To do several at once, use Select, tick the rows, then Omit.

What Omit actually does: it keeps the row and the receipt available for reference, but leaves them out of future reports, exports, tax calculations and insights. The sheet row and receipt stay in place. You can include the expense again later from the Omitted view. Existing reports you already generated stay unchanged.

That is the sentence that makes this safe to do quickly. Omit is not a deletion and it is not permanent — it is a decision about what counts, and decisions can be revisited.

If you are not sure which of the two rows is the duplicate, contact support@expensebot.ai before changing it. Two rows that look alike are not always the same expense — a repeat order from the same supplier on the same day is a real second expense, not a duplicate.

Why “just delete the duplicate” is the wrong instinct

Deleting feels tidier. It is the wrong move for one reason: a deleted row takes its evidence with it. An omitted row is still there — with its receipt — if it turns out you removed the wrong one, or if someone later asks why a number changed.

 OmitDelete the row
Row kept?Yes — stays in placeNo
Receipt kept?Yes — available for referenceNo
In future reports?NoNo
In exports & tax calculations?NoNo
Reversible?Yes — include it again from OmittedNo

Both options remove the expense from your totals. Only one of them lets you change your mind. The same reasoning is why an expense audit trail is worth keeping at all — the value is in being able to explain a number later, and a deleted row cannot be explained. Checking for duplicates is also a natural item on a monthly books review, where you are already looking at the month as a whole.

Frequently Asked Questions

If I resubmit a receipt that didn't go through, will it be flagged as a duplicate?

Only if it actually made it into your spreadsheet. ExpenseBot checks the spreadsheet before adding anything, so a receipt that failed the first time — a processing error, a dropped connection, any other reason — is processed normally on the second attempt. Resubmitting is safe.

Will forwarding the same email twice create two expenses?

No. If the first one already landed in your spreadsheet, the second is skipped. If the first never arrived, the second is processed as normal. The forwarding itself is not what decides it — what decides it is whether the receipt is already in the sheet.

I photographed a receipt that ExpenseBot also found in my Gmail. Do I now have two?

Not if the first one was already in your spreadsheet when the second was submitted — at that point the second submission is skipped. If the two arrived close enough together that both were processed, you will see two rows, and you can Omit one of them from Review expenses.

How do I remove a duplicate that's already in my sheet?

Open Review expenses from your dashboard, find the duplicate row, and use Omit. From a single row that is ⋯ More actions → Omit from reports & insights, then confirm Omit expense. Omit keeps the row and its receipt available for reference but leaves it out of future reports, exports, tax calculations and insights.

Should I delete a duplicate row instead of omitting it?

Omit is safer. Deleting removes the evidence; omitting keeps the row and receipt available while excluding them from your totals — so if you omitted the wrong one, nothing is lost and you can include it again from the Omitted view.

The same charge appears on two of my credit card statements. Is that a duplicate?

Yes, and it is handled separately from receipts. When you upload statements, ExpenseBot matches on merchant name, amount and date within ±1 day and suppresses the repeat, so a charge that posts in two months — a December 31 charge appearing in both the December and January statement — is only counted once.

I'm not sure which of the two rows is the duplicate. What should I do?

Contact support@expensebot.ai before changing anything, rather than guessing. An omitted row is recoverable, but if the two rows are genuinely different expenses that happen to look alike, it is better to have someone check than to remove real spending from your totals.

Resubmit the receipt you have been sitting on

Connect Gmail so receipts are captured as they arrive, or upload the one you were not sure about. If it is already in your sheet it will be skipped; if it is not, you just recovered an expense you had written off.

✓ No credit card • ✓ Omit is always reversible • ✓ Your data stays in your Google Drive

Related: receipt organizer app, refunds & credits tracker, expense audit trail, credit card reconciliation, expense tracker template.