See which Housecall Pro jobs actually make you money

By General Input

Open one screen each week to see revenue, cost, gross profit and margin on every completed job, rolled up by job type and by technician.

Integrations

  • Housecall Pro
  • Google Sheets

Type

App

Categories

  • Finance
  • Operations

Build me a job profitability console for Housecall Pro that I open every week to see which jobs, job types and technicians actually make money. Housecall Pro reporting really only shows revenue, so the whole point of this app is to put cost and margin next to that revenue on one screen.

The main view is a sortable table of completed jobs for a date range. Default the range to the last 30 days and default the sort so the worst margins are pinned to the top, since those are the rows I am actually here for. Load the jobs with List Jobs, filtered to completed work status (work_status of complete or completed_unrated) and to the selected date window, and page through with the page and page_size parameters until a short page comes back. Every row shows the job number and customer, the job type, the assigned technician, the date completed, revenue, cost, gross profit and margin percent. Let me sort by any column, search by customer or job number, and filter to a single job type or technician. Put a summary strip above the table with total revenue, total cost, blended gross profit and blended margin for the current filter, plus a count of how many jobs came in under my target margin.

Assemble each row server side. Revenue comes from List Job Invoices for that job, summing the invoice totals. Parts and labor lines come from List Job Line Items, where material and product lines are direct cost and labor or service lines are handled per the cost rules below. Time on site comes from List Job Appointments, summing scheduled appointment duration for the job, which is what drives labor cost. Technician names come from List Employees, cached once per load and joined to the employee ids on the job and its appointments. Job type names come from List Job Types. Cost for a row is materials cost plus labor cost, where labor cost is hours on site multiplied by that technician's hourly cost, and then the overhead percent is applied on top. Gross profit is revenue minus that total cost, and margin percent is gross profit divided by revenue.

Two side panels roll the same numbers up. One groups by job type using List Job Types, showing job count, total revenue, total cost, gross profit and average margin per type, sorted worst margin first. The other groups by technician, the same columns, so I can see who is consistently finishing jobs that lose money. Clicking any row in either panel filters the main table down to that job type or that technician.

The cost assumptions live in a Google Sheet, not hardcoded in the app. A settings panel reads a cost settings tab with Get Values: one row per technician with their hourly labor cost, plus a cell holding the default overhead percent. Show those as editable fields in the app and write my edits back with Update Values, so the owner tunes the cost model inside the app instead of maintaining a separate spreadsheet. When a technician has no row yet, fall back to the default hourly cost and show a small hint that the assumption is a fallback, not a real number.

Every row gets a 'why did this one lose money' button that starts a background agent for that single job. The agent reads the job with Get Job, its line items with List Job Line Items, its appointments with List Job Appointments, and the matching price book entries with List Materials so it can compare what was charged for a part against what the price book says it should cost. It then writes a short plain English diagnosis back onto the job with Add Note to Job, something an owner can read in ten seconds, for example that the job ran three hours over the booked window, or that materials were billed at cost with no markup, or that it looks like a return visit on work already paid for. It tags the job with Add Tags to Job using tags like low-margin or callback, and it appends the finding to a review log tab in the same Google Sheet with Append Values, one row per diagnosis with the date, job, technician, job type, margin and the summary, so the pattern is visible over time.

Show the agent's progress on the row it was started from, and once it finishes, show the diagnosis inline in the table so I never have to open Housecall Pro to read it. On load, read the review log tab with Get Values so previously diagnosed jobs still show their diagnosis and tags after a refresh. Let me run the diagnosis on several rows at once and watch them complete.

Bake in these rules. Housecall Pro money fields are integers in cents, so keep every amount in cents through all the arithmetic and only convert to dollars at the display layer, never the other way around. Invoices are read only through the API: revenue is read and never written back, and the only writes this app ever makes to Housecall Pro are job notes and job tags. Jobs have no top-level update endpoint, so all job mutation goes through those sub-resources. Jobs with no invoice yet are flagged as uninvoiced rather than counted as full losses, and are excluded from the job type and technician averages. Respect rate limits by backing off and retrying on a 429, and cache the employee, job type and material lookups for the session rather than refetching them per job row.

Related prompts

Explore more prompts
Call overdue Xero customers with an AI collections agentLocal listing health board for every location you manageLet support send one-off Loops emails without an engineerStop cold emails to anyone with a live deal in PipedriveiMessage campaign console with pre-flight checks and delivery boardLinkedIn Ads budget pacing dashboard for every client accountFront desk appointment confirmation board for the next 3 daysGive your team Looker numbers without buying more seatsBuild audience segments from product usage and push to LoopsTurn the people who engage with your posts into Pipedrive leads