# Invoice reconciliation

> Match a new invoice to its purchase order and get back a decision your finance team can act on.

A finance agent checks each invoice against its purchase order: vendor, line items, quantities, prices, and totals. Vendors and amounts change on every run, but the matching rules don't. This is the job behind the measured run in the [repeat-cost essay](/blog/ai-agent-repeat-costs): about 450x cheaper and 16x faster than Opus 5.5 on one run of each.

![A new invoice and purchase order in, a match decision back](/docs/figures/cookbook-invoice-reconciliation.svg)

## The job

- **New each run:** the vendor, the invoice and purchase order numbers, the line items, and the amounts.
- **Same each run:** your tolerance, your match rules, and the decision fields your system records.

## The call

```python
import json
from openai import OpenAI

client = OpenAI(api_key="YOUR_KEY", base_url="https://api.inferenceindex.com/v1")

RULES = """Match the invoice to the purchase order line by line.
Tolerance: 1% per line. Return JSON with keys:
status (matched|variance|mismatch), variance (number), lines_checked (integer),
issues (list of strings)."""

def reconcile(invoice: str, purchase_order: str) -> dict:
    response = client.chat.completions.create(
        model="workflow/auto",
        messages=[
            {"role": "system", "content": "You reconcile invoices for accounts payable. " + RULES},
            {"role": "user", "content": f"Invoice:\n{invoice}\n\nPurchase order:\n{purchase_order}"},
        ],
    )
    return json.loads(response.choices[0].message.content)
```

## What comes back

An example reply when every line matches:

```json
{
  "status": "matched",
  "variance": 0.0,
  "lines_checked": 6,
  "issues": []
}
```

## In production

- Approve `matched` automatically, and send `variance` and `mismatch` to a person, as your process does today.
- The invoice values are new on every run. This is the case a response cache gets wrong, because it returns yesterday's total. See [how it works](/docs/how-it-works#same-job-new-values).
- An invoice format your agent has never handled goes to your [fallback model](/docs/fallback-models).

## Related

- [Cookbook](/docs/use-cases)
- [Contract review](/docs/cookbook/contract-review)
