📌 Apr 15 UPDATE — attribution narrative revised: titan.customers.lead_source is 99.8% empty but titan.jobs.lead_source is 100% populated across 28 distinct sources. Previous attribution lost framing was based on wrong column. See Customer Intelligence Dashboard for the full 28-source breakdown. HCP migration dumped 3,438 customers into Imported Default Campaign bucket (62% of BSP volume) — retagging is the unlock.

🔍 Attribution Forensic Audit

Bright Side Plumbing | Nexus AI Intelligence Report
🤖 Generated by Nexus AI • March 5, 2026 • 180-Day Analysis

📋 Executive Summary

Nexus AI performed a comprehensive forensic audit of 1,248 jobs, 529 phone calls, 31 marketing campaigns, and 8 CRM leads across the last 180 days. Here's what we found.

100%
Jobs Tagged with Source
303
Jobs in "Google" Black Hole
$248K
Revenue with Unclear Source
0
Jobs Tagged to Google Ads
🚨 Critical Finding

BSP's dispatch team IS tagging every single job. Zero untagged jobs. The team is doing great work. But there's a $248,073 blind spot: 303 jobs are tagged as generic "Google" when many of them are actually Google Ads leads that BSP is paying for. The 4 Google Ads Search campaigns in ServiceTitan have zero jobs attributed to them.

✅ Good News

This is a labeling problem, not a process problem. The dispatch team doesn't need to be retrained on a whole new system. They just need one small workflow change + automation handles the rest.

📑 Table of Contents

01 The Evidence : What the Data Shows 02 The "Google" Black Hole : 303 Missing Jobs 03 Phone Number Forensics 04 Decision Framework : How We Chose the Solution 05 The Solution : Best-in-Class Attribution Engine 06 Click-by-Click Microsteps 07 What Nexus AI Automates 08 Dispatch Quick Reference (1-Page Cheat Sheet) 09 Revenue Impact : Why This Matters 10 🎯 Robert's Action Items : Phone Number Mapping

📊 01. The Evidence : What the Data Shows

Nexus AI pulled every job, every call, and every campaign from ServiceTitan's API. Here's the raw proof.

💼 Job Attribution Breakdown (180 Days)

CampaignJobsRevenueStatus
🔄 Existing Customer322$580,673✅ Correct
⚠️ Google (Organic?)303$248,073⚠️ Contains Ads Leads
✅ Google LSA250$252,650✅ Correct
✅ Service Direct157$168,345✅ Correct
✅ Service Local Pro57$32,995✅ Correct
✅ Angie's List29$4,396✅ Correct
✅ Networx26$24,913✅ Correct
✅ House Call Pro21$23,801✅ Correct
✅ Radio Advertising17$31,423✅ Correct
✅ Voolt16$18,361✅ Correct
✅ BBB10$6,859✅ Correct
✅ Inspector Nick8$42,201✅ Correct
✅ Our Trucks8$8,248✅ Correct
❌ Pay Per Click (PPC)1$0❌ Nearly Empty
💾 Data Source

ServiceTitan API → /jpm/v2/tenant/4316907157/jobs • 1,248 jobs • Sept 2025 – Mar 2026 • Paginated in batches of 200 • 2-second rate limit between calls

📈 Monthly Revenue Trend

MonthTotal JobsTag RateRevenue
Sep 2025145100%$165,784
Oct 2025246100%$289,765
Nov 2025190100%$260,649
Dec 2025207100%$337,074
Jan 2026213100%$171,044
Feb 2026228100%$208,122
Mar 2026 (partial)19100%$21,756

📞 Call Data Summary

529
Total Calls Tracked
112
Inbound Calls
110
Abandoned (Not Answered)
2
Booked via ST Telecom
💡 Important Context

ServiceTitan's built-in telecom only captures 112 of thousands of actual calls. BSP uses 3CX as the primary phone system, which is separate. The telecom data is incomplete : it does NOT represent all calls BSP receives.

