Who this is for
You do good work for small businesses and you are bad at billing. Or you want a first AI service to sell to a local business that pays for itself the day you deliver it, because it finds money they already earned.
Every guide here starts the same way: we run it on our own shop first and print the numbers. This one hurt.
What you get at the end
- A report of three leaks, each with the row that proves it: delivered jobs with no invoice, sent invoices past due (with days late), and jobs billed under your own price floor.
- A reminder email draft for every overdue invoice, with the tone set by how late it is. Drafts only. You send them, or you do not.
- A service you can run for a local business in one sitting.
What it costs
- The Claude plan you already pay for. No API keys, no new subscriptions.
- Python 3 (already on every Mac).
- About an hour for your own books, most of it spent getting the exports clean.
Build it
- Install the skill: copy the
unbilled-work-finderfolder into~/.claude/skills/. Open Claude Code in any folder. - Export two files from wherever you track work. QuickBooks, Wave, Square, a spreadsheet, a notebook all work. You need
jobs.csvwithjob_id,client,kind,delivered_onandinvoices.csvwithnumber,job_id,amount,issued_on,due_on,status. - Write your floors in
floors.csv: the lowest price you will do each kind of job for. Mine are on my offer sheet: a one-page site is $1,250. Decide yours before you look at the report, or the report will talk you out of it. - Run
python3 scripts/find_unbilled.py --jobs jobs.csv --invoices invoices.csv --floors floors.csv. - Go down the unbilled list and mark anything you settled another way (a trade, a favor, a retainer). Those are decisions. Everything left is a leak.
- Edit the reminder drafts and send the ones you mean from your own inbox.
Prompts to copy
Clean the exports (paste with your raw export attached):
Turn this export into two CSV files for the unbilled-work-finder skill.
jobs.csv columns: job_id,client,kind,delivered_on (YYYY-MM-DD, empty if not delivered).
invoices.csv columns: number,job_id,amount,issued_on,due_on,status (paid|sent|draft|void).
Do not guess. If a job has no delivery date or an invoice has no job, list it under QUESTIONS
and leave it out of the CSV. Show me the questions before you write the files.
Read the report back:
Run the unbilled-work-finder on jobs.csv, invoices.csv and floors.csv.
Lead with the single biggest dollar number and the rows behind it.
For every unbilled job, ask me whether it was settled another way before calling it a leak.
Then show the reminder drafts. Do not send anything.
Sell it
The offer: a "money already earned" audit for a local business. One sitting, their exports, the report and the reminder drafts handed over before you leave. Price it flat, never as a percent of what they collect. As an example only: $250 for the sitting. We have not sold this one yet, so treat that as a starting point, not a result.
Hi {name}, quick question for {business}.
Most shops I talk to have finished work that never got invoiced, and invoices
that went quiet. I run a one-hour check on your job and invoice exports that
lists every one, with the row that proves it, and drafts the follow-ups for you
to send. Nothing gets sent or changed without you. Want me to run it this week?
Where it breaks
- An invoice tied to the wrong job makes that job look unbilled. The report lists invoices pointing at unknown jobs so you catch the typo before you embarrass yourself.
- Quarterly retainers look like gaps between invoices. Give retainer work its own
kindand a floor of the period amount. - A negative invoice used as a credit is not supported. Record credits as a separate paid line, or fix them by hand first.
- The script finds the money. It cannot make you ask for it. The reminders sit in drafts until a person sends them.
Receipts
When I ran the same check on my own books (money-map reads them read-only), the client work I had delivered came to $23,500 at my own lowest offer tiers. I had billed $725 for that work. The gap is $22,775.
Across everything, my books show $1,625 billed in 7 invoices, $1,175 of it paid. Small numbers. They are real, and this site will print them every time they change, because the guides are checked against the books before they publish.
Prove it on your machine: python3 scripts/find_unbilled.py --jobs examples/jobs.csv --invoices examples/invoices.csv --floors examples/floors.csv --today 2026-10-09. Prove mine: the numbers above are checked by foreman playbook check against the books on every build. If they go stale, the guide stops publishing.