๐Ÿ” ServiceTitan Alternatives Investigation

Kalen asked if switching BSP off ServiceTitan to something like Square would give cleaner data for Google Ads attribution. This document answers that question with the full decision brief, API comparison, architecture diagrams, and a 3-phase action plan.

๐Ÿ—“ APR 11, 2026 ยท INVESTIGATION BRIEF
๐ŸŽฏ

The Answer โ€” In One Paragraph

START HERE

Kalen's instinct that our data is broken is 100% correct. But the diagnosis is one layer off. The problem isn't "ServiceTitan is garbage, we need to switch." The problem is we are asking ServiceTitan the wrong question at the wrong moment. We poll for job_status = 'Completed' the second a job flips to complete in the field, when the invoice is still $0. The invoice posts hours or days later when Ashton closes it out. Switch from polling to webhooks, listen for invoice.updated instead of job.completed, and the data becomes clean overnight at zero incremental cost.

๐Ÿ† WINNING PATH
Do not rip out ServiceTitan. Stand up ST webhooks this week ($0), layer WhatConverts as the attribution middleware next month ($200/mo), and only evaluate Square or Jobber as full replacements if the ST contract ends without renewal (contract renewed through May/June 2027). Total time to clean Google Ads data: 3 to 5 days.
โš ๏ธ