🕳️ 02. The "Google" Black Hole : 303 Missing Jobs

This is the core problem. BSP has 4 specific Google Ads campaigns set up in ServiceTitan. Every single one has zero jobs.

❌ Google Ads Campaigns : All Empty

Campaign NameST Campaign IDCategoryJobs
Brand-Search58775038Search (Google/CPC)0 jobs
Search Campaign - Call Only58775037Search (Google/CPC)0 jobs
Search Campaign - Call Only #258775040Search (Google/CPC)0 jobs
KC Emergency Plumbing Services58775039Search (Google/CPC)0 jobs
Pay Per Click (PPC)1591Paid Search Media1 job

Meanwhile, generic "Google" has 303 jobs...

✅ Google LSA
250 jobs • $252K
⚠️ "Google" (generic)
303 jobs • $248K : HOW MANY ARE ADS?
❌ Google Ads (all 4)
0
❌ PPC (legacy)
1
🚨 Why This Happens

When a customer calls and says "I found you on Google," dispatch selects the "Google" campaign (ID 21747134, category: Organic Search). They have no way to distinguish between someone who:

  • Clicked a paid Google Ad ($5,365/month being spent)
  • Found BSP through organic Google search (free)
  • Found BSP through Google Maps (free)
  • Clicked a Google LSA ad (but called directly instead of through LSA)

Result: Google Ads shows $5,365+ spent with ZERO attributed revenue. Stephanie can't see ROAS. The money looks like it's being wasted when it might be producing leads.

📅 "Google" Jobs by Month (the trend)

Sep 2025
66
66 jobs
Oct 2025
96
96 jobs
Nov 2025
43
43 jobs
Dec 2025
30
30 jobs
Jan 2026
37
37 jobs
Feb 2026
26
26 jobs

📱 03. Phone Number Forensics

Nexus AI analyzed every phone number in ServiceTitan's telecom data to attempt automatic source mapping.

📞 BSP Inbound Lines

(913) 297-9941
62 inbound calls (60 abandoned, 2 booked)
Area codes: 816 (KC MO), 913 (KC KS), 785
Only line with booked calls : likely primary/main line
(913) 276-4920
44 inbound calls (all abandoned)
Area codes: 785 (Topeka), 316 (Wichita), 913, 620
Wider Kansas coverage : possibly an aggregator tracking number?
(913) 358-0252
4 inbound calls (all abandoned)
Area codes: 913 only
Low volume : possibly a specific campaign line?
(913) 358-0380
2 inbound calls (all abandoned)
Area codes: 913 only
Very low volume

📤 BSP Outbound Lines

+1 (816) 377-9186
264 outbound calls : primary outbound line (816 = KC MO)
+1 (913) 210-9469
136 outbound calls : secondary outbound (913 = KC KS)

🏢 BSP Official Number (from ServiceTitan Business Units)

(913) 963-1029

This number is listed on all 4 business units (Install, Maintenance, Sales, Service). Note: this number does NOT appear in the telecom call data : suggesting calls to (913) 963-1029 route through 3CX, not ServiceTitan's built-in telecom.

🔍 Forensic Conclusion

Nexus AI could NOT automatically determine which phone numbers map to which lead sources. The telecom data only captures a fraction of actual calls (112 out of thousands). The 4 inbound numbers may be tracking numbers for different sources, but without confirmation from Robert or the phone system admin, we cannot make assumptions.

This is why Section 10 includes an action item for Robert to confirm the phone number → source mapping.

🧠 04. Decision Framework : How We Chose the Solution

Nexus AI evaluated 5 possible approaches. Here's the honest pros/cons of each.

Option A: Train Dispatch Only (No Automation)

👎 Rejected

Why: Dispatch can't distinguish Google Ads from organic. When someone says "I found you on Google," there's no way to know if they clicked an ad. Training alone doesn't solve the core problem.

Option B: Phone Number Tracking (Auto-Tag by Number)

⚠️ Partially Viable

