What it shows
Everyone who reached us on the last intake day, and whether each one became a Jobber request. An intake day is one business day, 12:00 am to 11:59 pm Eastern. Weekends and office holidays are added to the business day before them, so Monday’s report covers Friday, Saturday and Sunday as one intake day.
Who counts as a contact
One row per person per intake day (a person who calls three times in one day is one contact), from any of these:
- an inbound phone call to any office line (Clarity), grouped by the caller’s number;
- a lead record: a CallRail tracking-line call or web form, a ChoiceLocal lead, a Valpak call, a Home Depot Pro Referral email, a ReferPro, Project Quote, Networx or eLocal lead, or a lead-source email;
- a Jobber request created that day: online booking, Angi, Thumbtack, ReferPro, the AI agent, or one the office typed in from a text, an email or a craftsman.
Calls from craftsmen, staff, preferred vendors and our own lines are removed first, by phone number. A text, an email or a GlassHouse reply on its own does not create a contact.
From contact to lead
Each person gets one result. The results are checked in this order, and the first one that applies wins.
| # | Result | What decides it | Lead? |
|---|---|---|---|
| 1 | ⧉ Same household | Another person on this intake day is the same Jobber client. | No |
| 2 | 🟦 Legit decline | The call shows we couldn’t take the work: out of area, a trade we don’t offer, or no craftsman available. | No |
| 3 | ✅ Captured | A Jobber request was made for this person, and this is the first day they reached us about it. | Yes |
| 4 | ↩ Call-back (same request) | No new request. Their one request was entered in Jobber on this day, but they first reached us on an earlier day within the 30 days before the request. That earlier day already counted the request as Captured (row 3), so this contact isn’t counted again. | No |
| 5 | 🔧 Existing job | The call is about an appointment, estimate or complaint we already have, or Jobber shows open work and the call isn’t about new work. | No |
| 6 | ⚪ Not a lead | Wrong number, vendor or partner, sales call, or other. | No |
| 7 | ↩ Call-back (recent contact) | No new request, they already reached us in the last 30 days (a call, a request or a tracked line), and this contact is about the same job as that earlier contact, or the call has no transcript to classify. When the call is about new work, Claude reads it and compares it with what they contacted us about before (their recent request, or their earlier call). Same job: a call-back, not counted. A different job: not a call-back. It goes on to Open or Not captured and counts as a lead. | No |
| 8 | ❔ Couldn’t tell | A missed or under-20-second call with no transcript, no lead record and no Jobber client. | No |
| 9 | 🟨 Contacted, no request yet | We called, texted, emailed or messaged them through Jobber, but there is no request yet. | Yes |
| 10 | 🟥 Not captured | New work with no request and no follow-up. | Yes |
Example for 3 and 4: a customer calls Monday, and the office creates the request Wednesday. Monday is Captured: the request counts on the day they first reached us, not the day it was typed into Jobber. If they also call Wednesday about that same job, no new request is made, and Wednesday is a Call-back (same request). The one request is counted once, on Monday. If Monday’s call had been more than 30 days before the request, the request would count on Wednesday instead. A call after Wednesday about the same job is a Call-back (recent contact), or Existing job when the call is about the scheduled work. “First reached us” looks back up to 30 days before the request was made, and only to contacts about the same job: if Monday’s call had been about something else (say, rescheduling an old appointment), the request counts on Wednesday instead.
Results 2, 5 and 6 come from the call transcript, which exists for calls from July 1, 2026 on. The rest come from Jobber, Clarity and the lead feeds. A separate new request within 30 days of an earlier one is add-on work and counts as a new lead.
Home Depot Pro Referral
- Every Pro Referral “New Job Request!” email is one contact and one lead, dated the day the email arrived. If the same person is emailed again within 7 days, it counts once.
- The email has no phone number, so it is matched to a Jobber request created from 2 days before to 30 days after it: by the Jobber client Pro Referral linked, by first and last name, or, when the name differs, by the same job type and ZIP code within a few days.
- A matched request makes it ✅ Captured. No request makes it 🟨 Contacted, no request yet or 🟥 Not captured, like any other lead.
- A later call about the same referral or request is a ↩ Call-back, not a second contact.
- A Jobber request marked “Home Depot” with no referral email is not a Home Depot lead. It is someone who came back another way, and their lead source is decided by the rules below.
Lead source
Checked in this order; the first rule that answers wins:
- a tracked record for the person that day or in the 30 days before: a CallRail tracking line or web form (SEO, PPC, LSA, email campaign), a ChoiceLocal lead or a Valpak call;
- the BRAG / ActioNet networking log, matched by the client’s name;
- a Jobber integration created the request: HC website online booking, Angi, Thumbtack or ReferPro;
- a Home Depot Pro Referral email matched to the person (above);
- a SendJim postcard in the 60 days before, or a reply to a GlassHouse text;
- the office’s “how did you hear about us” answer in Jobber: the lead source on a new client, or on a returning client only if it was changed on or after this contact;
- Repeat Customers: a repeat customer (see Customer status) that none of the rules above matched, or anyone whose only source is the client’s Existing Customer Lead Source field in Jobber (Oct 28, 2026: that field alone no longer credits the source it names);
- Returning prospect, source unknown: a returning prospect (see Customer status) that none of the rules above matched. They contacted us before but never bought; what first brought them in is usually from before our records (intake history starts Jun 1, 2026; Dispatch has no lead source);
- Not asked: anyone else, meaning people new to us whose source nobody recorded. This is a coaching item, not a source.
Repeat customers are checked against every tracked source first. A repeat customer who called a CallRail line or was on a SendJim list is credited to that source. AI Booking is a way in, not a source; requests the AI agent created are marked 🤖 and still count as Captured.
Customer status
- Repeat customer: before the day they contacted us, a completed Jobber job or a Jobber payment, or a paid Dispatch purchase or a completed Dispatch work visit (Dispatch back to March 2023). A job created the same day doesn’t count.
- Returning prospect: known to us before (a Jobber client, request or call, or their phone or email in our Dispatch records) but never bought.
- New: neither.
People are matched to Jobber by phone number — any phone on the Jobber client (Main, Mobile, Work…), not only the primary one — then by first and last name; Dispatch history is matched by phone or email. Click a call, or a person’s row, in any list to read the call transcript.
The tiles
- Total inquiries: inbound calls plus Non Phone Inquiries (people who reached us without calling). This counts calls, not people. Total inquiries − craftsman calls = Customer inquiries.
- Contacted us: people, one per person, as defined above.
- Contacted us − Same household − Legit decline − Call-back − Existing job − Not a lead − Couldn’t tell = New opportunities.
- New opportunities = ✅ Captured + 🟨 Contacted, no request yet + 🟥 Not captured. 📅 Assessment scheduled is the part of Captured with an on-site assessment booked; its % is of New opportunities.
Yesterday is computed live when you open the report. The date picker shows an earlier window, rebuilt with today’s data. The History pop-up reads the stored intake days, rebuilt nightly at 5:50 am ET.
ℹ️ How This Report Works
What It Is
A breakdown of every lead by where it actually came from, sliced by source: Contacts received, Leads (distinct acquisition events), then Converted, Quoted and Jobs won. Converted, Quoted and Jobs are a strict funnel — each is a subset of the one before it, and all of them are subsets of Leads.
How Each Column Is Calculated
Contacts — every inbound record from that source in the period, completely unfiltered: spam-flagged calls, missed calls, very short calls, vendor/test numbers, and the same person contacting more than once all count. The rawest possible number, useful for total inbound volume. It is not a lead count. Contacts should always be greater than or equal to Leads.
Leads — distinct acquisition events, and the number to quote. Starts from Contacts and removes: spam-flagged records; numbers on the phone-exclusions list (employees, vendors); anyone who already had an open Jobber request, because a call from an existing customer is not a new lead; the same number contacting twice in one day, which collapses to the first; and double-counting where one person appears both as a CallRail record and a Jobber request. This is the figure comparable to an agency report or an outside benchmark.
Converted — a Lead whose matched Jobber client has an on-site assessment booked on a request dated on or after the original contact date. A lead is matched to a Jobber client by phone number first; email is used as a fallback if no phone match exists.
# Quoted — a Converted lead whose matched client has a quote created on or after the original contact date, and on or after 2026‑05‑07 (the date quote-tracking became reliable — quotes before that aren't counted here).
$ Quoted — the total value of those quotes. Same population as # Quoted, so the two can never disagree about which leads qualify. No status filter is applied: archived and draft quotes are included, because the count beside it doesn't filter them either. This is quoted value, not won or billed value.
# Jobs — a Quoted lead whose matched client has a job created on or after the original contact date.
$ Jobs — the total sold value of those jobs: what the work sold for, not what has been invoiced or collected. Jobber leaves a job's total field empty until the job is essentially finished — about half of all recent jobs have no total — so this falls back to the value of the quote the job came from. Every job can be valued that way, which matters: without the fallback a channel whose jobs are all still in progress would read $0 and look dead.
Conv % = Converted ÷ Leads · Slippage % = (Converted − # Quoted) ÷ Converted — the share of converted leads that never got a quote · Success % = # Jobs ÷ # Quoted · ROAS = $ Quoted ÷ Spend · ROI = $ Jobs ÷ Spend.
ROAS and ROI are both return multiples — customer dollars divided by marketing dollars, where 1.00x is break-even. They differ only in which customer dollars they count. ROAS uses quoted value, so it includes work that was proposed and never won; it is the early, generous read. ROI uses sold value, so only leads that became a job count. ROAS will therefore always be the higher of the two, and the gap between them is quoting that did not close. Both show — when no marketing spend is recorded, because a return over zero spend is unknown, not infinite.
One caution on ROI: $ Jobs is what the work sold for, not what has been invoiced or collected. A source can read above 1.00x on ROI while the cash has not arrived. For collected-dollar performance you still have to go to the invoices.
ROAS / ROI Replaced $/Job and $/Lead — 2026-08-20
The two cost-per-count columns were replaced with return multiples at Tim's direction. Cost per lead is no longer shown anywhere on this report. Nothing else in the table changed, and no underlying figure moved — ROAS and ROI are computed from the $ Quoted, $ Jobs and Spend columns already present.
Dollar Columns Added — 2026-08-17
Quoted and Jobs were renamed # Quoted and # Jobs, and a dollar column was added beside each. Nothing about the counts changed — the two new columns are additive, and every existing figure on the report is identical to what it was before.
The point is that count and value tell different stories about a channel. July 2026: Customer Referral produced 7 quotes worth $51,420 from just 8 leads, while Unattributed produced 16 quotes worth $39,872 from 41. Twice the quote count, less total value. A channel that reliably produces small jobs and one that occasionally produces large ones look identical in a count column.
One caveat on $ Jobs. Because it falls back to the originating quote when Jobber hasn't set a job total yet, it reflects what the work was sold for rather than what has actually been billed. For a month where most jobs are complete the two are close; for the current month they can differ meaningfully. If billed or collected value is what's wanted, that is a different column and would need the invoice tables.
Column Change — 2026-08-14
The column previously labelled Leads is now called Contacts, because that is what it always was — every contact, unfiltered. A true Leads column has been added beside it; that figure was always calculated but was never shown, which caused repeated confusion when comparing this report to agency reporting.
The Revised column has been removed, and Converted / Quoted / Jobs are now measured against Leads rather than against Revised. Revised applied a 30-day cross-source duplicate check that discarded genuine leads before the funnel was measured, which understated every downstream stage. As a result historical months now read higher than they used to — for July 2026, SEO jobs move from 5 to 10. Nothing changed in the business; the base of the calculation changed. The Funnel / Independent toggle has also been retired: there is now one set of numbers per row.
Funnel vs. Independent Mode
Funnel mode (default) — each stage is a strict subset of the one before it: Revised → Converted → Quoted → Jobs. A contact can only be Quoted if it was already counted as Converted, and can only count as a Job if it was already Quoted — the "true funnel," but it can under-count stages if a step gets skipped in practice (e.g. a job books without a formal quote).
Independent mode — each stage is checked separately against that source's full Revised lead set for the period, with no subset requirement. A contact can show up as Quoted without ever being marked Converted (say, the assessment step was skipped but a quote still went out). Use this to see real stage-level activity without the strict funnel ordering hiding it.
Only Converted, Quoted, Jobs, and their percentages change between modes — Leads and Revised are identical either way.
Where Each Source's Data Comes From
| Source | How It's Obtained |
|---|---|
| SEO | Calls to the dedicated SEO tracking number, plus every CallRail web-form submission on the site regardless of its real traffic source (standing design decision). Only counts if corroborated by CallRail — an uncorroborated manual "seo" tag falls to Unattributed (changed 2026-07-31). Split into SEO — Calls, SEO — Web Forms and SEO — Lead Capture since 2026-08-14, with a SEO — Total row summing the three. |
| SEO — Lead Capture | A Jobber lead-source value ("LeadCapture") that first appeared 2026-06-29. Arrives through the same Handyman Connection website integration as SEO web-form leads, and ChoiceLocal counts these as plain website form leads. Shown as a channel row under SEO since 2026-08-14, and included in SEO — Total. See "Lead Capture Rolls Into SEO" below. |
| Google LSA | Calls only, to the dedicated Google LSA tracking number. |
| Google PPC | Calls to the dedicated PPC tracking number, plus ChoiceLocal-emailed leads that match a Jobber client. Only counts if corroborated by CallRail or ChoiceLocal — an uncorroborated manual "ppc" tag falls to Unattributed (changed 2026-07-31). |
Brevo email-marketing campaigns. Identified by CallRail's medium = email or a Brevo source on the call or form, so it captures both people who call after a campaign and people who submit a form from one. Added 2026-08-14, once CallRail's source field started syncing — before that, email-driven calls were invisible and sat inside SEO. Not the same thing as ChoiceLocal (below), despite both arriving by email. | |
| ChoiceLocal not a row on the report | "New ChoiceLocal Lead" notification emails from the agency running our PPC landing pages, matched to a Jobber client by phone/email. This is a corroborating feed, not a lead source — it has never produced a row of its own. Every one of these leads is tagged PPC and lands in the Google PPC row (19 emails to date, 100% PPC). It exists so that a PPC lead with no CallRail call can still be recognised as PPC instead of falling to Unattributed. Added 2026-07-31. Do not confuse with the Email source above — that one is Brevo marketing campaigns and is unrelated. |
| Valpak | Not from Jobber — Valpak routes calls to its own tracking number and logs them in its Advisor portal, scraped nightly. |
| Angi | Native Jobber integration — Angi leads flow straight into Jobber as a Request automatically; Jobber itself sets the source. No manual tagging. |
| HC Integration | Auto-tagged whenever a lead arrives through the corporate website / online-booking integration — system-applied, doesn't even appear in Jobber's manual dropdown. |
| Thumbtack | Native Jobber integration, same pattern as Angi. |
| Customer Referral, Repeat Customer, Referral Partner, Social, 5 Star Rated, Vehicle Wrap | CSR-selected values from Jobber's lead-source dropdown, normalized via an alias lookup table. |
| Referpro | Native Jobber integration — Referpro leads flow straight into Jobber as a Request and Jobber itself sets the source. Unlike Angi/Thumbtack, every Referpro request counts as its own lead (not just the client's first) — a deliberate exception for Referpro's texting/repeat-contact model, where a repeat request is usually a genuinely new lead. From 2026-08-01 the Jobber request is the only source; before that date the lead-notification-email table (referpro_leads) also counted, and still does for those months. See "Referpro Email Feed Retired" below. |
| Home Depot | Manual Jobber tag, corroborated by a phone-match promotion against its own lead-notification-email table (proreferral_leads, parsed from Home Depot ProReferral emails) — though that table has no phone column, so in practice it can only ever be corroborated by an exact Jobber tag, not a phone match. |
| Networx, Project Quote | As of 2026-08-11: native Jobber integration, same pattern as Angi/Thumbtack — Jobber itself tags the request, and only the client's first request counts (no "every request counts" exception like Referpro). Before 2026-08-11: leads stay on the old dedicated-table + phone-match pattern (networx_leads / projectquote_leads) and always will — this is a hard cutover applied going forward, not a backfill, so historical totals for these sources don't change. The two paths can't double-count the same lead: a post-cutover lead that lands as a native Jobber request is automatically excluded from the old table's count via the same phone-match dedup. |
| eLocal | Wired up end-to-end (dedicated table, phone-match promotion) but typically near-zero or filtered-out volume in any given month, so it may not always appear. |
| Unattributed | The fallback — a blank Lead Source field, a raw value with no alias mapping, or (since 2026-07-31) an uncorroborated "ppc"/"seo" tag. Never silently dropped from the report. |
Corroboration Rule (SEO / PPC)
Changed 2026-07-31: a CSR's manual "ppc"/"seo" tag on a Jobber client is no longer trusted on its own. It only counts as ppc/seo if a real second source backs it up — CallRail (both) or a ChoiceLocal email (ppc only). Otherwise it's reclassified to Unattributed. This was a deliberate accuracy-over-volume tradeoff, confirmed with Tim after seeing it would move ~25 SEO leads/month to Unattributed.
SEO Is Split Into Channel Rows (2026-08-14)
SEO is shown as three channel rows plus a total, rather than one aggregate line:
- SEO — Calls — CallRail calls to the SEO tracking number, plus Jobber requests from clients with a blank lead source that a CallRail call matched by phone.
- SEO — Web Forms — CallRail web-form submissions, plus the same phone-matched Jobber requests where the match was a form. A customer with both a call and a form counts under Calls, the same tiebreak used everywhere else in this report.
- SEO — Lead Capture — the Jobber "LeadCapture" lead source, first seen 2026-06-29. It arrives through the same Handyman Connection website integration as SEO web-form leads, and ChoiceLocal counts these as plain website form leads.
- SEO — Total — the sum of the three.
Two reasons for the split. It makes the report directly comparable to ChoiceLocal, which reports SEO Call Leads and SEO Form Leads as separate figures. And the channels behave very differently — for July 2026, Calls produced 50 leads and 2 jobs while Lead Capture produced 7 leads and 3 jobs. That was invisible while everything sat in one SEO row.
How the numbers are produced. The sub-rows come from a companion database function that replicates the SEO portion of the main report's logic rather than editing it, so the main calculation is untouched. This gives a built-in check: the sub-rows must sum exactly to what the report computes for SEO overall. Verified against July 2026 — leads 81, revised 69, raw 141, and both Funnel and Independent mode all tie exactly. If they ever stop tying, the Total row is the one to trust and the breakdown is wrong.
Per-channel drill-down (fixed 2026-08-14). Clicking a Calls, Web Forms or Lead Capture row now opens only that channel's leads. SEO — Total still opens the full SEO list, which is the intended behaviour. Earlier in the day every SEO sub-row opened the full list, so the pop-up held more rows than the number clicked.
Lead Capture is grouped with SEO for display only — the underlying lead_capture bucket and the corroboration rule are unchanged in the database. That's deliberate: re-tagging these leads as "seo" in the data would put them under the corroboration rule, and 12 of the 13 have no CallRail or ChoiceLocal record, so they'd have landed in Unattributed — the opposite of the intent.
ChoiceLocal Reference Figures (2026-08-14)
Inside the ChoiceLocal box, some rows show a small blue CL <n> under the Leads figure. That is ChoiceLocal's own comparable number for that row. It is a reference only — it never replaces or adjusts our Leads count. Hover it for the counting rule, the delta against our figure, and where the number came from.
ChoiceLocal's methodology, in their own words. These are the definitions published on their own dashboard, transcribed verbatim on 2026-08-14. They are reproduced here so the two reports can be read against each other without guessing at what their numbers mean.
| Their metric | Their published definition |
|---|---|
| SEO Leads | Non-paid website form submissions + (unique SEO calls over 1 minute × Call Lead Percentage) |
| Paid Leads | Paid-source form submissions + (unique paid calls over 1 minute × Call Lead Percentage) |
| Investment | Ad spend + Management Fee. July 2026: $1,757.05 ad spend + $1,881.00 fee = $3,638.05. |
| Blended CPL | Investment ÷ total leads. July 2026: $25.09. This report no longer shows a cost-per-lead column (ROAS and ROI replaced $/Job and $/Lead on 2026-08-20), so there is nothing here to compare it against directly. If you need the comparison, note that their Investment includes the management fee and our Spend is media spend alone. |
| Revenue | Total leads × Avg Close Rate × Avg Client Value. This is modeled, not measured — see below. |
| Projected ROI | Revenue ÷ Investment. Inherits the modeled Revenue, so it is also a projection. |
The constants feeding those formulas, as configured on 2026-08-14: Call Lead Percentage 1.00 (so the multiplier does nothing — an SEO call lead is simply a unique caller over 60 seconds), Avg Close Rate 0.54, Avg Client Value $1,000.
Their Revenue figure is a model and must never be placed beside our Jobber revenue. July 2026 reads $78,300, which is exactly 145 leads × 0.54 × $1,000 — confirmed to the dollar, and their ROI of 21.52 is exactly 78,300 ÷ 3,638.05. It is a projection of what their lead volume would be worth under assumed close rates, not money the business collected. Only lead counts are meaningfully comparable between the two reports.
How they assign a call to a channel. Not by which tracking number was dialed — by CallRail's per-call source field, which reflects how the caller actually reached the site. In July 2026 that moved two calls placed to the PPC number into SEO, and moved 15 of the SEO number's calls out to brand-site, LSA, Brevo, Direct and Google Organic. Our report groups by the tracking number, which is why the two disagreed at channel level until we started syncing source on 2026-08-14.
Two things about their portal worth knowing before quoting it. Their closed-month figures restate — on 2026-08-14 the July SEO call tile read 45 at 2pm and 47 at 5pm, for a month that had closed two weeks earlier, so any ChoiceLocal number needs a date and a time attached. And their KPI tiles lag their own underlying call grid: for July the tile said 47 while their grid said 49, and the 49 phone numbers in that grid are an exact set match with CallRail. When the two disagree, the grid is right and the tile is stale — that is why the badge on this report is computed from CallRail rather than transcribed from their tile.
Why we don't just adopt their rule. Applying their over-one-minute filter here would discard real business: in July 2026 the SEO calls under 60 seconds were 20 calls from 17 distinct callers, of which 3 produced an assessment, 4 produced a quote, and 2 became actual jobs. Their rule is a reasonable agency-side quality filter — it protects them from being judged on wrong numbers and hang-ups — but it is not a lead definition this business should run on. So both numbers are shown, side by side.
Two kinds of reference, and the difference matters.
- Computed (solid blue) — SEO — Calls. Since 2026-08-14 we sync CallRail's source field, which carries ChoiceLocal's own tracking-source label. Applying their rule to it reproduces their published call grid exactly: July 2026 gives 49 against their grid's 49, an exact match on the phone numbers themselves. This updates itself every month with no manual step.
- Published (grey, dashed underline) — SEO — Web Forms. ChoiceLocal counts form submissions from their own website tracking, which we do not receive, so this one cannot be computed. It is stored as a value transcribed from their portal, with the date it was read. Months where nobody has read their portal simply show no badge rather than a guess.
There is deliberately no combined "ChoiceLocal SEO total." Their dashboard has four separate lead tiles plus a Total Leads tile — no single SEO figure exists anywhere in it. Adding their call tile to their form tile produces a number that exists nowhere in their reporting, that moves whenever either tile restates, and that is built on the stale side of the tile/grid split described above. Any such total is derived arithmetic, and anyone quoting one should say so.
What the July 2026 comparison actually shows. SEO — Calls is the first channel where the two reports agree at channel level (ours 50, theirs 49). The whole remaining gap is on the web side: our Web Forms and Lead Capture against their form-lead figure. Their form leads come from their own website tracking feed, which HCAA does not receive — so this is a website-tracking gap, not a counting-rule disagreement, and it is the thing worth chasing. Note also that their feed counts submissions we would not: a July 2026 spot-check found a ChoiceLocal staff test submission counted as a real lead in their totals.
Referpro Email Feed Retired — 2026-08-01
Referpro used to reach this report two ways at once: the native Jobber integration created the Request, and Referpro sent a notification email that was parsed into its own table. Every lead therefore landed twice, which is why Referpro's Contacts figure ran to roughly double its Leads figure — July 2026 showed 57 Contacts against 31 Leads, and 26 of those 57 were simply the second copy of a lead already counted.
From 2026-08-01 the Jobber request is the only source. The notification-email table no longer produces Referpro leads or contacts. This costs nothing: native tagging took over in the week of 2026-07-13, and from that week onward the email feed recovered exactly zero leads that Jobber had not already tagged. Referpro appears to have stopped sending the emails in any case — the last one arrived 2026-08-04 while Jobber requests continued.
This is a hard cutover, not a backfill — the same approach used for Networx and Project Quote on 2026-08-11. Months before August 2026 keep the old behaviour and their figures never change. That matters: May and June 2026 had no Jobber-tagged Referpro requests at all, so those months came entirely from the email feed and would collapse to nothing if the change were applied retroactively.
Going forward, Referpro's Contacts should sit at or just above its Leads rather than at roughly double, and the two columns should finally tell the same story.
Uncorroborated SEO / PPC Tags — Review Link
Added 2026-08-14. The amber link above the table shows how many Jobber leads in the selected month were tagged PPC or SEO with nothing to back the tag up, and lists them with a direct link into each Jobber client. These leads are counted as Unattributed in the table — the link exists so that reclassification is visible instead of silent, since the count runs to dozens in some months. Nothing is changed automatically; correcting one means fixing the tag in Jobber or confirming the real channel.
Known Gap — Home Depot Volume
Updated 2026-08-20. Home Depot conversions are now measured. Until migration 066 the report could not show them at all: v_leads hardcoded the Jobber client link to NULL for the Pro Referral branch, so every Home Depot lead was filtered out of the funnel before it could be counted, and Converted / Quoted / Jobs rendered as a dash. That link is now populated and the funnel is computed like any other source. Read these figures as a floor, not a total. A Home Depot lead only enters the funnel once it matches a Jobber client, and the match is on customer name alone, because a Pro Referral notification email carries only name, ZIP and job type — no phone number and no address. Match rates by month run 24 of 38 (May), 19 of 51 (June), 1 of 39 (July) and 2 of 6 (August), so actual performance is at least what is shown here and likely better. The durable fix is real contact data from Pro Referral rather than the notification email; that request is open with the vendor.
Fixed 2026-08-11 — Referpro Client-Sync Gap
Referpro requests were syncing into Jobber correctly (properly tagged, visible in Jobber itself), but a gap in the separate client-record sync meant some of those requests' client records were silently never written to this report's database — so a correctly-tagged Referpro lead could still be invisible to every report here. This wasn't a data-entry problem; it looked like one at first (a live comparison against Jobber briefly pointed at "leads never entered"), but tracing the exact request IDs showed the requests existed and were tagged, just missing their linked client row. August's Referpro count was undercounted as a result (3 shown vs. 8 actual). Fixed by adding a reconciliation pass to the daily Jobber sync that fetches any request's client directly by ID if it's ever missing, plus a one-time backfill of the existing gap. This closes the gap going forward automatically on every sync — no manual step needed — though the underlying reason the client-only sync occasionally misses a record in the first place is still unconfirmed.
Networx & Project Quote — Native Integration Cutover (2026-08-11)
Networx and Project Quote became Jobber-integrated the same way Angi and Thumbtack already are, effective today. Leads dated 2026-08-11 or later that arrive as a natively-tagged Jobber request now count via the standard Jobber branch above instead of only through the networx_leads / projectquote_leads staging tables. Everything dated before 2026-08-11 is untouched — this is a forward-only cutover, not a reclassification of history, so past totals for these two sources won't change.
One-Time Historical Backfill (2026-08-01)
For clients this report was showing as Unattributed, any phone match found in the old, now-superseded Dispatch database (pre-Jobber system) with a real source on file was written in as a manual correction — a one-time pass, not an ongoing sync. Every match in a source category prone to over-eager reclassification (LSA, Home Depot, Referpro, eLocal, Networx, Valpak, Project Quote) was only applied if independently corroborated by that source's own live data, to avoid the correction accidentally making a real lead disappear from the report. All-time Unattributed dropped from 598 to 379 as a result.
Common Uses
Tracking which marketing channels actually produce leads and jobs, not just raw contact volume · Spotting a sudden drop/spike in a specific source · Sanity-checking CSR lead-source tagging accuracy via the Potential Mismatched Lead Sources link above.
ℹ️ How this report works
What it shows
For each lead source and period: how many people contacted us (Contacts), how many were new-work leads (Leads), and how many of those leads got an assessment, a quote and a job, with the dollars and the return on marketing spend.
The people are counted the same way as Yesterday’s Intake. The full method is below, so you don’t need to open that report.
Intake day
People are counted per intake day: one business day, 12:00 am to 11:59 pm Eastern. Weekends and office holidays are added to the business day before them, so Friday, Saturday and Sunday are one intake day. Someone who calls three times on one intake day is one contact; someone who calls Monday and again Thursday is one contact on each day. An intake day counts in the month it starts in, so a Friday–Sunday intake day counts in Friday’s month.
Contacts
Everyone who reached us in the period: one per person per intake day, credited to the same lead source as their lead would be. A person comes from any of these:
- an inbound phone call to any office line (Clarity), grouped by the caller’s number;
- a lead record: a CallRail tracking-line call or web form, a ChoiceLocal lead, a Valpak call, a Home Depot Pro Referral email, a ReferPro, Project Quote, Networx or eLocal lead, or a lead-source email;
- a Jobber request created that day: online booking, Angi, Thumbtack, ReferPro, the AI agent, or one the office typed in from a text, an email or a craftsman.
Calls from craftsmen, staff, preferred vendors and our own lines are removed first, by phone number. A text, an email or a GlassHouse reply on its own does not create a contact. Contacts is always at least Leads on every row.
From Contacts to Leads
Each person gets one result. The results are checked in this order, and the first one that applies wins.
| # | Result | What decides it | Lead? |
|---|---|---|---|
| 1 | Same household | Another person on this intake day is the same Jobber client. | No |
| 2 | Legit decline | The call shows we couldn’t take the work: out of area, a trade we don’t offer, or no craftsman available. | No |
| 3 | Captured | A Jobber request was made for this person, and this is the first day they reached us about it. | Yes |
| 4 | Call-back (same request) | No new request. Their one request was entered in Jobber on this day, but they first reached us on an earlier day within the 30 days before the request. That earlier day already counted the request as Captured (row 3), so this contact isn’t counted again. | No |
| 5 | Existing job | The call is about an appointment, estimate or complaint we already have, or Jobber shows open work and the call isn’t about new work. | No |
| 6 | Not a lead | Wrong number, vendor or partner, sales call, or other. | No |
| 7 | Call-back (recent contact) | No new request, they already reached us in the last 30 days (a call, a request or a tracked line), and this contact is about the same job as that earlier contact, or the call has no transcript to classify. When the call is about new work, Claude reads it and compares it with what they contacted us about before (their recent request, or their earlier call). Same job: a call-back, not counted. A different job: not a call-back. It goes on to Open or Not captured and counts as a lead. | No |
| 8 | Couldn’t tell | A missed or under-20-second call with no transcript, no lead record and no Jobber client. | No |
| 9 | Open | We called, texted, emailed or messaged them through Jobber, but there is no request yet. | Yes |
| 10 | Not captured | New work with no request and no follow-up. | Yes |
Example for 3 and 4: a customer calls Monday, and the office creates the request Wednesday. Monday is Captured: the request counts on the day they first reached us, not the day it was typed into Jobber. If they also call Wednesday about that same job, no new request is made, and Wednesday is a Call-back (same request). The one request is counted once, on Monday. If Monday’s call had been more than 30 days before the request, the request would count on Wednesday instead. A call after Wednesday about the same job is a Call-back (recent contact), or Existing job when the call is about the scheduled work. “First reached us” looks back up to 30 days before the request was made, and only to contacts about the same job: if Monday’s call had been about something else (say, rescheduling an old appointment), the request counts on Wednesday instead.
Leads = Captured + Open + Not captured. New, returning and repeat customers all count. Results 2, 5 and 6 come from the call transcript, which exists for calls from July 1, 2026 on. June 2026 has no transcripts, so its Contacts − Leads gap is mostly Call-back rather than Existing job or Not a lead, and isn’t comparable with later months. A separate new request within 30 days of an earlier one is add-on work and counts as a new lead.
One exception: ActioNet leads come from the networking log (people the networking team recorded), not from the steps above, because many of them never call the office.
Home Depot Pro Referral
- Every Pro Referral “New Job Request!” email is one contact and one lead, dated the day the email arrived. If the same person is emailed again within 7 days, it counts once.
- The email has no phone number, so it is matched to a Jobber request created from 2 days before to 30 days after it: by the Jobber client Pro Referral linked, by first and last name, or, when the name differs, by the same job type and ZIP code within a few days.
- If a request matched, Converted, Quoted and Jobs follow that request. If not, it is a lead that didn’t convert.
- A later call about the same referral or request is a call-back, not a second contact.
- A Jobber request marked “Home Depot” with no referral email is not a Home Depot lead. It is someone who came back another way, and their lead source is decided by the rules below.
Lead source
Checked in this order; the first rule that answers wins:
- a tracked record for the person that day or in the 30 days before: a CallRail tracking line or web form (SEO, PPC, LSA, email campaign), a ChoiceLocal lead or a Valpak call;
- the BRAG / ActioNet networking log, matched by the client’s name;
- a Jobber integration created the request: HC website online booking, Angi, Thumbtack or ReferPro;
- a Home Depot Pro Referral email matched to the person (above);
- a SendJim postcard in the 60 days before, or a reply to a GlassHouse text;
- the office’s “how did you hear about us” answer in Jobber: the lead source on a new client, or on a returning client only if it was changed on or after this contact;
- Repeat Customers: a repeat customer (see Customer status) that none of the rules above matched, or anyone whose only source is the client’s Existing Customer Lead Source field in Jobber (Oct 28, 2026: that field alone no longer credits the source it names);
- Returning prospect, source unknown: a returning prospect (see Customer status) that none of the rules above matched. They contacted us before but never bought; what first brought them in is usually from before our records (intake history starts Jun 1, 2026; Dispatch has no lead source);
- Not asked: anyone else, meaning people new to us whose source nobody recorded. This is a coaching row, not a source.
Repeat customers are checked against every tracked source first. A repeat customer who called a CallRail line or was on a SendJim list is credited to that source. AI Booking is a way in, not a source. “Unattributed” is not used.
Customer status
- Repeat customer: before the day they contacted us, a completed Jobber job or a Jobber payment, or a paid Dispatch purchase or a completed Dispatch work visit (Dispatch back to March 2023). A job created the same day doesn’t count.
- Returning prospect: known to us before (a Jobber client, request or call, or their phone or email in our Dispatch records) but never bought.
- New: neither.
People are matched to Jobber by phone number — any phone on the Jobber client (Main, Mobile, Work…), not only the primary one — then by first and last name; Dispatch history is matched by phone or email.
The other columns
- Converted: a Lead whose counted request has an on-site assessment. Quoted: quotes made from that request. Jobs: jobs converted from those quotes. Each is a subset of the one before.
- $ Quoted: the total of those quotes, any status. $ Jobs: what the work sold for. That is the job total, or the quote total until Jobber sets the job total. It is not what has been invoiced or collected.
- Spend: marketing spend from QuickBooks, prorated by day. Networking uses its dated payments. LeadCapture spend sits on SEO.
- Conv % = Converted ÷ Leads · Slippage % = (Converted − Quoted) ÷ Converted · Success % = Jobs ÷ Quoted · ROAS = $ Quoted ÷ Spend · ROI = $ Jobs ÷ Spend. ROAS and ROI show “—” when no spend is recorded.
- ChoiceLocal group: SEO, PPC, LSA and Email sit in the outlined box. SEO is split into Calls (CallRail SEO line), Web Forms (CallRail forms), Lead Capture (Jobber LeadCapture) and Office’s answer (no CallRail record; the office recorded Website, Google or Chatbot). The blue CL badges are ChoiceLocal’s own comparable numbers, for reference only. Their definitions: SEO Leads = non-paid form submissions + unique SEO calls over 1 minute; Paid Leads = paid form submissions + unique paid calls over 1 minute.
Data refreshes nightly at 5:50 am ET. Click any number in Leads to see the people behind it.
How this report works
- To put a request on this report: in Jobber, open the Request, and under Product / Service on the On-site Assessment add Winter Special 2026-2027, then Save.
- Matching is on the catalogue item, not the text — renaming the promo in Jobber will not empty this report.
- New entries appear after the next sync: overnight at 1:20 AM, plus Mon & Thu at 4:55 PM. Press Run Now to pull everything immediately (about 45 seconds), or ↻ Update data on one row to refresh just that customer.
- Qualify and Contact Method are entered here by the office and save as soon as you change them. Everything else comes from Jobber and is read-only.
- Click the customer's name to open the Quote Builder: it reads the draft quote and works out the Final Quote.
- One-off quotes: when the customer didn't ask about the Winter Special but we are giving it anyway (usually labor over $5,000), press + Add one-off quote, find the quote by quote # or customer name, and add it. It joins this list marked One-off and opens in the same Quote Builder.
- Another quote for the same customer: press + Quote on that customer's row, find the quote in Jobber and add it. It gets its own row marked Added quote, with its own Quote Builder, Qualify and Contact Method.
- Remove from list: ✕ Remove takes a row off this list. Nothing changes in Jobber and saved Quote Builder versions are kept. Tick Show removed to see removed rows and ↺ Restore one.
- Only DRAFT quotes can be sent back to Jobber.
- Craftsman commission is based on the labor in the Draft Quote.
ℹ️ How This Report Works
What It Is
A breakdown of how quickly Jobber Requests move from creation → first on-site visit → sent quote, and how often they convert into paid jobs — sliced two ways: by the craftsman who ran the visit, and by the price tier of the quote. This report is scoped specifically to Requests and tracks the full funnel from a customer's first contact through to a completed job.
Data Sources
Jobber Requests, Assessments, Quotes, Jobs & Visits — synced nightly, then queried live from Supabase on every page load (not a static snapshot). Craftsman attribution uses the on-site assessment's assignee first; if no assessment was recorded, the earliest job visit's crew; if neither exists, the request's own assigned-to field.
Summary by Craftsman
One row per craftsman: Requests handled, Quoted count, Quote Rate, Jobs won, Success Ratio, and average business-day turnaround for Request→Visit and Visit→Quote.
Summary by Price Tier
The same metrics bucketed by the quote's dollar amount ($0–250 up to $5,000+), with a Craftsman filter to isolate one person's mix. Lost (29 Oct 2026) = quoted, no job, and not waiting on the customer; the columns after it split Lost by the quote's Lost Reason in Jobber: Can’t reach (Not able to contact), No longer interested, Another co. (Work done by another), Price, No CM / slot / not our work, and No reason (N/A in Jobber). Click a tier to see each request with its Lost reason. Why Quotes Were Lost, the next report down, has the full detail.
"Quoted" & Success Ratio
A request counts as Quoted if a quote was sent to the customer, or if a quote existed and still produced a job even though it skipped Jobber's formal "send" step (a real data quirk found 2026-07-29). Success Ratio = Jobs ÷ Quoted. Not a real loss (29 Oct 2026): a request whose quote was archived but whose work was won on another quote or job is left out of this report entirely — out of Quoted, Jobs and every Success Ratio — and counted only in the price-tier table’s Not a real loss column. In the drill-down, a Quoted date marked with an asterisk (*) means the quote was never formally sent — that date is when it converted directly to a job, not a real sent date; hover it for details.
Drill-Down & Sorting
Click any row to see the individual requests behind the numbers — the Request, Amount, and Job cells link directly to that record in Jobber. Click a column header to sort either table by that column.
Common Uses
Identifying craftsmen who are slow to visit or quote · Spotting where quote-to-job conversion drops off by price tier · Coaching conversations backed by real turnaround data · Sanity-checking the funnel behind the Sales & Lead Pipeline numbers above.
ℹ️ How This Report Works
What It Is
Every quote that was lost in 2026 — archived in Jobber with no job — and why. Pick a month it was archived and a craftsman at the top. The tiles, the reasons, the month table and the craftsman table all follow both pickers. Click any number, or a reason row, to list the quotes behind it.
Where the reason comes from
The Lost Reason field on the quote in Jobber, read by the Jobber sync (nightly at 1:45 am and on weekdays at 9, 12, 3 and 6). Source in the quote list says who set it: Office = picked by the office in Jobber; Filled in from records = set by the nightly review, which reads the quote’s notes, calls, texts, emails and follow-ups and writes a reason into Jobber only when the records state it plainly (high confidence); N/A in Jobber = nobody set one. No reason recorded counts the quotes still at N/A. What the records show is the record behind the reason, shown only where it matches the reason in Jobber.
Not a real loss
A quote that was archived but the same work was won anyway — booked on another quote or job, or replaced by a revised quote that went ahead (checked against the line items in Jobber). These are not counted as lost anywhere in this report, in My Scorecard’s Success rate, or in Request→Quote Turnaround; they are shown on their own so you can see them.
Left out
The quotes imported from Dispatch on May 5, 2026 that no craftsman is credited with.
Craftsman
The quote’s salesperson in Jobber when that person is a craftsman; otherwise the one non-Helper craftsman on the request’s on-site assessment (the same order as My Scorecard’s # Quotes). Quotes neither can credit show as “(not credited)”.
Columns
Lost = lost quotes (not counting not-a-real-loss). Can’t reach = Not able to contact; Another co. = Work done by another; No CM / slot / not our work = No Craftsman Available/Interested, Time slot not available and Work we don’t do together. $ is the quote total before tax. Archived is the date the quote was archived in Jobber, Eastern time.
ℹ️ How This Report Works
What It Is
A side-by-side view of the Payment line items recorded in Jobber's Billing section against the actual payments received at the bank — credit cards and ACH through Helcim, checks through QuickBooks. The goal is to confirm that every payment recorded in Jobber has a corresponding deposit at the bank, and vice versa.
Data Sources
Jobber — Payment records from each client's Billing section (not invoices), synced nightly at 3:30 AM. Helcim — credit card and ACH settlements fetched on refresh. QuickBooks Online — check deposits fetched on refresh. Rows are joined by customer name and dollar amount within the selected date window.
Date Range
Choose Yesterday, Week to Date, Last 7 Days, Month to Date, or a rolling 14–90 day window. Wider windows are useful for catching older invoices that were never paid or posted.
What to Look For
✓ Matched — invoice and payment align. Clean. 🔗 Manual — linked by you when auto-match wasn't possible. 💡 Potential — amount matches a source payment but names differ; confirm or dismiss. ⚠ Unverified — invoiced in Jobber but no matching payment found in Helcim or QuickBooks. May need to be collected or posted. ⚠ Source Only — payment received in Helcim or QuickBooks but no Jobber invoice exists. May be a cash job that was never entered.
Common Uses
Weekly reconciliation before bookkeeper review · Month-end close prep · Chasing outstanding invoices · Identifying jobs completed but never invoiced.
ℹ️ How This Report Works
What It Is
A chronological list of HCAA's outgoing business credit card expenses — charges the company makes on the CFCU MasterCards at vendors (materials, gas, subcontractors, supplies, etc.). This is not about customer payments; for customer receipts see the Payment Reconciliation section.
Data Sources
Primary — ORSA Credit Union email alerts (formerly CFCU): Transaction alert emails are auto-forwarded from hc2300@ → tfabrizio@ → leadsannarbor@ and synced nightly at 4:27 AM via Cowork scheduled task. These emails provide the craftsman name (which card was used) — data QuickBooks does not supply. Rows sourced from ORSA show a green ✉ badge in the By column.
Secondary — QuickBooks Online: CFCU MasterCard Purchase transactions synced nightly via GitHub Actions. QBO rows appear only when no matching ORSA email was found (fallback/reconciliation). QBO provides GL expense categories that ORSA emails do not.
Note on Customer Payment Sources
Customer credit card and ACH payments come from Helcim. Customer check payments come from QuickBooks. Both are reconciled together in the Payment Reconciliation section below.
Date Range
Choose Last 7, 14, or 30 days from the dropdown.
Columns
Date — transaction date. Payee / Location — vendor name (from ORSA email merchant field, or QuickBooks payee). Category — QuickBooks GL expense category when available (e.g., Vehicle Gas, Materials); blank for ORSA-only rows. Amount — charge total. Match — whether a corresponding Jobber expense entry was found. Jobber Title / ID / By — linked Jobber expense entry if matched; By shows the craftsman name from the ORSA email (✉) or the Jobber entered-by name for QBO-only rows.
Common Uses
Verifying craftsmen entered their material purchases in Jobber · Identifying which craftsman made a charge · Catching unrecognized charges · Month-end expense review.
| Completed | Job Title | Customer | Craftsman | Source | Salesperson | Zip | Sales | Labor | Expenses | Profit | Margin % | Labor Margin % | Open |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Load data using filters above | |||||||||||||
ℹ️ How This Report Works
What It Is
Every sale a salesperson has made, open or finished: the Request, its Quote and the Job it became. It is the record his sales commission will be worked out from once the commission scale is settled.
What counts as his sale
The switch from craftsman to salesperson is decided job by job, not by date. A sale is (1) a Request, Quote or Job tagged below as a Sale, or (2) automatically, any Request created on or after his start date that is assigned to him or has him as salesperson, plus a Quote with no Request or a Job with no Quote that he is salesperson on from that date. A Quote follows its Request and a Job follows its Quote. Untagged work from before the start date stays his craftsman work. A Craftsman tag keeps one item craftsman work; Jennifer Ellsworth (the whole client) is tagged Craftsman so her basement stays craftsman work until it is finished.
What it changes elsewhere
Sales work is left out of his craftsman credit: Open Work (it shows under the Salesperson drop-down instead), commission and Craftsmen Career Path sales, and the Scorecard / Craftsman Performance quote credit. A payment on a sales job shows in Commission as Sales job — crew to be assigned until a craftsman is put on its visits; a manual credit override still works. Payroll hours are not changed.
Columns
Quote = the newest quote on the Request (total incl. tax). Booked = approved date, or the converted date when a quote became a job without approval. Paid = invoice payments plus deposits taken within 14 days of the job, the same as Open Work. Margin = the Job Profitability rule (job revenue minus labor entries and job expenses, cash expenses excluded) and shows only once the job is finished. How = Tagged or Automatic.
ℹ️ How This Report Works
What It Is
How HCAA's phones are handled, using the names contact centers use: how many calls were offered, how many were answered, how long the conversations ran, how many callers hung up or went to voicemail, what calls the office made out, and when the phones ring. It combines the former Call Volume, How Long the Calls Ran and Craftsman Calls reports. All dates and times are America/Detroit.
Data Source
Clarity Voice call detail, taken from the Call History export in the Clarity management portal (portal.clarityvoice.com), pulled nightly and on Update. One row per call, with a start time, the caller, the number dialed, where it went, one duration and a missed flag. Inbound history starts 2024-07-01; outbound history starts 2026-07-01. Nothing earlier exists.
Which Calls Count
Inbound calls to any HCAA number. Calls that arrive from one of HCAA's own Clarity numbers are the phone system calling itself, not customers, and are left out of every figure (mostly (734) 259-6990, 3,387 calls from July 2024 to April 2026); the count left out is in the footnote under the Inbound table.
The Measures
Calls Offered: every inbound call that counts, answered or not. Calls Handled: offered calls picked up by a person or the AI receptionist. Answer Rate = Calls Handled ÷ Calls Offered. Not Answered = Calls Offered − Calls Handled, which is Abandoned Calls plus Calls to Voicemail. ("Missed" in contact-center tools means a call that rang a rep who didn't pick up, which is not what this counts, so it isn't used.)
Abandoned Calls: not answered and not sent to a mailbox; the caller hung up while it rang. Abandon Rate = Abandoned Calls ÷ Calls Offered, counting every abandoned call, including ones that rang only a second or two (Tim, 2026-10-20). Average Time to Abandon = total ring time of abandoned calls ÷ abandoned calls. Calls to Voicemail: not answered and logged to a mailbox (VMail (nnn)); Voicemail Rate = ÷ Calls Offered. Voicemail is kept apart from abandoned because the caller left a message.
Average Talk Time = total duration of handled calls ÷ Calls Handled. Clarity records one duration per call, so any time the caller spent on hold is inside it. Median Talk Time is the middle call, shown because a few long calls pull the average up. A handled call under 10 seconds is usually a pick-up-and-hang-up, a wrong number or a transfer, not a fast conversation.
Outbound Calls
Calls placed from HCAA extensions, leaving out calls to HCAA's own lines and internal numbers. Each is placed in the first group it fits, so the four add up: To Craftsmen (the number dialed is a craftsman cell on file); Returning a Missed Call (that number rang in within the previous 7 days, wasn't answered, and no answered call from it came since; time to return is from that missed call); Call-Back to a Recent Caller (that number had an answered inbound call in the previous 7 days); All Other Outbound. Missed Calls Returned: of the Not Answered calls in the period with caller ID, how many got an outbound call to that number within 7 days. Outbound length includes calls that reached the other person's voicemail; Clarity can't tell those apart.
Who Is Calling
Craftsmen: the caller ID matches a craftsman cell in the CM Locator profiles (a floor, since not every craftsman has a cell on file). Vendors: the caller ID matches a number in the Industry Contacts sheet (also a floor: the sheet holds mostly main business lines). Everyone else is New (the first call we have ever seen from that number) or Called Before (that number rang at least once before, across all history). No Caller ID: the caller withheld their number.
Calls by Hour & Day of Week
Calls Offered in the period by the hour the call started and the day of the week. Darker cells had more calls.
What This Data Can't Show
Clarity's export has no queue, hold, wrap-up or rep-status times. So Average Handle Time (talk + hold + after-call work), Service Level (e.g. 80% answered in 20 seconds), Average Speed of Answer, longest wait, hold time, after-call work, occupancy and transfer rate can't be measured, and none are shown.
Sources For The Names
Genesys Cloud metric definitions; Avaya CMS measures; Cisco Webex Contact Center call report parameters; Talkdesk (Abandon Rate; Missed vs abandoned); Zendesk Talk dashboard metrics; Call Centre Helper (Abandon Rate, Average Talk Time, AHT). Full list and links: the Call Metrics reorganization page of 2026-10-20 in claude_reports/.
Calls from craftsmen in the period: which HCAA number they rang, and the count per craftsman.
ℹ️ How This Report Works
What It Is
Every call the AI receptionist answered on (734) 926-4503, what it did with each one, and how far the bookings travelled in Jobber. Filterable by day, week or month.
Data Sources
Three, joined on call time: the Retell AI call log (volume, duration, sentiment, how the call ended), the outcome notifications from Manifest GTM (booked / message captured / needs follow-up / no action, and the Jobber request id on a booking), and Jobber for the request → quote → job funnel.
Why Bookings Are Not Counted From The Lead Source
A booking made against an existing Jobber client does not set the lead source, so HC Ann Arbor - AI Booking (Production) catches only about half of them. Bookings are therefore counted from the notification stream, which is complete.
Caller Types
Caller numbers are matched against phone_directory — the same table the Call Metrics report uses. Craftsman counts are a floor: only 25 of 30 craftsmen have a cell on file.
Status
Mockup on a fixed snapshot. The figures are real, read on 31 August 2026, but the nightly refresh is not built yet — the page does not update on its own.
ℹ️ How This Report Works
What It Is
What customers actually said when they rang, and what happened as a result. Every inbound customer call is recorded, transcribed, and sorted into an outcome — booked, estimate set, or lost, with the reason in the caller's own words. It exists to make visible the one thing no other report can see: the jobs that never reached Jobber because the call ended without an appointment. Those callers leave no trace anywhere else in the business.
How To Read It
There is one table that carries every call, and it adds up. Each row is an outcome; click it and it opens in place to show why those calls ended that way and which calls they were. The sub-totals inside a row always add back to the row above them.
Below that spine sits a second block — the same calls, cut a different way. What they wanted, speech difficulties, service recovery, the type of jobs they called about. Those cut across every outcome rather than sitting under one, so they are kept separate; each still totals the same number of calls. One exception is labelled where it appears: job types can be several per call.
Data Source
Clarity Voice call recordings, transcribed through Clarity's own transcription service into clarity_transcripts, then classified into clarity_call_insights. Transcripts are pulled nightly at 3:00 AM and classified at 3:35 AM, both America/Detroit. All times on this page are America/Detroit.
The Quality Sections (⭐)
The three sections marked ⭐ are the quality-observation program. Every inbound call with a transcript is read by Claude Haiku 4.5 with each line already marked Rep or Caller, and the review is saved per call (clarity_call_qa). New calls are reviewed overnight, after they are transcribed and labeled. CSR = who answered, from the Clarity extension the call rang (the AI receptionist has its own row); “Not matched” means the call couldn't be tied to an extension.
Customer Sentiment: the caller's sentiment over the call, positive, neutral or negative, with the phrases behind it, each marked Rep or Caller. Shown as a trend line since Jul 1, 2026, by week, month or quarter, for the CSRs you tick plus a company line for all calls; pick % Positive, % Neutral or % Negative. The word lists count the words that appear most often in those phrases. The Quality sections don't use the Period picker (it sits under Call Insights); Coaching By CSR and ServiceScore have their own Period dropdown. This is a separate read from the older Customer Sentiment section below, which judges only Clarity's short summary.
Booking The Assessment: an opportunity is a call where the caller wanted new work and the call was a chance to book the free on-site estimate (the review decides this from the transcript). Assessment in Jobber = the caller matches a Jobber client by phone (the client's main phone, or the intake's phone match that day) and that client has an on-site assessment on a request created from 1 day before to 30 days after the call. Every opportunity without one is placed once: booked on the call but no assessment in Jobber, a legitimate no (out of area, service not offered, no craftsman, declined after hearing the price or process, not ready yet), or a miss. A miss can have more than one reason, so the reason rows can add to more than the missed calls. “Call-back never happened” = the rep promised a call-back instead of booking and no assessment followed. The trend line plots the share of each period's opportunities in the bucket you pick. The Pareto chart ranks the reasons for missed opportunities, filtered by CSR and month: each bar is that reason's share of all reasons given, and the line is the running total.
Coaching By CSR: up to three specific points per call, each with what happened and what to say instead. When a caller pushed back on price or was comparing companies, the point names the Handyman Connection differentiator that would have helped (warranty, background-checked craftsmen, written estimates, dispatch updates, licensed and insured, fair pay for craftsmen).
These are AI reads of speech-to-text. Spot-check them against the recordings before using them in a review with a CSR. No targets or good/bad colouring are applied yet.
Which Calls Are Included
Inbound only, from numbers that are not a craftsman, an internal extension, or a preferred vendor — so customers and unknown callers. Minimum ten seconds. Voicemails are included (they have audio); abandoned calls are not (they have none). History starts 1 July 2026 — Tim's chosen floor, extended from 4 August on 5 September 2026 so that trends have something to stand on. Nothing earlier will be pulled: the floor is a deliberate guard, because the call-detail feed goes back to July 2024 and an unbounded backfill would be enormous.
How A Call Is Classified
Clarity's transcription service returns a full transcript and a short AI summary. The summary is then read by Claude Haiku, which assigns the outcome, the reason lost, the job types, the sentiment, who answered, any speech difficulty, and the service-recovery flag. The categories are a closed list enforced by the database — a label outside it is rejected rather than quietly added to the report, so the categories on this page cannot drift without a schema change. Every classification is auditable: click any call to read the summary and the full transcript it came from.
One Outcome Per Call — And One Total
Every call carries exactly one outcome. There is no hidden filter, no "noise" exclusion and no second denominator — the outcome rows add up to the headline number, and the Find A Call list at the bottom has the same row count. Where a rate is quoted it is quoted against new-work calls, because that is the only group where a sale was ever possible; cancellations, transfers and wrong numbers were never going to be won and are not used to flatter or depress a percentage.
Where The Summaries And Recommendations Come From
They are computed, not written. Each one is assembled in code from the figures on this page against fixed thresholds, so the same data always produces the same words and every sentence carries the count behind it. Nothing here is a language model's opinion. The thresholds are: a reason-lost group is called out when it is the largest and reaches 3+ calls; service recovery is flagged when any call is open; a CSR's booking rate is compared only when they handled 20+ calls; a spread between CSRs is called out at 15 percentage points; a speech issue is raised at 3% of calls; a period-over-period change is called real at 10 percentage points with 25+ calls on both sides.
Win Rate
On What The Caller Wanted, each row carries a Win rate: the row's Won count divided by the calls in that row, not by the period total. So the new-work row is measured against new-work callers, and a row like estimate follow-up is measured against its own callers — which is the only base that works everywhere, since those rows have no new-work count to divide by. A rate resting on fewer than 25 calls is shown grey; a percentage of nine calls is arithmetic, not a rate.
What "Won" Means — And What It Does Not
Won = the call ended with a visit in the diary. Exactly two outcomes count: Appointment Booked (a work visit was scheduled) and Estimate Scheduled (an estimate visit was scheduled). Nothing else does — a promised callback, information given, or confirming or moving an appointment that already existed are all not wins.
Three things it is not:
1. It is not a sale. No quote accepted, no job created, no money taken. It means somebody is going out.
2. It is not verified against Jobber. It is read from the call summary. The Call → Jobber section is the independent check, and it finds that roughly three quarters of won calls produce a Jobber Request within seven days — so about one in four leaves no trace in Jobber at all.
3. It is the sum of the two outcomes that may be one thing. On the evidence to date those two behave identically; if they are ever merged, Won does not change, because it is already their total.
“Callback Promised” — And Whether The Callback Was Made
Callback Promised is the single biggest outcome on the page: the caller was told somebody would ring them back. Until 5 September 2026 nothing in the business could say whether that happened, because the call log held inbound calls only. It now also holds outgoing calls and the text-message threads, so the question is answerable and the answer sits inside the Callback Promised row — open it.
How it is judged. A promise counts as followed up if, within seven days, there was an outgoing call to that number, a text thread with that number, an email from the office (ServiceAnnArbor) to the email address Jobber holds for that number, or a message Jobber sent that client (an email or text on the client's Communications tab; counted from Oct 20, 2026). All are matched on the number that rang in.
“Too soon to tell” is a separate answer from “nothing found”, and that distinction matters. A call from three days ago has not had seven days to be followed up, and the outgoing-call feed ends on a fixed date. Those calls are shown as too soon to tell and are excluded from every rate. Folding them into “nobody called them back” would report recent callers as neglected when nothing of the kind has been established.
Four limits, all of which push the figure DOWN, never up:
1. Only calls placed through the office phone system count. A CSR ringing from a mobile looks like no call at all.
2. The text side counts a thread whose most recent message falls in the window. A conversation that carried on for weeks afterwards has a later timestamp and is missed.
3. Matching is on the number that rang in. A customer reached on a different number is missed.
4. An unanswered outgoing call still counts as an attempt made.
So the follow-up rate on this page is a floor. The real figure is that or better — but the calls shown with nothing recorded are the ones worth chasing.
What it does not tell you is whether the promise was ever written down. Nothing in Jobber or anywhere else records that a callback was owed, so there is no list for anyone to work from and nothing to prompt the call. That is the gap this measurement exposes rather than closes.
Comparing With The Period Before
Every table carries a Prior column and a change in share. Prior is the same number of days immediately before the period you are looking at, fetched the same way and cut by the same code — so a comparison can never disagree with the table it sits in. The change is quoted in percentage points of share, not in calls, because the number of calls moves on its own and a bigger week would otherwise look like an improvement everywhere. If the previous window would run off the front of the record it is refused rather than approximated, and the report says so.
A change is only coloured when it clears 10 percentage points and both periods carried at least 25 calls. Anything smaller is shown in grey. That is not timidity: a week holds roughly 45 new-work calls, which carries a swing band near ±15 points with nothing at all having changed, so a coloured arrow on a 6-point move would be an invitation to chase noise.
⚠️ There Is No Speaker Separation
Clarity returns the call as a single merged stream of text — it does not tag who said what. So this report can tell you what a call was about and how it ended, but it cannot measure talk time, interruptions, or who spoke first. Any such metric would be invented, so none is shown.
Speech Difficulties (in Service Recovery)
This measures whether the two people on the call struggled to understand each other — a bad line, a strong accent, a caller who could not hear. It deliberately does not count transcription errors: the software mishears names and numbers constantly ("Handicap Connection", a $250 estimate rendered as "$2.50"), and that is a limitation of this report, not a problem on the call. Both are reported, separately.
Lost On The Phone
A call is lost when the caller wanted work done and left without an appointment or an estimate. Cancelling, moving or checking on an existing appointment is not lost — those have their own outcomes. A caller who cancels a booked project because they decided to do it themselves is lost, because the work was lost.
From The Call To A Sold Job
The old Call → Jobber section is now part of Quality: Booking The Assessment. Each opportunity is matched to a Jobber client by phone, then followed to a Request, an on-site assessment, a Quote and a Job created from 1 day before to 30 days after the call. The old section used a 7-day window. Customer Sentiment and By CSR were also retired here (Oct 19, 2026); the ⭐ sections read the full transcript and credit calls by the extension that answered, not the name heard.
Update
The nightly jobs keep this current. Update classifies anything transcribed but not yet analysed — useful straight after a manual Clarity refresh (the Update button on Call Metrics).
Complaints, warranty calls, no-shows and chased estimates — someone is waiting on a call back. A flag rather than an outcome, so these calls also appear under several rows of the outcomes table. Below them: calls where the two sides had trouble understanding each other (bad line, accent or language, hard of hearing, talking over).
⚠️ A call can involve more than one job type, so this is the one table on the page that does not total to the call count.
The searchable index of every call in the period, and the CSV export.
ℹ️ How This Report Works
What It Is
The Craftsman Locator rebuilt inside Reporting, for testing side by side with the current CM Locator. Same search, results, 30-day calendar, coverage maps and craftsman editor.
Data Source
Skills, zip codes, schedules and map pins are copied from the current CM Locator into Reporting every 15 minutes. Profile details come from Admin › Users. Calendar bookings are read live from Jobber.
While Testing
Only the 4 test records (Test Tim, Test Max, Max McGonegal (Dev), Max McGonegal (Test)) can be changed here. Make real changes in the current CM Locator until the switch-over. Plan: Craftsman Locator Migration Plan (Oct 30).
Direct link: /cm-locator-new
ℹ️ How This Report Works
What It Is
Everything craftsmen have sent from the 💬 Feedback button in the field app, newest first. It exists to catch the thing a craftsman notices at 7:40 on a driveway and has forgotten by the time anyone asks him.
Data Source
The app_feedback table in the Reporting database, written straight from the phone. The table is append-only — there is no way to edit or delete a row from the app or from this page, so what a craftsman sent is what you read.
What Each Row Carries
The craftsman, the screen he was on, the app version and the OS. The screen is what makes a one-line complaint actionable — "the refresh took ages" is noise; "the refresh took ages, Open Work · Requests" is a bug report.
Read and Unread
Read marks are per person, kept in a separate table so that marking something read never edits the feedback itself. Your unread count and Max's are independent.
Every submission emails Tim and Max the moment it lands. A digest of the week — grouped by screen and by craftsman, with anything raised more than once flagged — goes out Monday at 7:00 AM, and is sent even when the week was empty so that silence is confirmed rather than assumed.
Turning It Off
The button is temporary. It is gated on app_config.feedback_enabled — set that to false and the button disappears from every phone at once, with no App Store release. This report can then be removed from 🧪 Beta Reports.
ℹ️ How This Report Works
What It Is
A per-craftsman view of scheduled field time pulled directly from Jobber. It shows Do Work visits (active job appointments) and Estimate assessments for any selected date — use it to see who is scheduled, for how long, and on which jobs.
Data Source & Sync
Data is sourced from Jobber's scheduled visits and assessments (not timesheet entries) and synced nightly at 3:00 AM Eastern by a Supabase cloud job (jobber-sync-schedule). Each run re-reads every visit from 14 days back to 45 days ahead, and re-checks assessments scheduled in the next 36 hours against Jobber. The sync is the source of truth: any visit in that window that was cancelled or rescheduled in Jobber is removed from the database, so the dashboard reflects Jobber's current schedule — including changes made up to two weeks after the fact.
7-Day Navigation
Use the quick-select chips below the date picker to jump to today or any of the next 6 calendar days. You can also pick any date manually with the date picker. Click Refresh to reload the selected date.
Multi-Craftsman Rule
When a Do Work visit has more than one craftsman assigned, the first craftsman counts at 100% of the visit duration and each additional craftsman counts at 50%. For example, a 2-hour visit with 2 craftsmen = 2.0h for craftsman 1 + 1.0h for craftsman 2. This applies to both the detail table rows and the KPI hour totals.
KPI Cards
Total Hours — combined Do Work + Estimate hours for the day (applying the multi-craftsman rule). Do Work Hours — hours from scheduled job visits only. Estimate Hours — hours from assessment appointments only. # Estimates — count of distinct estimate appointments scheduled that day. Under Total Hours, available = each active craftsman's hours for today's weekday in the CM Locator scheduler, minus hours covered by Jobber tasks with no customer that are labeled time off or outside work (same rule as Craftsmen Performance), and % utilized = Total Hours ÷ available (staff utilization rate). Click that line for each craftsman's scheduled, time off, available and booked hours. The POD drop-down beside it (default All PODs) shows utilization for one POD only: that POD's craftsmen's available hours, and their booked hours — Do Work visits split first craftsman 100% / each additional 50%, and an estimate shared by two craftsmen counted in full for each. POD comes from the Craftsmen Career Path; unassigned appointments and craftsmen with no POD count under All only.
Detail Table
Do Work rows show one row per craftsman per visit, so a visit with two craftsmen appears as two rows. Estimate rows are merged into one row per appointment, with multiple craftsmen listed together. Columns show craftsman name, appointment type, customer, scheduled start and stop times, and calculated duration.
Twist Integration
Daily posts to Twist: This report is automatically posted to the Office Staff channel on Twist every weekday at 6:30 AM EDT. The post includes today's total scheduled hours, Do Work vs. Estimate breakdown, number of craftsmen working by POD, and a summary of all scheduled appointments with Jobber links.
Common Uses
Previewing tomorrow's crew schedule · Confirming field coverage for a given day · Spotting double-booked or unassigned visits · Cross-checking scheduled hours against invoiced work.
ℹ️ How This Report Works
What It Is
A live list of Jobber service requests — work orders that are open, scheduled, or in progress. It gives the office a single-screen view of what's on the board at any moment.
Data Source
Jobber. Requests sync automatically at 1:20 AM every day, again at 9 AM, 12 PM, 3 PM and 6 PM on weekdays, and once more at 4:55 PM on Mon/Thu just before the Twist post. The "Data as of" timestamp shows when the data in this table was last pulled from Jobber.
Click ↻ Refresh to pull straight from Jobber right now rather than waiting for the next scheduled sync. It takes about a minute, and the table reloads by itself when it finishes.
Filter Toggle
When the Filter is ON, four categories of requests are automatically hidden to keep the list focused on active work:
- 🗄 Archived — requests with a status of "Archived" in Jobber
- ✅ Converted — requests with a status of "Converted" in Jobber (a job has been created from the request)
- 🔧 Warranty — requests whose title contains the word "Warranty" (case-insensitive)
- 📍 No City/Street — requests with no service address on file
The legend above the table always shows how many records fall into each filtered category, even when the filter is ON. Turn the filter OFF to see all requests including the hidden ones.
Columns
Jobber Request — links directly to the request in Jobber. Date — the date the request was created in Jobber. Service City — city where the work is to be performed. Description — the request title from Jobber.
Common Uses
Morning board review · Spotting requests that are sitting open without being converted to a job · Confirming all active work is properly addressed.
Twist Integration
Twice-weekly posts to Twist: This report is automatically posted to the zCraftsmen channel on Twist on Monday and Thursday at 5 PM ET. The post includes the full work order list for that day, with Jobber links for each request.
Post to Twist button: owners, managers and office staff can push the list out immediately without waiting for the schedule. The button posts the same list, to the same channel, as a new thread.
Duplicate posts are blocked. Every post records a fingerprint of exactly what was sent. If the list is identical to what was posted last time — nothing added, closed, or re-titled since — the post is skipped and you'll be told when the current version was last posted. This applies to the scheduled Mon/Thu post as well as the button, so craftsmen never get the same list twice. Hit ↻ Refresh first if you want to be sure you're working from the latest Jobber data.
ℹ️ How This Report Works
What It Is
A per-craftsman view of all open work pulled directly from Jobber — showing Open Requests, Open Quotes, Open Jobs, and Open Tasks for the selected craftsman. Use it to quickly see what's on someone's plate without logging into Jobber.
Data Source
Jobber, synced nightly via GitHub Actions. Data reflects the previous night's sync; click the Jobber link on any row to view the live record.
Open Requests
Service requests that belong to the craftsman and have not been archived or converted to a quote or job. A request belongs to its salesperson in Jobber when that is a craftsman (office staff are skipped), otherwise to the craftsman it is assigned to. Columns show the client name, description, current status (e.g., Upcoming, Assessment), date created, the scheduled assessment date/time (if one has been booked), Days since that scheduled date (today minus the scheduled date, in calendar days; a dash if nothing is booked or the date is still ahead — 3–4 yellow, 5+ red), whether an assessment has been completed, and a direct link to the request in Jobber.
Open Quotes
Jobber quotes for this craftsman (the quote's salesperson in Jobber; if a quote has none, the craftsman assigned to its request) that are not yet a job: Draft (not sent yet), Awaiting approval (sent, customer hasn't answered), Changes requested (customer asked for changes), and Approved, not yet a job (customer said yes, no job created yet). Once a quote becomes a job it moves to Open Jobs. Days counts calendar days from the date that matters for its status: created for a draft, sent for awaiting approval, the date changes were requested, or the date it was approved. Longest-waiting quotes are listed first. Quotes deleted in Jobber drop off after the nightly sync.
Open Jobs
Active jobs that belong to the craftsman. Each job shows under one craftsman, the first match in this order: (1) the craftsman on the job's next upcoming visit, or, if none is booked, its first visit (a helper alone on a visit counts for the craftsman he works with, e.g. Kendan Sipes → Scott Salo; if two craftsmen share that visit, the job salesperson decides); (2) the job's salesperson in Jobber; (3) the quote's salesperson; (4) the request's salesperson; (5) the craftsman the request was assigned to; (6) whoever logged the most labor on the job. Office staff and helpers are never the owner. Jobs that match nobody don't appear on any list. Columns show job number, client, title, status, date created, next scheduled visit, and a direct link to the job in Jobber.
Open Tasks
Tasks assigned to the craftsman in Jobber that are not yet marked complete. Columns show the linked client, task title, status (Open or Overdue based on scheduled date), and the scheduled date and time. Tasks are synced nightly at 4:30 AM EDT.
Salesperson
The Salesperson drop-down lists people who sell rather than do the work (Brandon Tracy from Oct 23 2026). Picking him there shows his sales work: Requests, Quotes and Jobs tagged as his sales (Kathleen Forhan, Jon Hoffman, Tonya Jaiswal) plus every Request assigned to him or with him as salesperson from Oct 23 2026 on. That work is left out of his name in the Craftsman drop-down, and the crew on a sales job is “to be assigned” until a craftsman is put on its visits. His craftsman work (Jennifer Ellsworth’s basement, and anything from before Oct 23 that isn’t tagged) stays under his name in the Craftsman drop-down. Tasks always stay in the Craftsman view. Tags are managed on Sales & Financials → Salesperson Sales.
How to Use
Select a craftsman from the dropdown above. All four tables load automatically. "Overdue" tasks are those whose scheduled date has already passed.
ℹ️ How this report works
What it is
The Progress Payment Calculator tracks what is owed to the Lead Craftsman on each Jobber job. It pulls revenue line items and timesheet labor from Jobber nightly and lets you calculate commission after accounting for sales overhead, project management, and helper payments.
Lead Craftsman
If only one craftsman logged paid hours on a job, they are automatically assigned as Lead. If two or more craftsmen have pay, you select the Lead manually — your selection is saved and never overwritten by the nightly sync.
Line Items (Revenue)
Synced nightly from Jobber. Labor lines and material lines are tracked separately — only labor is commissionable. You can add or edit lines manually; manual edits are preserved across syncs.
Helper Payments
Craftsmen who worked the job but are not the Lead. On first open, these are auto-populated from Jobber timesheet entries. Helper costs reduce the Lead's commission through the Commission Decrease calculation.
Payments Already Made
Prior payments to the Lead Craftsman on this job (e.g. draw, advance). These are subtracted at the end to show what remains to be paid.
Sync schedule
Jobs and timesheet data sync nightly at 3:30 AM from Jobber via GitHub Actions. New jobs from the past 2 days are added; all open jobs are refreshed.
💡 Helper & Progress Payments
Helper Pay
- Helper Pay is generally set at $30 per hour, though the final rate is determined by the lead Craftsman based on what they are willing to pay.
- For W2 helpers — payroll taxes, unemployment insurance, and workers' compensation premiums are factored into the total cost, which reduces the lead Craftsman's commission accordingly.
- Cost Split: 67% of Helper Pay is covered by the lead Craftsman (via decreased commission), and 33% is covered by the company.
Progress Payments
- Deposits: Progress payments will not be issued before a job has physically started, even if a customer deposit has been received. We issue 100% refunds for any jobs that have not yet started.
- To receive a progress payment, the Craftsman must request one. Required — a note on the Job (in Jobber) indicating the percent complete otherwise we will not know how far along the job is. Our contract specifies for jobs over $5,000 we will collect on the labor at 40% (down payment), 60%, 80%, and 100% completion.
- Once a progress payment is requested by the Craftsman, the office contacts the customer to request payment in alignment with the percent the job is complete.
- If payment is received, the amount is entered into the Progress Payment Calculator. Progress payments are only issued when the customer agrees with the reported progress and makes the payment.
Progress Payment Calculator
- The calculator was established several years ago and remains unchanged.
- Factors included: Customer payments received, Helper Pay, Material expenses incurred, Percentage of work completed, Customer sentiment / feedback / resolution.
| Product / Service | Type | Amount |
|---|
| Date | Name | Amount | Type |
|---|
| Date | Craftsman | Amount |
|---|
| Date | Method / Type | Amount | |
|---|---|---|---|
| Loading… | |||
| Date | Item | Amount |
|---|---|---|
| Loading… | ||
Lead Craftsman: Auto-assigned when only one craftsman has paid timesheet hours. When two or more craftsmen have pay, you select manually — your selection is never overwritten by the sync.
ℹ️ How This Report Works
What It Is
A per-craftsman performance grid that ties each craftsman's earnings goal to the estimates, sale rate, and field hours needed to hit it. Pick one craftsman or All craftsmen from the Craftsman drop-down, and click any column header to sort. The columns from # through Last 3 Pay Periods — Earnings stay frozen on the left when you scroll sideways.
Craftsman & Goal
Name — the active roster from the Craftsmen Career Path Tracker. FT/PT — manual entry. 2026 Avg/PP — the craftsman's actual 2026 gross pay ÷ the pay periods he was paid, from the Payroll Coding runs (Envision). A special (off-cycle) run adds to the pay but not to the period count — the same figure as the 2026 Gross Pay by Craftsman popup. Earnings/Pay Period (the goal) uses the 2026 Avg/PP automatically (blue cell) unless a manual goal is typed in (amber cell). Clear a manual goal to go back to the automatic one. FT/PT and the goal are editable inline — click the cell.
Last 3 Pay Periods
Actual gross pay for the three most recently completed 14-day pay periods (cycles start 2026-05-13, America/Detroit), from the Payroll Coding runs (Envision) — the same source as 2026 Gross Pay by Craftsman. Each column is everything paid for that pay period: the regular run plus any special (off-cycle) run. Envision's pay period numbers line up with these cycles (May 13–26 = Pay Period 11). A column shows "—" until that pay period's payroll has been uploaded in Payroll Coding, and $0 when it has been uploaded but the craftsman was not paid.
Inputs
The Inputs and Requirements sections start collapsed to keep the table narrow. Click ► under INPUTS or REQS to expand that section, and ◄ Hide to collapse it again.
Comm % — from Craftsmen Career Path. AJS (Disp) and SR% (Disp) are provided Dispatch-era data. AJS Closed and SR% are pulled from Jobber for each craftsman since June 1, 2026. AJS Closed uses the RAAG Franchisor (v2) definition: $ Closed ÷ # Closed, where # Closed is jobs by completed date and $ Closed is the invoice subtotal on those jobs. SR% uses the Request → Quote Turnaround report's Success Ratio, so the two reports always agree: of the requests created since June 1 that were quoted (a sent quote, or an unsent quote that became a job), the share that became a job (any status); a request whose quote was not a real loss (the same work won on another quote or job) is left out, as in that report. Requests are credited the same way as in that report: the first non-Helper craftsman on the earliest assessment, else on the first job visit, else the request's assignee. (Until Sep 24, 2026 SR% used RAAG's approved-quotes rule, which undercounted because many jobs were converted in Jobber without the quote being marked approved.) Both show 0 when there's nothing to divide by. Jobs are credited the same way as the Craftsmen Career Path Tracker's sales credit, checked in this order: a manual override, when every payment on the job is overridden to one craftsman; the first non-Helper craftsman on the job's earliest visit; the non-Helper assessor on its request; the craftsman on the job's earliest labor entry. For # Quotes and $ Booked, a quote goes to the non-Helper craftsman who did the assessment on its request; quotes with no request or assessment aren't credited to anyone. Hover a cell to see the counts behind it. AJS Target, SR% Target, and Hourly Rate are editable inline.
Requirements (calculated)
$Booked (Labor) = Goal ÷ Comm %. #Completed = $Booked ÷ AJS Target. # Quotes (quotes needed per pay period) = #Completed ÷ SR% Target. A requirement shows "—" when an input it needs is blank — # Quotes needs both AJS Target and SR% Target to be entered. Work Hrs/PP = Goal ÷ Hourly Rate.
Results
# Quotes — one column for each of the same three pay periods as Last 3 Pay Periods — Earnings. Each counts the craftsman's non-draft quotes created in Jobber during that 14-day period (RAAG Franchisor # Quotes, America/Detroit), credited to the craftsman who did the assessment, same as SR%. Compare each period to # Quotes under Requirements, which is a per-pay-period target. $Booked — one column for each of the same three pay periods: labor only — the craftsman's quotes approved in Jobber during that period (by approved date, America/Detroit), each quote's subtotal minus its materials (the quote's Product line items), credited the same way as # Quotes. Quote line items come from Jobber nightly at 2:35 AM ET. Compare each period to $Booked (Labor) under Requirements.
Color coding
Green = at or above target, red = below target. No color = there is no target to compare against.
Last 3 Pay Periods — Earnings: each period against the craftsman's Earnings/PP goal (manual goal if entered, otherwise his 2026 Avg/PP).
Results — # Quotes: each period against # Quotes under Requirements. Only craftsmen with an AJS Target and SR% Target entered have that requirement, so only their # Quotes are colored.
Actual Rate/Hr — All Hrs and Do Work: each against the craftsman's Hourly Rate under Inputs.
Results — $Booked: each period against $Booked (Labor) under Requirements (both labor only).
Scheduling (avg per pay period, last 3)
Each value is the average per pay period across the same three pay periods shown under Last 3 Pay Periods — Earnings. Each period's hours are totalled separately, then the totals are averaged. Only pay periods that start on or after the craftsman's hire date count (hire date from the Craftsmen Career Path), so a new hire is averaged over the periods since he started — hover his Sched Hrs to see how many. Available Hrs = each craftsman's weekly availability from the CM Locator scheduler × 2 (one 14-day period), refreshed nightly at 3 AM ET, minus time off: hours inside his scheduled window covered by Jobber tasks with no customer that are labeled time off or outside work (doctor's appointment, request off, vacation, another job). Tasks are labeled automatically every hour; the deduction is averaged over the same pay periods as Scheduled Hrs. Hover Avail Hrs to see scheduled hours, the deduction, and any blocks not yet labeled (those are not subtracted). Craftsmen with no schedule set show "—". Scheduled Hrs uses the same Jobber visits and assessments as Craftsmen → Work Hours, placed in a pay period by the appointment's start date in Eastern Time: All Activity = Do Work visits + Estimate assessments; Do Work = job visits only. Both apply the multi-craftsman rule — the first craftsman assigned gets 100% of the hours and each additional craftsman 50% — including on assessments. (The Work Hours report gives every craftsman on a shared assessment its full hours, so a shared assessment counts for less here.) Utilization (craftsman utilization) = Scheduled ÷ Available — under All Activity and again under Do Work.
Actual Rate/Hr
What the craftsman actually earned per scheduled hour over the same three pay periods: All Hrs = total of the three Last 3 Pay Periods — Earnings ÷ total Scheduled Hrs (All Activity) over those three periods. Do Work = the same earnings ÷ total Scheduled Hrs (Do Work). Because the Scheduling columns show a per-period average, the total hours are that average × the number of periods, so the rate equals average earnings ÷ average scheduled hours. For a new hire, only the pay periods since his hire date are used on both sides. Shows "—" when there are no scheduled hours.
ℹ️ How This Report Works
The same leaderboard craftsmen see from 🏆 Leaderboard on My Scorecard in the field app, with full names. Active craftsmen only (Craftsmen Career Path status Active, not Helpers, no test logins). Pick the period and the measure.
$ Sales — the Craftsmen Career Path Tracker’s sales: customer payments credited to the craftsman (Jan–Apr 2026 the imported Dispatch totals, May Jobber + Dispatch, June on Jobber). Everyone with sales is ranked.
$ Quoted / # Quotes — non-draft quotes created (cperf_quoted_between, full subtotal). $ Booked / # Booked — quotes approved (cperf_booked_between; $ is labor = subtotal − materials). Avg job — jobs closed, invoice subtotal ÷ jobs (cperf_raag). Success rate — won ÷ (won + lost) for requests created in the period; quotes still awaiting response are not counted. Days to quote — assessment visit → quote sent, exact quote dates only, fastest first. Survey NPS — WebPunch HC surveys matched to the craftsman through the customer's name on the Dispatch (to 5 May 2026) or Jobber job: % promoters (9–10) − % detractors (0–6), shown as a percent; ranked with 5+ surveys in the period. No surveys were sent in June or July 2026.
Rates (Success rate, Avg job, Days to quote) rank only craftsmen with at least 10 decided quotes / closed jobs / quotes in the period; the rest are listed under “Not ranked yet”. Last 3 months = the first of the month two months back through today; This month = month to date; Last month = the whole previous calendar month; 2026 = Jan 1 through today. Date range = any From/To you pick (Jan 1 2026 or later); every measure uses the same rules for exactly those days. For $ Sales, January–April 2026 and May’s Dispatch figures only exist as monthly totals, so they count only when the whole month is inside the range; Jobber payments from May 1 on count by day.
ℹ️ How This Report Works
What it is
The Payroll Report shows what each craftsman is owed for a given 14-day pay period. It combines timesheet pay from Jobber, vehicle expense reimbursements, material reimbursements, and any manual entries added here.
Pay Periods
Periods run every 14 days starting from May 13, 2026. Select a period from the dropdown to view or export that period's data.
Row Types
CM Pay — craftsman pay from Jobber timesheet entries where a pay rate is set. Each row links to the Jobber job.
Vehicle Expense — vehicle reimbursements from Jobber expense records titled "Vehicle Expense." Shown as a negative in the CM Pay column.
Labor Adjustment — Jobber expense records titled "Labor Adjustment." Used when a craftsman keeps cash from a customer.
Material Reimbursement — truck stock / material expenses from Jobber expense records. Shown in the Material Reimb column.
Manual Entry — line items added directly via the + Add Entry button. Can be for any craftsman or all craftsmen, any pay period.
W2 / 1099
Each craftsman's employment type is shown as a badge in their section header. Click the badge to toggle between W2 and 1099 — the change saves instantly.
Summary Bar
The three cards at the top show totals for W2, 1099, and Combined — CM Pay, Materials, and Net Pay for the selected period.
Excluded Craftsmen
Max McGonegal, Tori Hanners, Jarvae, Tim Fabrizio, and CM Test are always excluded from this report.
Data source & sync
Timesheet and expense data syncs nightly from Jobber. Manual entries are stored here and are never overwritten by a sync.
ℹ️ How This Report Works
What It Is
A centralized tracker of every craftsman's career profile, employment details, and full sales history at HCAA. It serves as the single source of truth for tenure, title, commission rate, POD assignment, and year-over-year production.
Data Source
All records are stored in Supabase and were initially imported from the CM Tracker Excel file. Fields marked with a dropdown or input (Status, Type, POD, Last Date) can be edited directly in this table and save instantly — no page reload needed. Sales through April 2026 are the historical Dispatch-era figures imported from Excel. From May 2026 onward, sales are computed automatically from customer payments in Jobber (see Sales Credit Methodology below).
Sales Credit Methodology (May 2026 onward)
Each craftsman's sales = the customer payments credited to them, where credit follows these rules:
• A sale is a customer payment, not an invoice. Both deposits and payments count, on the date the money was recorded (America/Detroit). A payment and the final payment on the same job often land in different months.
• Credit goes to the job's owner (Tim's priority chain, Oct 15 2026), first match in this order: (1) the craftsman on the job's next upcoming visit, or, when none is booked, its first visit (a helper alone on a visit counts for the craftsman he works with, e.g. Kendan Sipes → Scott Salo; two craftsmen on that visit → the job salesperson decides); (2) the job's salesperson in Jobber; (3) the quote's salesperson; (4) the request's salesperson; (5) the craftsman the request was assigned to; (6) the craftsman paid the most Labor on the job. Only craftsmen count: office staff who appear as a Jobber salesperson are skipped.
• If the payment has no job link at all, credit falls back to the earliest non-Helper labor entry across any job for that client. If exactly one craftsman qualifies, they are credited automatically (via Client Labor badge). If multiple craftsmen tie on the same earliest date, the payment goes to Unassigned for manual review.
• Helpers never receive sale credit — if a Helper is first, credit passes to the next non-Helper craftsman (applies to visit, job labor, and client labor fallbacks).
• Refunds reduce the credited craftsman's sales.
• May 2026 is a hybrid month: Dispatch sales (imported per craftsman, shown as one monthly line) plus Jobber-attributed payments. June 2026 onward is Jobber only.
The full attribution chain for each payment is: (1) Manual override → (2) The job's owner (visit → job salesperson → quote salesperson → request salesperson → request assignee → most labor; requires job link) → (3) Earliest client-level labor entry (used when no job link) → (4) ⚠ Unassigned.
Click any May 2026 or later monthly cell (or the 2026 total) to see the exact payments behind that number — customer, payment type, amount, date, and a link to the job in Jobber. Payments that can't be auto-credited collect in the ⚠ Unassigned row at the bottom, where you can manually assign the correct craftsman using the Assign to dropdown.
Title
Title is calculated automatically from Lifetime Sales: Apprentice ($0–$74,999) · Journeyman ($75K–$249,999) · Master Craftsman I ($250K–$749,999) · Master Craftsman II ($750K+). Helpers are manually designated and override the calculation.
Tenure
Calculated as (Today − Hire Date) ÷ 365. If a Last Date is entered (for craftsmen who have departed), Tenure uses (Last Date − Hire Date) ÷ 365 instead. Tenure feeds the Sales/Yr calculation.
Sales Columns
Sales are grouped by period. Historical covers pre-9/21/23 and 9/21–12/31/23 totals; click ► Detail to see the breakdown. 2024, 2025, 2026 each default to the annual total; click ► Qtrs to show Q1–Q4, then ► Months to show individual months. All expanded columns can be re-collapsed in reverse order.
Editable Fields
Status (Active / Not Active) · Type (W2 / 1099) · POD (Jarvae / Tori / Max / Tim) · Last Date (MM/DD/YY). All changes save immediately to the database and persist across reloads and redeployments.
Filters & Sorting
Filter by Status, Employment Type, and POD using the dropdowns above the table. Click any column header to sort ascending or descending.
💡 Insights
🎉 Promotion
🎯 Upcoming Promotions
🗓️ PTO
💰 Bonus
📈 Equity
Everyone with an account
| Who | Role | Status | Last sign-in | |
|---|---|---|---|---|
| Loading… | ||||
How the data gets from each system into the Reporting site and the Field app. Nothing here runs on Tim's Mac: the Supabase database starts every scheduled pull itself (pg_cron), and the three email/portal pulls that need a mailbox run as Claude cloud scheduled tasks. Times are Eastern (America/Detroit). Live health for each pull is in Sync Status above.
| Source | What we pull | How it runs | When |
|---|---|---|---|
| Jobber | Clients, Requests, Quotes, Jobs, Invoices, Payments, Visits, Expenses, Timesheets, Tasks, Users, photos | Edge Functions Jobber webhook | Nightly 1:00–4:45 AM; Requests, Sales and Financials again during business hours; Request changes arrive by webhook |
| Clarity Voice | Calls, text messages, recordings, transcripts, who spoke, Quality and Call Insights | Edge Functions GitHub workflow talk/silence only | Nightly from 3:00 AM; quality review every 2 min; talk/silence 5:30 AM |
| CallRail | SEO, PPC and LSA calls and web forms | Edge Function | 2:39 AM |
| Valpak | Direct-mail calls | Edge Function | 3:01 AM |
| QuickBooks | Credit-card charges, checks, marketing spend | Edge Functions | Hourly 7 AM–8 PM |
| Helcim | Card and ACH customer payments | Edge Function | 3:45 AM |
| Google Reviews | Reviews and ratings (SerpApi) | Edge Function | 4:05 AM |
| SendJim | Mailer orders by recipient | Edge Functions | 5:00 AM pull, then processed |
| GlassHouse | Text-campaign replies; matched to customers | Edge Functions | 5:25 AM replies, 5:30 AM matching |
| WebPunch | NPS scores and customer feedback (email 2FA handled in the function) | Edge Functions | 9:30 AM NPS, 9:45 AM feedback |
| AI Voice Agent | AI receptionist calls and outcomes | Edge Functions Claude task classifies no-action calls | Weekdays: 6:35 AM classify, 6:50 AM report |
| Home Depot Pro Referral | Lead emails in the LeadsAnnArbor mailbox | Claude task | Daily ~4:20 AM |
| ORSA Credit Union | Card-charge alert emails (craftsman per charge) | Claude task | Twice daily, ~6 AM and ~6 PM |
| EMC Insurance | Monthly bill and bank drafts, split for QuickBooks | Claude task Edge Function daily check | Monthly on the 18th; QuickBooks check 10:05 AM |
| Home Depot prices | Shelf prices for the Price Estimator (SerpApi, Ann Arbor store) | Edge Functions | When an estimate runs; tracked daily ~6:20 AM |
Switched off: eLocal, Project Quote and Networx (lead sources ended 3 Sep 2026), the Referpro email scan (Referpro tags Requests in Jobber itself since 1 Aug 2026), and Plaid (last ran 22 May 2026). Their history stays in the database.
Supabase — project HCAA Reporting (aeondsvudtbdnmyvamlj). It holds every table and report function, and it is also the scheduler: pg_cron starts each pull at its Eastern time, and the sync_schedule dispatcher starts the rest. Passwords and API keys sit in the Supabase vault, never in the website's code. Every pull writes a line to sync_log. A health check at 6:30 AM emails anything that failed, a failed call is retried after 1, 3 and 10 minutes, and runs missed during an outage are caught up automatically.
| Destination | What | How |
|---|---|---|
| Reporting website | hcaa-reporting.netlify.app — every report, reading Supabase directly | Master copy in GitHub serviceannarbor/hcaa-reporting. The Netlify Deploy workflow builds the review link (review--hcaa-reporting.netlify.app); production only after Tim says "push to live". |
| HCAA Field app | iPhone and Android app for craftsmen and the office | Reads the same Supabase database. Source is in GitHub (field-app/). |
| Jobber | Draft quotes from the Price Estimator | estimator-run Edge Function → Jobber API |
| Twist | Work hours (weekdays), work orders (Mon & Thu), craftsman pay summaries | pg_cron → twist-post Edge Function; pay summaries from the Payroll report via a GitHub workflow |
| Sync health, AI Voice Agent report, booked-with-no-assessment, bank charges, compliance reminders, EMC alerts | Edge Functions via Resend; EMC alerts from the Claude task |
No data pull does. Only building a new Field app version for the App Store and Google Play needs Xcode or Android Studio on a Mac.
| Completed | Mailed Date | Job ID | Sales | Craftsman | #CM>1 | Source | Customer | Street | City | Zip | Edit |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Load data using filters above | |||||||||||