# Find the Jobber work you finished but never invoiced

> A Monday close-out board that surfaces every completed job, visit, approved quote, and billable expense that never made it onto an invoice.

- Workflow type: app
- Services: Jobber, Slack Bot
- Categories: Finance, Operations
- Published: 2026-08-24

## What it does

- Scans your Jobber account for finished work that never made it onto an invoice and sorts it into four lanes: completed jobs with no invoice, completed visits on jobs that were never billed, approved quotes nobody turned into a job, and billable expenses that never got charged on.
- Totals the money sitting in each lane at the top of the screen, so your Monday close-out starts with one number instead of a spreadsheet hunt.
- Lets you raise the invoice, turn an approved quote into a job, or dismiss a row with a reason the board remembers, so the same rows stop coming back week after week.
- Includes a Build the invoice button that has an assistant read the job, its visits, the hours logged, and the materials used, match them against your price book, and hand you a draft invoice to approve in one click.

## What you'll need

- A Jobber account, with a login that has permission to create invoices and jobs
- Your saved products and services list in Jobber, so draft invoices come back priced at your real rates
- A Slack workspace, only if you want the weekly total posted to a channel

## Prompt

Build me an app called the Revenue Leak Board that I open every Monday morning to find work we already did in Jobber but never billed anyone for. This is a close-out ritual for my ops manager and bookkeeper: one screen, four lanes, and a single number at the top that says how much money is sitting unbilled right now. Keep it strictly about work that was never invoiced. Chasing invoices that were raised but never paid is a different job and does not belong on this board.

Across the top, a summary bar totals the dollars at risk in each of the four lanes plus a combined grand total, so the leak is visible in one number. Each lane below is a column of rows, and every row shows the client name, what the work was, how many days it has been sitting since it was completed or approved, and the dollars at risk. Sort every lane oldest first and make the age visually obvious so the stalest money stands out immediately.

Lane one is completed jobs with no invoice raised against them. Pull jobs with List Jobs, filter to the ones marked complete, and use Get Job for the detail and value of each one. Cross reference against List Invoices to work out which of those jobs have never been billed. The dollars at risk is the job's own value.

Lane two is completed visits sitting on jobs that have never been invoiced. Use List Visits to find visits marked complete, roll them up to their parent job, and show the job's client, the number of completed visits waiting, and the value attached to them. This catches recurring and multi visit work where the job itself may still be open but the completed visits should already have been billed.

Lane three is quotes the customer approved where nobody ever created the job. Use List Quotes to find approved quotes and Get Quote for the line items and value, then check List Jobs to see whether a job was ever created for that client off the back of it. The dollars at risk is the approved quote total. This is the earliest leak in the chain: the customer already said yes and the work has not even been scheduled.

Lane four is expenses booked against a job that were meant to be billed back to the client but never appeared on an invoice. Use List Expenses to find expenses attached to jobs, then check the invoices for that job and their line items with List Line Items to see whether the cost was ever passed through. Show the client, the job, what the expense was, and the amount that never got recharged.

Jobber does not expose a single flag that says whether a job has been invoiced, so the app has to work it out by cross referencing. For each completed job, pull the invoices for that same client with List Invoices and inspect those invoices and their line items with List Line Items for anything that covers the job. Treat a job as unbilled only when nothing matches. Be conservative: when a match is ambiguous, show the row with a short note about why it is uncertain rather than silently hiding it or asserting it is definitely unbilled.

Add a settings control for the staleness threshold, defaulting to 3 days, because the office normally bills within 48 hours and anything newer than that is work in progress rather than a leak. Anything completed or approved inside the threshold is excluded from both the lanes and the totals. Let me also set a minimum dollar amount so tiny rows do not clutter the board.

From any row I can act without leaving the board. Rows in the job, visit, and expense lanes get a Create invoice action that raises the invoice in Jobber with Create Invoice. Rows in the approved quote lane get a Create job action that turns the quote into a job with Create Job, carrying over the line items from Get Quote. Every row also has a Dismiss action that asks me for a reason, for example warranty work, goodwill, already billed outside Jobber, or duplicate.

Store dismissals in the app's own storage keyed to the specific job, visit, quote, or expense, along with the reason, who dismissed it, and when. Keep dismissed rows out of the lanes and out of the totals on every future refresh so the board stays clean week to week. Give me a separate view of dismissed rows with a way to undo a dismissal and put it back on the board.

Every row in the job and visit lanes also carries a Build the invoice button that starts a background agent for that job. The agent reads the job with Get Job, its completed visits with List Visits, the hours logged against it with List Time Sheet Entries, and any materials or costs booked to it with List Expenses. It then pulls my saved price book with List Products and Services and matches the labour hours and materials to the right saved items and rates, assembling proposed line items with quantities, descriptions, and prices. It should explain its reasoning line by line: which visit, timesheet entry, or expense each line came from, and which price book item it matched to, flagging anything it could not match to a saved rate so I can price that myself.

The agent's output lands back in the app as a draft invoice attached to that row, and nothing reaches Jobber until I approve it. Show the proposed line items in a table where I can edit quantities and rates or delete lines before approving. One click on Approve creates the invoice in Jobber with Create Invoice and then leaves a note on the job with Create Job Note summarizing what was billed and what it was based on, so the next person to open that job can see why the invoice looks the way it does. Show the agent's progress while it runs, and let me have several drafts open across different rows at once without losing any of them.

Add a Post to Slack button that sends the weekly leak total and the oldest five unbilled jobs to a channel I choose using Slack Bot Send a Message. Format it as a short readable message with the combined total, the per lane totals, and then the five oldest rows with client name, age in days, and dollar amount, so the whole office sees the number even if nobody else opens the app.

Keep all the on screen copy in plain language for an ops manager or bookkeeper, with no technical or system jargon anywhere in the interface. Format money as currency and ages as plain day counts like 12 days. When a lane is empty, say something reassuring like nothing leaking here rather than leaving a blank space.

## How to customize

- Set the grace period before finished work counts as a leak. It starts at 3 days, since most offices bill within 48 hours.
- Add a minimum dollar amount so small rows stay off the board and the totals reflect what is worth chasing.
- Choose which Slack channel gets the weekly post and how many of the oldest unbilled jobs are listed in it.

## FAQ

### How does it know a job was never invoiced?

Jobber does not keep a single tick box for this, so the board compares each completed job against the invoices raised for that same client and looks at what those invoices actually cover. If nothing matches the job, it shows up as unbilled. When a match is uncertain, the row is shown with a note explaining why rather than being quietly hidden.

### Could this accidentally bill a customer twice?

No. Nothing is created in Jobber until you click, and every draft invoice is shown to you first so you can edit quantities and rates or delete lines before approving it.

### What if we deliberately decided not to bill something?

Dismiss the row and give a reason, like warranty work, goodwill, or already billed outside Jobber. The board remembers it and stops resurfacing that row next week, and you can undo a dismissal at any time.

### How is this different from chasing overdue invoices?

Chasing overdue invoices is about money you already billed but have not been paid for yet. This board is the opposite: work you finished and never billed for at all, so the invoice does not exist in the first place.

### Do I need Slack to use it?

No. Slack is only used by the optional button that posts the weekly total and the oldest unbilled jobs to a channel. The board works on its own without it.

Use this prompt in General Input: https://www.generalinput.com/prompts/find-the-jobber-work-you-finished-but-never-invoiced