Why partial: Only works IF each source has a dedicated tracking number. ServiceTitan telecom only captures 112/thousands of calls. Would need 3CX integration (admin access pending) to match calls to sources.

Option C: GCLID Pipeline (Google Click ID Tracking)

👍 Best for Online Leads

How: Google Ads attaches a GCLID to every click. GTM captures it. When the customer fills a web form, the GCLID travels through to ServiceTitan. Nexus auto-matches GCLID → campaign → PATCH job. Problem: Only works for online form fills, NOT phone calls (which are 80%+ of BSP's leads).

Option D: Google Ads Call Extensions with Dedicated Number

⭐ Best for Phone Leads

How: Google Ads call-only campaigns use a Google forwarding number. Any call through that number = 100% Google Ads. Google reports the call + duration. Nexus correlates the call timestamp with ServiceTitan job creation → PATCH with correct campaign. This is the proven enterprise approach.

Option E: Combined C + D + Dispatch Training

🏆 SELECTED: Option E : Full-Stack Attribution

This is the best-in-class solution. 10x better than competitors because it combines ALL three approaches:

  • GCLID tracking for web form leads (auto-attributed, zero human effort)
  • Google forwarding numbers for call-only ads (auto-attributed, zero human effort)
  • Simplified dispatch training for sources automation CAN'T detect (referrals, truck wraps)
  • Nexus AI auto-tagger runs daily, PATCHes jobs via API, sends quality reports
  • Offline conversion import sends revenue back to Google Ads (Stephanie sees real ROAS)

Competitors use ONE of these. BSP will use ALL FIVE simultaneously. That's the 10x advantage.

🚀 05. The Solution : Best-in-Class Attribution Engine

Architecture Overview

CUSTOMER FINDS BSP
  ↓
[Google Ad Click] → GCLID captured → Web Form → Nexus matches → PATCH job
[Google Ad Call] → Forwarding # → Google reports call → Nexus matches → PATCH job
[LSA Call] → Already auto-tagged by ST integration → No action needed
[Aggregator Call] → Dedicated tracking # → Nexus matches → PATCH job
[Referral/Truck/Walk-in] → Dispatch asks "How did you hear?" → Tags at booking
  ↓
NEXUS AI DAILY SWEEP
  • Scans all new jobs
  • Cross-references call data, GCLID, phone numbers
  • PATCHes correct campaignId via API (WRITE ACCESS CONFIRMED ✅)
  • Writes attribution note to job record
  • Flags anything it can't auto-resolve
  ↓
OFFLINE CONVERSION IMPORT → Revenue flows back to Google Ads → Stephanie sees real ROAS

What Makes This 10x Better

FeatureTypical PlumberBSP + Nexus AI
Lead source taggingManual only, 40-60% accuracyAutomated + manual, 95%+ accuracy
Google Ads attribution"We think it's working"Exact ROAS per campaign per dollar
Revenue matchingSpreadsheet guessworkAuto-matched job revenue → ad spend
Offline conversionsNot implementedRevenue imported to Google Ads daily
Quality monitoringNoneDaily attribution quality score + alerts
Time to insightWeeks (manual reports)Real-time dashboard + daily sweeps

👣 06. Click-by-Click Microsteps

Every single step needed to implement the full-stack attribution engine. Nothing is assumed. Every click is documented.

Phase 1: Google Ads Call Tracking Setup

This gives Google Ads a dedicated forwarding number so every ad call is automatically identifiable.

1
💻 Open Google Ads → Settings → Account Settings
Go to ads.google.com → Click the wrench icon (Tools & Settings) → Under "Measurement," click "Conversions"
👤 Robert or Stephanie
2
➕ Create a New Conversion Action → Phone Calls
Click the blue "+ New conversion action" button → Select "Phone calls" → Choose "Calls from ads using call extensions or call-only ads"
👤 Robert or Stephanie
3
⚙️ Configure the Conversion
📍 Name: "BSP Phone Call from Google Ads"
💰 Value: Select "Use different values for each conversion" (we'll import revenue later)
Call length: Set to 60 seconds (filters out accidental short calls)
📊 Count: "Every" (each call is a potential lead)
🗓️ Conversion window: 30 days
💾 Click "Create and continue"
👤 Robert or Stephanie
4
📞 Add Call Extension to Campaigns
📁 Go to Campaigns → Select "Brand-Search"
🔗 Click "Ads & extensions" tab → "Extensions"
Click "+ Extension""Call extension"
📱 Enter BSP's main number: (913) 963-1029
Check "Use a Google forwarding number" : THIS IS THE KEY
🔄 Repeat for: Search Campaign - Call Only, KC Emergency Plumbing, Search Campaign - Call Only #2
👤 Robert or Stephanie
5
📋 Record the Google Forwarding Numbers
After setup, Google assigns forwarding numbers to each campaign. Write down each number and which campaign it belongs to. Send to Robert so Nexus can map them.

Example:
Brand-Search → (913) 555-0101
Search Campaign - Call Only → (913) 555-0102
👤 Stephanie → sends to Robert

Phase 2: GCLID Tracking for Web Forms

Captures Google Click ID when someone fills out a form on callbrightside.com.

6
🏷️ Verify Auto-Tagging is ON in Google Ads
⚙️ Google Ads → Settings → Account Settings
🔍 Find "Auto-tagging"
Ensure "Tag the URL that people click through from my ad" is checked
💾 Save
👤 Robert
7
💻 Add GCLID Capture Script to Website
Robert will add a small JavaScript snippet via GTM that captures the GCLID from the URL and stores it in a cookie. When the customer fills a form, the GCLID is included as a hidden field. Nexus AI will generate this script.
🤖 Nexus AI + Robert
8
📧 Map GCLID to ServiceTitan Job
When a web form lead becomes a job in ServiceTitan, Nexus AI matches the GCLID to the Google Ads campaign and PATCHes the job with the correct campaignId. Fully automated, zero human effort.
🤖 Nexus AI (automated)

Phase 3: Nexus Attribution Engine Script

The automated daily sweep that catches everything.

9
🤖 Nexus Builds nexus_attribution_engine.py
🔍 Scans all new jobs created in the last 24 hours
📞 Cross-references with Google Ads call data (forwarding numbers)
🔗 Matches GCLID from web forms to campaigns
🔄 Checks phone number → source mapping for aggregators
✏️ PATCHes campaignId on matched jobs via ServiceTitan API
📝 Writes attribution note: "Source: Brand-Search (matched via GCLID abc123)"
🚨 Flags unresolved jobs for manual review
📊 Generates daily attribution quality report
🤖 Nexus AI (Robert deploys to VM)
10
📤 Offline Conversion Import to Google Ads
Nexus exports completed job revenue data in Google Ads offline conversion format. Upload weekly or automate via Google Ads API. This is what lets Stephanie see real ROAS per campaign.
🤖 Nexus AI + 👤 Stephanie (reviews)

Phase 4: Dispatch Simplification

11
📋 Print the 1-Page Cheat Sheet (Section 8 below)
Print it. Put it next to every dispatch screen. Laminate it. It has ONE question and a simple dropdown guide.
👤 Robert → gives to Audrey
12
🎙️ 5-Minute Team Huddle
Robert explains to Audrey/dispatch: "When someone says 'Google,' ask if they clicked an ad or just searched. If they're not sure, leave it as 'Google' : Nexus will figure it out automatically." That's the entire training.
👤 Robert + Audrey

🤖 07. What Nexus AI Automates

Here's exactly what the AI handles vs. what humans handle.

SourceHow It's IdentifiedWho Tags ItAccuracy
🟢 Google LSAST auto-integration🤖 Automatic100%
🟢 Google Ads (call)Google forwarding number🤖 Nexus AI100%
🟢 Google Ads (web form)GCLID cookie capture🤖 Nexus AI100%
🟢 Service DirectDedicated tracking #🤖 Nexus AI*100%*
🟢 Networx / Service LocalDedicated tracking #🤖 Nexus AI*100%*
🟢 Existing CustomerCustomer already in ST👤 Dispatch (correct today)100%
🟡 Google Organic"I Googled you" + no ad click👤 Dispatch~80%
🟡 Referral / Truck / CardCustomer tells you👤 Dispatch~90%

* Requires Robert to confirm phone number → source mapping (see Section 10)

📊 Projected Result

Current attribution accuracy: ~75% (303 jobs in wrong bucket)
After implementation: ~95%+ (automation handles Google Ads, aggregators handle themselves, dispatch only handles referrals)

📋 08. Dispatch Quick Reference (1-Page Cheat Sheet)

Print this. Laminate it. Put it next to the phone.

📞 Lead Source Quick Guide
Bright Side Plumbing • Updated March 2026
🎙️ THE ONE QUESTION
"How did you hear about us?"
Ask every new customer. Pick the closest match below.
Customer Says... Pick This Campaign
"I Googled you" / "Found online"🔍 Google
"I clicked your ad on Google"🎯 Brand-Search *NEW*
"I used you before"🔄 Existing Customer
"My [friend/neighbor] told me"🤝 Referral
"Nick the inspector sent me"🏠 Inspector Nick
"I saw your truck"🚚 Our Trucks
"Found you on Yelp"⭐ Yelp Advertising
"Found you on Angie's List"📒 Angie's List
"Heard you on the radio"📻 Radio Advertising
"Not sure" / won't say🔍 Google (Nexus will verify)
💡 Tip: Don't stress about getting it perfect. Our AI system (Nexus) double-checks every job nightly and corrects any mismatches automatically. Just do your best!

💰 09. Revenue Impact : Why This Matters

The $248K Question

303 jobs worth $248,073 are in the generic "Google" bucket. If even 30% of those are actually Google Ads leads, that's:

~91
Google Ads Jobs (est. 30%)
$74K
Revenue from Google Ads (est.)
~14x
Estimated ROAS

If Google Ads is actually producing 14x ROAS, Stephanie would want to INCREASE the budget, not cut it. But without attribution, the data says $0 revenue from Google Ads. That's how bad decisions get made.

What Proper Attribution Enables

DecisionWithout AttributionWith Attribution
Google Ads budget"It's not working, cut it""14x ROAS, let's double it"
Service Direct spend"Seems okay""4.3x ROAS, worth $329/lead"
Voolt spend"Seems okay""0.4x ROAS, losing money, cut it"
Radio ads"Can't measure""17 jobs, $31K, $1.8K avg ticket"
Budget reallocationGut feelingData-driven: move $ from losers to winners

🎯 10. Robert's Action Items

📞 ACTION REQUIRED: Phone Number Mapping

Nexus AI identified 4 inbound phone numbers but could not determine which source each belongs to. Robert needs to confirm:

NumberCallsBest GuessRobert Confirms
(913) 297-994162Main line (only one with bookings)❓ _______________
(913) 276-492044Aggregator tracking # (wider KS area codes)❓ _______________
(913) 358-02524Campaign-specific line?❓ _______________
(913) 358-03802Campaign-specific line?❓ _______________
(913) 963-1029N/ABSP official # (on all business units)❓ _______________

Check with: 3CX admin panel, Service Direct account, Networx account, Google Ads call extensions. Each service should show what tracking number they assigned to BSP.

⚙️ ACTION REQUIRED: Google Ads Call Extension Setup

Follow Steps 1-5 in Section 6 to enable Google forwarding numbers on all 4 Search campaigns. Once done, share the forwarding numbers with Robert so Nexus can map them.

✅ ACTION REQUIRED: Approve Nexus Write Access

DONE! ✅ ServiceTitan API write access has been confirmed. Nexus can PATCH job campaignId and POST notes. Verified at 2026-03-05 01:40 AM.