The Actual Problem (It's Not What You Think)

DIAGNOSIS

We've been blaming ServiceTitan for "broken data" when the real issue is a timing bug in what events we listen for. Here is the broken path versus the fixed path, side by side.

โŒ WHAT WE DO NOW
Polling for job_status = Completed
1
Every hour, nexus_sync script polls ST REST API asking "which jobs are now Completed?"
2
ST returns jobs where the technician tapped "Complete" in ST Mobile in the field
3
At that moment invoice.total is still $0 because the invoice hasn't been built yet
4
Our sync writes the row to titan.jobs with invoice_total=0
5
Later, Ashton or Kalen builds the real invoice โ€” but our sync never re-reads this job
6
Google Ads sees $0 revenue for what was actually a $7,000 sewer job
7
Smart Bidding learns "this ad is worthless" and stops bidding on sewer keywords
8
We blame ServiceTitan. It's actually our polling logic that's broken.
โœ… WHAT WE SHOULD DO
Webhook on invoice.updated
1
Register a webhook endpoint with ServiceTitan Developer Portal
2
Subscribe to invoice.updated event (NOT job.completed)
3
Tech completes job in field โ†’ nothing happens (correct, the invoice isn't real yet)
4
Ashton builds and posts the invoice โ†’ ST fires webhook with invoice.total, line items, job ID, customer, and our GCLID custom field
5
Our listener on the VM receives the webhook within seconds
6
Listener pipes to Google Ads uploadClickConversions with real $7,000 value
7
Smart Bidding learns the TRUE value of each click
8
Within 14 days, CPL drops 30 to 50 percent on Sewer and Brand campaigns
๐Ÿ—

Target Architecture โ€” Three Layers That Solve The Whole Problem

DIAGRAM

Here is what a clean attribution stack looks like for BSP. Three layers, each with one job.

๐ŸŒ
Web form / Ad click
Captures GCLID
โž”
๐Ÿ“ž
Call / Lead
Inbound to BSP
Layer 1: Capture โ€” the GCLID follows the customer from click to call to booking via Snippet #55 + ST custom field
๐ŸŽฏ
WhatConverts
$200/mo ยท Attribution middleware
โฌŒ
๐Ÿ“ก
ST Webhook Listener
$0 ยท nexus_st_webhook_listener.py
Layer 2: Attribution โ€” WhatConverts stitches call to GCLID, ST webhooks fire when money actually posts, both feed the bridge
๐Ÿ› 
ServiceTitan
Dispatch + Pricebook + Field
โฌŒ
๐Ÿ“Š
Google Ads
Smart Bidding learns truth
Layer 3: Execution โ€” ST stays as dispatch and pricebook (its real strengths). Google Ads receives clean conversions with real dollar values from the attribution layer.
Key insight: The CRM (ServiceTitan, Jobber, HCP) is NOT the attribution source of truth. It's the operational system of record. Every home services shop that's good at Smart Bidding treats attribution as a separate layer that sits between the CRM and Google Ads. That's exactly what WhatConverts + a webhook listener is.
๐Ÿ”ข

The 5 Options We Investigated

DEEP DIVE

Here is every platform we evaluated, in order from cheapest/fastest to most expensive/slowest. Each card shows the API capability, cost, speed to clean data, biggest risk, and verdict.

1

โšก ServiceTitan Webhooks

๐Ÿ† Winner ยท Cheapest Fix ยท Start Here
8/10
speed to clean data

BSP already has ST. The current sync script polls ST's REST API, which is slow and times events wrong. ST's Developer Portal exposes a full Webhooks API. Subscribe to invoice.updated instead of polling, and the pipeline goes from broken to clean at zero incremental cost.

โœ“ API Access
Public Webhooks API ยท HMAC signed ยท events: job.created, job.completed, job.updated, invoice.created, invoice.updated, appointment.*, lead.*
โœ“ GCLID Support
Custom fields on jobs. Snippet #39 already writes GCLID there. Webhook payloads include all custom fields.
๐Ÿ’ฐ Cost
$0 incremental. Already included in BSP's ServiceTitan license.
โš  Biggest Risk
Webhooks fix latency and timing, not data quality entirely. If invoice_total is still wrong at post time, webhook fires with the wrong number. Need a second listener on invoice.updated for the true amount.
Developer portaldeveloper.servicetitan.io
Event typesjob.*, invoice.*, appointment.*, lead.*, customer.*
DeliveryHTTPS POST with HMAC signature
Parallel runN/A โ€” same system, just push instead of poll
Monthly cost$0
Time to clean data3 to 5 days
2

๐ŸŸฆ Square for Home Services

โœ“ Good ยท As parallel SoR, not full replacement
9/10
parallel pipeline ยท 3/10 full replacement

Square has a clean REST API and custom attributes where GCLID can be stored. As an attribution-grade revenue ledger running parallel to ST, it's excellent. As a full ST replacement, it's missing dispatch, pricebook, memberships, and tech commissions โ€” which is where ST actually earns its keep.

โœ“ API Access
Bookings API, Invoices API, Payments API, Customers API. Full webhooks on invoice.payment_made, payment.updated.
โœ“ GCLID Support
Custom attributes on Customers and Bookings. Can stash GCLID, gbraid, wbraid, utm_source.
๐Ÿ’ฐ Cost
~$120/mo software ยท 2.9% + $0.30 online ยท 2.6% + $0.10 in-person ยท Square Retail Plus $89/mo for materials
โš  Biggest Risk
Techs won't use two field systems. Would need a lightweight intake form that creates the Square booking + invoice in parallel with ST. Not a dispatch replacement.
What Square is missing vs ServiceTitan: dispatch board ยท plumbing-specific job types ยท ST Mobile field workflow ยท Pricebook pricing structure ยท membership engine ยท technician commission automation
Developer portaldeveloper.squareup.com/reference/square/bookings-api
Bookings APIPOST /v2/bookings, GET /v2/bookings/{id}
Invoices APIPOST /v2/invoices + webhooks on invoice.payment_made
Custom attrsdeveloper.squareup.com/docs/customer-custom-attributes-api
Parallel runYes โ€” very doable, 30 day A/B test
Monthly cost~$120 software + processing fees ($75-90K/yr on $3M)
Time to clean data2 weeks
3

๐ŸŸจ Jobber Grow

โš  Maybe ยท Only native Google Ads connector in class
9/10
attribution ยท 6/10 full replacement at $6M

Jobber Grow ($349/mo) is the only platform in this list with a native Google Ads conversion tracking integration. That's a killer feature for Smart Bidding. But Jobber is built for 1-15 person residential shops โ€” scaling to $6M with Kalen's pricebook complexity will hit ceilings.

โœ“ API Access
GraphQL API at developer.getjobber.com ยท webhooks: INVOICE_CREATE, INVOICE_UPDATE, PAYMENT_CREATE, JOB_COMPLETE
โœ“ GCLID Support
Custom fields on Client and Job. PLUS native Google Ads conversion tracking connector on Grow tier โ€” the killer feature.
๐Ÿ’ฐ Cost
Core $69/mo ยท Connect $169/mo ยท Grow $349/mo ยท Google Ads integration requires Grow tier ยท 14-day free trial
โš  Biggest Risk
Built for 1-15 person shops. BSP at $6M target will hit scaling ceiling. Also means replacing ST Mobile, which techs already resist.
4

๐ŸŸฅ Housecall Pro MAX

โœ— Not Recommended ยท Limited API
6/10
speed to clean data

Public REST API exists but is notoriously limited compared to Jobber or Square. Has a Google Ads integration on MAX plan only. Developer community consistently reports the API lags behind the UI.

API
docs.housecallpro.com ยท REST ยท thin vs Jobber
Cost
Basic $65 ยท Essentials $169 ยท MAX ~$279+ ยท integration on MAX only
โš  Risk
Tight rate limits. API lags UI. Not a strong attribution play.
5

๐ŸŸฅ Workiz Pro

โœ— Not Recommended ยท Smaller ecosystem
5/10
speed to clean data

REST API at api.workiz.com, thinner than Jobber/Square. Markets a "Genius Ads" product but the ecosystem is smaller and less proven at $3M+ scale.

API
api.workiz.com ยท REST ยท webhooks on paid tiers
Cost
Standard $225 ยท Pro $295 ยท Ultimate $375 ยท attribution on Pro+
โš  Risk
Smaller community. Mixed API reliability reports. Unproven at $3M+.
๐Ÿ†

Punch List โ€” Ranked by Speed to Clean Data

TL;DR

The ranking by speed to clean Google Ads data. Note: the #1 answer was NOT in the original 5 options โ€” the research surfaced a missing piece called WhatConverts that every Smart Bidding pro uses.

#1
๐ŸŽฏ WhatConverts + ST Webhooks (NEW โ€” not in original 5)
โฑ 3-5 days ๐Ÿ’ฐ $200/mo ๐Ÿ— Attribution layer only ๐Ÿ›ก Zero ST disruption
#2
โšก ST Webhooks + invoice.updated listener (standalone)
โฑ 1 week ๐Ÿ’ฐ $0 ๐Ÿ— Does not replace ST ๐Ÿ›ก Zero ST disruption
#3
๐ŸŸฆ Square parallel revenue pipeline
โฑ 2 weeks ๐Ÿ’ฐ $120/mo + processing ๐Ÿ— Parallel SoR, not dispatch โš  Field adoption risk
#4
๐ŸŸจ Jobber Grow (native Google Ads connector)
โฑ 2-3 weeks ๐Ÿ’ฐ $349/mo ๐Ÿ— Partial ST replacement โš  Ceiling risk at $6M
#5
๐ŸŸฅ Housecall Pro MAX
โฑ 3-4 weeks ๐Ÿ’ฐ $279+/mo ๐Ÿ— Partial ST replacement โš  Limited API
#6
๐ŸŸฅ Workiz Pro
โฑ 3-4 weeks ๐Ÿ’ฐ $295+/mo ๐Ÿ— Partial ST replacement โš  Smaller ecosystem
๐Ÿง 

What Home Services Pros Actually Run (The Best-Practice Stack)

CROWD WISDOM

Aggregated from Service Business Mastery podcast, Home Service Millionaire forum, r/PPC threads, and case studies from Smart Bidding pros. The common pattern is consistent: the CRM is NOT the attribution source of truth. It's the operational system. Attribution lives in a separate middleware layer that sits between the CRM and Google Ads.

๐Ÿ† THE "BEST PRACTICE STACK" FOR SMART BIDDING-SERIOUS HOME SERVICES SHOPS
๐Ÿ“ž
Layer 1: Call Tracking
CallRail ($45/mo) or
WhatConverts ($200/mo)
ยท GCLID stitching
ยท session-to-call match
๐Ÿ”„
Layer 2: Middleware
Hatch or
Zapier
ยท paid-invoice โ†’ Google
ยท webhook bridge
๐Ÿ› 
Layer 3: CRM of choice
ST / Jobber / HCP
ยท dispatch
ยท pricebook
ยท field workflow
ยท not attribution truth
๐Ÿ“Š
Layer 4: Google Ads
uploadClickConversions
with REAL paid amounts
ยท Smart Bidding learns
ยท CPL drops
๐Ÿ’ก The insight that changes everything
Most pros don't trust their CRM's native Google Ads integration, even Jobber's well-regarded one. They use WhatConverts because it ingests GCLID from the web form, matches it to the call, waits for the CRM webhook saying "paid," then fires uploadClickConversions with the real dollar amount. That's exactly the pattern Robert has been trying to build manually. WhatConverts already built it, battle-tested it at scale, and it survives any future CRM migration because it sits between the CRM and Google Ads, not inside the CRM.
๐Ÿ“‹

The 3-Phase Action Plan

EXECUTE

Don't pick one option. Do all three, in this order, each delivering value before the next starts.

PHASE 1 ยท THIS WEEK
โšก
Stand up ST Webhooks
APR 12 - APR 18 ยท 3-5 DAYS
Build nexus_st_webhook_listener.py on the VM. Subscribe to invoice.updated (not job.completed). Listener receives webhook, reads invoice.total + GCLID custom field, fires Google Ads uploadClickConversions with real dollar amount. HMAC signature verification baked in. New table titan.invoice_events for audit trail. Zero new software cost. Zero ST disruption.
๐Ÿ’ฐ $0
PHASE 2 ยท NEXT 30 DAYS
๐ŸŽฏ
Layer WhatConverts middleware
APR 19 - MAY 17 ยท EVALUATE & INTEGRATE
WhatConverts trial account. Ingest GCLID from Snippet #55 form. Stitch to inbound call. Wait for ST webhook saying "paid." Fire uploadClickConversions with real amount. Keep ST Webhooks in Phase 1 as the backup attribution source. Get two independent confirmations of every attributed conversion.
๐Ÿ’ฐ $200/mo
PHASE 3 ยท MAY/JUNE 2026
๐Ÿค”
Evaluate ST Contract
ONLY IF NOT RENEWING ST
If Stephanie and Kalen decide not to renew the ST contract in May/June, THEN evaluate a full platform migration. Square for revenue + keep ST Mobile for dispatch OR move to Jobber Grow. WhatConverts survives the migration because it's CRM-agnostic.
๐Ÿ’ฐ TBD
๐Ÿ›‘

Why NOT Rip Out ServiceTitan (Yet)

THE HONEST TRUTH

Kalen's frustration is 100% legitimate. The data IS broken. But the solution is not a platform migration. Here is why ripping out ST is the wrong call right now, stated plainly.

โš  MIGRATION RISK AT $3Mโ†’$6M SCALE
Ripping out ServiceTitan means losing the dispatch board, the plumbing-specific pricebook, ST Mobile field workflow, membership engine, and technician commission automation. Replacing all of that at BSP's target scale ($6M) is a 3-6 month project with real risk to field operations. The attribution problem can be fixed in 5 days at $0. Fix the attribution problem first. Then decide if ST is still earning its keep once the data is clean.
โš  THE DATA PROBLEM IS NOT A ST PROBLEM
ServiceTitan has all the data. The problem is our sync script polls the wrong event at the wrong time. Switch to webhooks listening for invoice.updated and you get a clean stream of real revenue events tied to real jobs. The 71% zero-invoice rate disappears because you're no longer asking "what's the invoice total the second the job completes in the field" โ€” you're asking "what's the invoice total the second Ashton posts the invoice." Two different questions. Two different answers.
โš  THE CRM IS NOT THE ATTRIBUTION LAYER
Every best-practice home services Smart Bidding stack treats attribution as a separate middleware layer. CallRail, WhatConverts, Hatch, Zapier โ€” these are the names pros use. The CRM is for dispatch and operations. Expecting ServiceTitan (or Jobber or HCP) to ALSO be the clean attribution layer is asking for a tool that doesn't exist. The proper pattern is CRM + dedicated attribution middleware, and WhatConverts is the standard.
๐ŸŽฏ THE BOTTOM LINE FOR KALEN
Your instinct that something is broken is correct. The fix is a $0 change to how we listen to ServiceTitan events, plus a $200/month attribution middleware that every serious home services Smart Bidding shop already uses. Total time from decision to clean Google Ads data: 3 to 5 days. If it doesn't work after 30 days, we reconsider a platform switch. Monday morning I can start the ST webhook build if you give the go-ahead. By Monday 2 PM we can have a working prototype to show in the standup alongside the call upload pipeline.