Duplicate detection
A duplicate payment is the cheapest error to prevent and one of the most tedious to find afterwards. Published estimates of how often it happens vary by more than an order of magnitude — between 0.1% and 2% of payments, depending on whose study you read — which is itself the point: nobody knows their own rate until somebody checks.
inletAP checks once, properly. After an invoice is extracted and coded, it is compared against the invoices you already hold — matched on the vendor, or on the attachment's fingerprint — and anything that matches raises a card. One outcome, and only one, is enforced: an invoice still carrying an open top-tier duplicate card is held out of the export batch until a person answers it.

At the door
One check runs as mail arrives, and it is narrow on purpose: the same message delivered twice — a retrying mail server, a double send from the same sender — is collapsed on an idempotency key built from your workspace, the message's own ID and the raw bytes. The second delivery creates nothing. It is not an invoice comparison and it never links two documents.
Everything below runs after extraction, once there is a vendor, a number, a date and an amount to compare.
The matching rules
These run against the invoices already in your workspace that share this one's vendor or its exact attachment, going back two years, up to the 200 most recent candidates. In plain English:
| Rule | What it looks for |
|---|---|
| The same file | Byte-for-byte the same attachment, arriving as a second document. |
| The same invoice, twice | Same vendor, same invoice number, same amount to the cent. |
| The same invoice, re-sent | Same vendor and number, and the text of the document is identical — a re-generated PDF of a bill you already have. |
| A mis-read digit | Invoice numbers that differ by one character, where the difference is one of the pairs a scanner or a typist confuses: O and 0, I and 1 and L, S and 5, B and 8, Z and 2, G and 6, and 4 and A. The amount has to match exactly. |
| A transposition | Two adjacent characters swapped — 44172 keyed as 44127 — with the same amount, within 90 days. |
| Same number, different amount | Same vendor and invoice number, amounts that differ. Usually a revision, occasionally a real double. |
| Same amount on the same day | Same vendor, same amount, same invoice date, different numbers. A vendor rarely issues two bills of identical value on one day. |
| Same amount, close together | Same vendor and amount within 90 days, different numbers. On its own this is the weakest signal in the set and is treated as one. |
| Same amount, different property | The same figure billed to two buildings within a fortnight. |
Two invoices arriving through different routes — one emailed by the vendor, one uploaded by a colleague — count as stronger evidence than two that arrived the same way. That only applies when the two arrived within three days of each other, and it is a small adjustment rather than a rule of its own.
Rules are never added up. Correlated evidence summed together produces a large number and no more truth, so the strongest rule that matched sets the level and the rest can only adjust it a little. Matching only after leading zeros were stripped, a vendor linked by name similarity rather than by identity, or a field read with low confidence all count against a match.
The guards, which matter more than the rules
Without these, the rules above would flag every recurring vendor you have. A monthly landscaping contract at the same price produces a "same vendor, same amount" pair every single month, and a product that reports that is a product nobody reads by week two.
- The monthly-bill guard. If the vendor and property are on a regular cycle at a steady amount, and the two invoices are a normal cycle apart, the amount-only rules are switched off for them. That is not a duplicate; it is January and February. The guard inverts if the two are only days apart — a monthly vendor that billed twice inside one cycle is strong evidence, not weak.
- The period guard. Two invoices carrying the same base number but different period tokens —
WM-4471-2025-06andWM-4471-2025-07— are never duplicates, whatever else matches. - The credit-note guard. An approved credit from the same vendor for the same amount within 180 days cancels the match. Credit notes and negative documents are excluded from every duplicate rule.
- The statement guard. See below.
- The progress-billing guard. Draws, phases, retainage, deposits and instalments named as such are capped at a note. A four-phase job that bills the same amount four times is doing what the contract says.
- The consecutive-number guard. A vendor issuing
INV-1001,INV-1002,INV-1003puts every consecutive pair one character apart. Near-miss number matching is therefore only allowed when the edit is a genuine transposition or one of the confusion pairs above, when the numeric tails are far apart, and when the amount matches to the cent. - Memory. A pair you have rejected is never raised again. Reject the same kind of match twice for the same vendor and property and that rule is demoted to a silent note for that pair. The memory outlives an
Undotoday: if you accept a duplicate card by accident, undoing it restores the finding but the pair stays muted, and the mute has to be removed from the vendor's suppression list.
The three levels, and which one stops an export
| Level | What you see | What it does |
|---|---|---|
| Hard duplicate | A card naming the document it matched, side by side. | This is the one thing in the product that blocks anything. The invoice cannot be exported to your ledger until a person decides. The hold is applied when the batch is built, so a duplicate raised at any point before the export — including after approval — keeps the bill back. |
| Possible duplicate | A card with the two documents side by side and a one-click Mark duplicate. | Nothing. It informs. Approval and export are unaffected. |
| Note | A collapsed line on the invoice. | Nothing, and it never interrupts. |
Blocking is deliberately reserved for the top level. "We never silently stop your bills" is a promise worth keeping, and a product that stops bills on a weak signal is one whose users learn to click through everything.
We do not publish a catch rate or a false-positive rate, and you should be skeptical of anyone in this category who does. No credible published figure exists for any commercial duplicate engine, ours included. What we will state is what is compared: your own invoices from the same vendor, or carrying the same file, over the last two years — on nine rules and seven guards — before the bill can leave for your ledger.
Statements
A vendor statement — a list of invoices you already have, with a total at the bottom — is one of the three most common reasons an AP tool reports a duplicate that is not one. The total matches invoices you hold, because it is the sum of them.
inletAP looks for the shape of a statement on three signals — several invoice-shaped numbers in the body, a header line like statement of account, aging, balance forward or amount now due, and a total that equals the sum of invoices already in your workspace — and treats the document as a statement when any two of the three are present.
When a document looks like a statement:
- Every duplicate rule is cancelled for it. It is not reported as a copy of anything.
- It is not automatically kept out of export. Nothing stops a statement being approved and posted as a bill, so it is worth rejecting one rather than leaving it in the approval queue.
- No duplicate card is raised on it, so it does not appear in your findings at all. There is no separate "this is a statement" note today.
What to do with it: keep it out of the approval queue. Leave it where it is if nobody is going to approve it by reflex; otherwise reject it. It stays in the workspace as a record, and the invoices it lists are already there. If the statement lists an invoice you never received, that is the useful part — search the vendor, find the gap, and ask them to re-send the missing one. If a document was called a statement and is genuinely a single invoice, open it and code it as normal; the classification applies to the document, not to the vendor.
What this does not do
- It does not check for duplicates across other inletAP customers, or against anything outside your own workspace.
- It does not look at payments. inletAP moves no money, so a bill paid twice in your bank is outside what it can see; what it prevents is the second bill being created.
- It does not contact the vendor about a possible copy.
- It does not delete anything. A document ruled a duplicate stays visible, linked to its original, with the decision in the audit trail.
See also
- Second Look — the rest of what is checked on every bill, and the two verbs.
- Why hasn't my invoice appeared? — when the missing document turns out to be a caught duplicate.
- Export failures — what to do when your ledger refuses a bill number it believes it already holds.