---
name: document-reconciliation
source: https://app.decimal.ai/s/document-reconciliation@1/SKILL.md
source_sha256: 474f8e6073c1
---

> **Template skill.** Three-way match is a standard, public accounts-payable method — the discipline below is shared and well-known; only the specific tolerances are yours to set. The tolerance bands and routing thresholds shown are a worked, illustrative example: fork this skill and replace them with your real accounts-payable policy, and the agent then applies *your* thresholds instead of guessing. The measured lift demonstrates the shape works; the specific tolerances are yours to set.

# Document Reconciliation (Three-Way Match)

Takes three documents for one purchase — the **purchase order** (what was ordered), the **goods receipt** (what the warehouse actually received), and the **supplier invoice** (what is being billed) — and decides whether to pay the invoice. The output is a per-line comparison, a typed flag on every mismatch, and one routing verdict.

The base model, handed these three documents and asked "should we pay this?", eyeballs the header totals and gives a narrative yes/no. It does not, by default: match line by line across all three, apply an explicit tolerance band, name each mismatch by type, or route the result through a fixed approve/hold/escalate policy. This skill makes that discipline mandatory.

## When to Use

Activate when the user has an invoice **and** at least one of the order or the receipt and wants a pay decision:
- Should we pay this invoice? Here's the PO and the receipt.
- Do these three documents line up before I release payment?
- Cross-check this supplier bill against what we ordered and received.

Do NOT activate for: pulling fields out of one document (that is extraction), approving a T&E expense report, or matching bank transactions to a ledger.

## Step 1 — Match Line Items Across All Three Documents

Do not compare totals. Build one row per distinct line and pull the ordered, received, and billed figures side by side.

- **Match key:** SKU/part number first. If a document omits the SKU, fall back to a normalized description match (case-insensitive, word-order-insensitive: "Bracket, steel" = "Steel bracket").
- A line may appear on some documents and not others — that absence is itself a finding (Step 3), not a reason to skip the line.
- Compare **quantities against the goods receipt**, not the PO: you pay for what was received, not what was ordered.

## Step 2 — Apply the Tolerance Bands

These bands are org policy (the numbers you fork and replace):

| Dimension | Rule | Within band → | Outside band → flag |
|---|---|---|---|
| **Unit price** | Invoice unit price ≤ PO unit price **+2%** (rounding/FX headroom). Price *below* PO is always acceptable. | pass (note a below-PO price as a favorable variance) | `price-variance` |
| **Billed vs received qty** | Billed qty ≤ received qty. Never pay for more than was received. | pass | `qty-over` |
| **Received vs ordered qty** | Received within **5%** of ordered. Short by more than 5% = short delivery; more than ordered = over-delivery. | pass (note it) | `short-ship` / `over-delivery` |
| **Line extended amount** | Immaterial if off by ≤ the greater of **$2 or 1%** of the PO line amount (pure rounding). | pass | (falls out of price/qty flags) |

Extended edge cases — units-of-measure conversion (cases vs eaches), multi-currency invoices and the FX band, one PO received across several partial goods receipts, and non-matchable lines like freight or tax: see **references/edge-cases.md**.

## Step 3 — Flag Every Mismatch by Type

Assign one of these types to each problem line — a bare "there's a discrepancy" is not enough:

- `price-variance` — invoice unit price above the +2% band.
- `qty-over` — billed quantity exceeds received quantity.
- `short-ship` — received quantity below ordered beyond the 5% band.
- `over-delivery` — received quantity above the ordered quantity.
- `missing-line` — a line on the PO/receipt that the invoice never bills, or invoiced with nothing received.
- `duplicate-line` — the same SKU billed more than once on the invoice.
- `unmatched-charge` — an invoiced line with **no matching PO line at all** (off-contract charge, e.g. a pallet or handling fee that was never ordered).

## Step 4 — Route: Approve / Hold / Escalate

Collect all flags, then pick the verdict by the **highest-severity flag present** (escalate beats hold beats approve):

- **ESCALATE** (control or fraud signal, not a clerk fix) — any `unmatched-charge`, any `duplicate-line`, a re-submitted invoice already paid, or an invoice total over the PO total beyond the price band with no approver on file.
- **HOLD** (recoverable with the supplier or warehouse) — any `price-variance`, `qty-over` (short-pay to the received quantity and hold the difference), `short-ship`, `over-delivery`, or `missing-line`.
- **APPROVE** — every invoiced line matches a PO line and a receipt line, unit price within (or below) the band, and billed qty ≤ received qty. A below-PO price or an under-tolerance rounding gap still approves.

## Output Format

A per-line table, then the verdict:

| SKU | Ordered | Received | Billed | Unit price (PO → inv) | Flag |
|---|---|---|---|---|---|
| A-100 | 100 | 100 | 100 | 12.00 → 12.00 | — |
| A-205 | 50 | 46 | 50 | 4.00 → 4.00 | qty-over |

**Verdict:** HOLD — billed 50 of SKU A-205 but only 46 were received; short-pay to 46 and hold the 4-unit difference with the supplier.

## Worked Examples

### Clean match → APPROVE
Ordered/received/billed all 30 of SKU B-011 at unit 5.00; ordered/received/billed all 12 of SKU B-012 at unit 40.00.
**Verdict:** APPROVE — every line matches on SKU, quantity, and price within band.

### Price above band → HOLD
SKU C-200: PO unit 8.00, invoice unit 8.60 (+7.5%), quantities all equal.
**Verdict:** HOLD — `price-variance` on C-200: billed 8.60 against an ordered 8.00, past the +2% band.

### Off-contract charge → ESCALATE
Every ordered line matches, but the invoice adds a "handling fee" line with no SKU on the PO.
**Verdict:** ESCALATE — `unmatched-charge`: the handling-fee line was never ordered and has no PO line to match.

### Under-tolerance rounding → APPROVE
SKU D-9: PO unit 3.33, invoice unit 3.34 (+0.3%), same quantities; line total off by $0.15.
**Verdict:** APPROVE — the gap is within the rounding band; do not flag a penny.

## Edge Cases

- **Invoice bills the received quantity after a short delivery:** received 40 of an ordered 100, invoice bills 40 — approve the payment (you pay for what arrived) and note the `short-ship` for procurement follow-up; do not hold the payment.
- **Price below PO:** approve and record it as a favorable variance — never hold a discount.
- **Both a hold-level and an escalate-level flag on one invoice:** the verdict is ESCALATE (highest severity wins), even if most lines are clean.
- **A line the invoice under-bills** (billed less than received): favorable — approve, note it.
- **No goods receipt available yet:** you cannot clear the quantity band — HOLD pending receipt, do not approve on the PO alone.

## Quick Checklist
- [ ] Matched line by line (SKU, then description), not by comparing totals
- [ ] Compared billed quantity against the **receipt**, not the PO
- [ ] Applied the +2% price band and the quantity bands explicitly
- [ ] Gave every mismatch a specific flag type
- [ ] Routed by the highest-severity flag: escalate > hold > approve
