DEV Community

Mario Hayashi
Mario Hayashi

Posted on • Originally published at blog.mariohayashi.com on

Using AI to make Xero expense auditing fast, cheap, and (almost) fun

Github: https://github.com/logicalicy/xero-expense-audit

Expense auditing is the kind of work that nobody talks about but most founders quietly dread (or maybe you are more vocal than I am).

Missing descriptions and wrong tax codes? Bills parked in “draft” state for weeks because fixing them individually is a time sink? Oh, of course, those foreign currency receipts that need converting and exchange rate evidence that need attaching.

It’s the kind of work that takes real attention — but not the kind that benefits from being done manually.

I need to audit expenses in Xero from time to time, so I decided to automate it. What I ended up building let me explore how to use AI well in a workflow (”AI UX”). AI is not magic do-it-all but a very cheap, very fast assistant that fills in the gaps where rules can’t.

This write-up is about the CLI tool I built and how I think about using AI for tasks like accounting.

Expense auditing CLI tool — Claude Haiku triaging issues


Setup: Xero, bills, and edge cases

In the context of small business accounting, bills arrive, get created as a “draft” and need to be reviewed before they can be approved and marked as paid.

The review checklist for me is usually:

  • Does the bill have a description?

  • Is the account code valid?

  • Is the tax rate correct?

  • Is there an attachment (receipt or invoice)?

  • If there’s a foreign currency receipt, has it been converted at the right rate with evidence? (E.g. USD to GBP.)

In practice, every item on the above list could go wrong in subtle ways. Suppliers don’t label things helpfully. Receipt transactions are in EUR and Xero parsed them as GBP. When you’re running a lean operation, this kind of review is the thing that gets deferred until it’s too late and you need to sink hours into fixing it.

The tool I built is called xero-expense-audit. It’s a Python CLI that automates the tedious work and flags the tricky tasks for human review. ( Link to repo will be added when I tidy it all up and create a Github repo. Github: https://github.com/logicalicy/xero-expense-audit)


Design principle: deterministic code first, AI second

Before I get into the details, let’s talk about the part that runs first: deterministic code.

This was a conscious choice. The deterministic rules are defined in a rules.yaml config file and they check things like:

  • Is the description field empty?

  • Is the tax rate in the approved list for this account code?

  • Is the amount zero?

  • Is there no attachment when one is required?

These checks are instant, reliable and cheap. And they run before any LLM is called (which absolutely is necessary to keep costs low!). The AI only gets involved when a bill has been flagged and only suggests fixes. AI does not apply the fixes automatically. A human is in the loop.

This design keeps the human (you) in control. AI fills gaps that rules can’t handle: ambiguous categories, unstructured text in receipt images/PDFs, natural-language bill editing (i.e. describing changes that need to be made to the bill in English).


Where I used AI

I used Claude Haiku 4.5 for this project (the smaller, fast Anthropic model), costing approximately ~$1 per million input tokens as of the time of this writing:

1. Triaging bills

After the deterministic rules flag issues with bills, Haiku reviews the bill and returns structured JSON suggestions with a confidence score. Anything below 0.7 confidence gets filtered out. The rest is queued for your review.

It pattern-matches across accounting categories and returns ranked guesses. The confidence threshold filters out noise.

2. Reading receipts/invoices’ supplier name

This was always a headache for me. After attaching a receipt/invoice to a Xero bill, Haiku’s vision reads it and extracts the supplier name. That name then gets matched against existing Xero contacts to find the right supplier. If an existing supplier is not found, the CLI suggests you create a new one.

Doing this manually (especially for new suppliers) used to take a tonne of time before. Now it’s just a few key presses.

3. Reading receipts’ line item descriptions

In the same pass, we also try to detect the line item description. Haiku reads the receipt and populates empty description fields. For example “Monthly subscription fee.”

4. Foreign currency detection/conversion

This one I thought wouldn’t be possible given the need for a third party, reliable data source but it could work.

When a receipt/invoice is in a foreign currency, the tool sends it to Haiku for currency identification. Once identified and if it’s in a currency that’s not the business’s currency, it automatically calls the ECB (European Central Bank) Data API to fetch the historical rate for the transaction date, converts the amount to the business’s currency (GBP in my case), and then uploads the ECB rate CSV export directly to the bill as audit evidence.

The whole flow: receipt in USD > AI currency identification > fetch ECB rate > convert amount > attach rate file.

5. Context-based description fallback

When there’s no receipt, Haiku generates a short description from supplier name + amount + date. A last resort but at least gives us an “out” if we’re stuck.

6. Natural-language bill editing

In the interactive fix-bill command, instead of navigating Xero’s UI to update fields, you are given suggestions on how the bill can be fixed. Or, you just type what you want in English. For example:

Set description to monthly subscription fee

Haiku converts the above to a JSON “patch” and applies it to the bill. This one is small but it makes the UX go from average to great. Instead of clicking through Xero, you just say what you want.


The interactive review flow

Once the audit run is complete, you can use the fix-next-bill command to fix issues, one at a time. AI suggestions are shown beside the bill and all you need to do is approve or edit (in natural language).

Approved bills get auto-fixed and approved (i.e. authorised). The CLI makes this flow a real joy (compared to clicking through Xero). Rich handles the display (colour-coded panels, tables, status indicators) and Questionary handles the interactive checkboxes.

fix-next-bill keeps you in the flow while you audit expenses


The impact

Before, I’d open Xero, manually click through draft bills, fix things individually in the Xero site. Click description field, enter description, click account code, enter account code, etc. I often left the currency conversion until it became a time sink.

After building this tool, with one “run” command, I get a structured list of issues with suggested fixes, review the queue, approve bills in bulk.

The AI helps me semi-automate the corrections. But the deterministic code does most of the work and ensures results are consistent for future audits. You (the human) always stay in the loop: nothing auto-applies unless you explicitly say --auto-correct.

Auditing dozens of bills with full AI suggestions and receipt vision runs to a few cents. Haiku is genuinely cheap enough that it’s a game changer for small business.


What I’d do differently

The natural-language editing (”change description to XYZ”) is fun but most fixes could use predictable patterns. I could turn those into interactive menus next time faster and less prone to misinterpreting and AI safety issues (which is a whole topic in itself). I’d also invest more in exception-handling and testing, as I’ve only tested these on my own expenses (your mileage may vary).


Conclusion

There’s a lot of talk about AI replacing complex knowledge work. What I’ve found through this task is that it’s excellent at very structured tasks. It doesn’t get tired, bored or frustrated about tasks that we might get annoyed about. The tasks still require human input but we get to the decision point much, much faster. This tool freed up real time that I’d rather spend making things.


If you’re experimenting with AI in your workflow, I’d love to hear from you! I write more like this at blog.mariohayashi.com, and feel free to follow me on X: @logicalicy.

Top comments (0)