What call tracking actually means on a contractor site
Call tracking is not a phone system upgrade. It's a layer that sits between your website and your phone number so you can see where a call came from before you ever pick up. The mechanic is dynamic number insertion (DNI): your site holds a pool of tracking numbers, and JavaScript swaps in a different number depending on how the visitor arrived, paid search, organic search, a Google Business Profile listing, a specific service page. All of those numbers forward to your real line. You still answer one phone. You just get a report showing which source rang it.
For a contractor, this matters because the phone is still the primary conversion event. Roofers, plumbers, HVAC techs: most of your leads call, they don't fill out a form, no matter how good the form is. If your site has one static number and no tracking layer, every call looks identical in your reporting. You cannot tell a big remodel lead that came from a branded Google search apart from a tire-kicker who found you on page four of organic. That's not a marketing problem, it's a wiring problem, and it lives in how the site was built.
The honest caveat: DNI adds a script dependency and, if it's implemented sloppily, a flash of the wrong number before JS swaps it in, or a broken swap that shows a dead number to visitors with JS disabled. We build it so the fallback number is always your real, working line, never a blank or an error. Tracking should never risk the one thing it's supposed to protect: the call getting through.
Common providers we wire in: CallRail is the standard for contractor sites because it plugs into Google Ads, GA4, and most CRMs without custom code. Some shops run their CRM's native tracking (ServiceTitan and Housecall Pro both offer it) if you're already paying for the platform. Either way, the number pool, the swap logic, and the forwarding rules get built into the site at launch, not bolted on six months later when someone asks why the ad budget can't be justified.
Static number vs. dynamic tracking numbers: what you actually lose without it
A lot of contractor sites we inspect during an audit have exactly one phone number, hand-typed into the header, the footer, and a few call now buttons. It works. Calls come in. The problem shows up the first time you spend money on anything, Google Ads, a GBP posting service, a mailer with a QR code, and try to answer the question every owner eventually asks: did that work?
Here's the gap between the two approaches:
| Question | Static number | Dynamic tracking number |
|---|---|---|
| Which channel drove this call? | Unknown | Logged automatically |
| Can you hear the actual call? | No | Recorded (where legal, with disclosure) |
| Can you kill an underperforming ad? | Guesswork | Data-backed |
| Shows in Google Ads conversion data? | No | Yes, if wired to the ad account |
| Extra moving part to break | None | One script dependency |
That last row is the honest trade-off. A static number is simpler and it never breaks. Dynamic tracking adds a dependency: a script has to load, a number pool has to be current, and if the tracking vendor has an outage, you want the fallback to be your real number, not a blank field. We build the fallback logic in from day one so a tracking outage degrades to showing your real number and never to showing nothing.
Where this earns its keep: any contractor running paid search, a Local SEO campaign with GBP call-tracking requirements, or more than one active marketing channel at once. If you run word-of-mouth and one steady organic listing and nothing else, dynamic tracking is overkill; a clean static number with good call-to-action placement does the job. Match the tooling to what you're actually spending on. Consider the crew-size angle too: a two-truck outfit answering its own phone can often tell channels apart from context (a homeowner mentioning "I saw your ad"), which is a rough, human version of attribution. Once you're running paid campaigns across more than one platform, or you've added a dispatcher who wasn't on the sales call, that informal tracking breaks down fast and the dynamic-number data becomes the only reliable record.
Form wiring: what connected to your CRM should actually mean
A lead form that emails a Gmail inbox is not wired, it's parked. Real form wiring means a submission does four things automatically: it lands in your CRM or job-management platform as a new lead record, it tags the source (which page, which campaign, which trade if you serve more than one), it notifies a human immediately (text or push, not just email), and it survives if your inbox is full, deleted, or the office manager is on vacation.
The mechanism is a webhook: the form's backend fires an HTTP POST to an endpoint the moment someone submits, carrying every field plus metadata like the referring URL and UTM parameters. ServiceTitan, Jobber, and Housecall Pro all accept lead data through their own APIs or through middleware like Zapier or Make. A well-built contractor site posts directly to the CRM's endpoint where the CRM supports it, and uses middleware only where a direct integration doesn't exist. Fewer hops means fewer places a lead can silently vanish.
The failure mode we see most in a WordPress-to-static migration audit: a contact form plugin setup with three or four email notification rules layered on top of each other over the years, one going to an old employee's inbox, one going to a spam-filtered address, one going nowhere because a plugin update broke it quietly months ago. Nobody notices because some leads still come through. The ones that don't just disappear, and there's no log to prove it happened.
What a rebuilt form should log, at minimum:
- Timestamp and full field data, stored somewhere outside your email inbox (the CRM record itself, or a backup spreadsheet)
- Source page and referring channel, tagged automatically
- Delivery confirmation, ideally a text alert to the owner or dispatcher, not email alone
- A honeypot field to silently trap bot submissions instead of clogging your CRM with spam leads
- A visible success or error state on the page itself, so a visitor knows the form actually went through
None of this requires a plugin marketplace. It's standard form-handling logic wired directly into the site's code and a webhook endpoint, which is exactly the kind of integration work that belongs in a custom build rather than duct-taped onto a template.
Wiring your site to ServiceTitan, Jobber, or Housecall Pro
If you're running your business on a field-service platform, the website's only job on the lead-capture side is to get clean data into that platform without a human retyping it. How that connection gets built depends on the platform.
ServiceTitan has a documented API and, more commonly for smaller shops, supports lead capture through its marketing integrations or a middleware layer. Larger contractor operations sometimes have a ServiceTitan rep who can open direct API access; most single-location shops route through Zapier or a similar connector instead. Either path works. The direct API is faster and has fewer failure points; middleware is easier to set up and swap later if you ever change platforms.
Jobber has a public API and a request-a-quote form embed, plus native Zapier support, which makes it one of the more straightforward platforms to wire a custom site into. A form submission can create a Jobber client and request record without any manual re-entry.
Housecall Pro supports webhook-based lead intake and has its own API for partners; the same webhook pattern (form fires a POST, Housecall Pro receives it as a new lead) applies.
What we build regardless of platform: the form or call-tracking event fires into the CRM automatically, a fallback path (usually a plain email or text alert) exists in case the API call fails, and nothing about the wiring depends on a plugin that could silently stop working after an update, because there is no plugin, the integration is written into the site's own code. That's the core difference between a hand-coded site's integration layer and a WordPress form plugin's: the code is yours, you can see exactly what it does, and it doesn't have a vendor who can deprecate the plugin out from under you.
One honest limit: we wire the site to your CRM's intake. We don't rebuild your CRM workflows, sales stages, or dispatch logic inside ServiceTitan, Jobber, or Housecall Pro itself. That's platform configuration on your side or your CRM vendor's, not a website build task.
Payments, review requests, and chat: the rest of the integration layer
Call tracking and forms are the two integrations that most directly affect whether a lead gets counted. The rest of the integration layer, payment links, review-request triggers, chat widgets, matters for a different reason: it determines whether the site feels like a functioning piece of your operation or a brochure that happens to be online.
Payments. A deposit link or invoice-pay page wired to Stripe, Square, or your CRM's own payment processor lets a homeowner pay a deposit the moment they're ready, instead of waiting for a callback to take a card number over the phone. This is a build-time decision: does the payment link live on the site, or does it route through the CRM's hosted invoice page? Either is fine. What's not fine is a pay now button that's actually a mailto link or a broken redirect, which we catch in every pre-launch QA pass.
Review requests. If your CRM already sends review-request texts after a job closes (most do), the website doesn't need to duplicate that. What the site should do is make it dead simple to leave a review from any device: a single tap-to-review link on the thank-you page and in the footer, pointed straight at your Google Business Profile review URL, no extra steps.
Chat widgets. Live chat and chatbots are optional and trade-dependent. A high-ticket remodeler with a long buying cycle sometimes benefits from a chat widget that captures an after-hours question. A plumber running mostly same-day emergency calls usually doesn't need one; the phone number and a short form cover it, and one more third-party script is one more thing that can slow the page down or misfire.
The rule we apply: every integration on the site should either move a lead forward or remove a friction point. If a widget doesn't do one of those two things, it doesn't earn a place on the page, no matter how polished it looks in a demo.
How to check what's already wired on your current site
Before you pay anyone to rebuild anything, spend twenty minutes auditing what you have. Most of this doesn't require developer access.
- Call your own number from a phone that's never called it before, using an incognito browser session on a different device to load the site first (some DNI setups need a fresh session to swap the number). Does the number that displays match what you'd expect for that traffic source? Does the call actually connect?
- Submit your own contact form with a clearly marked test entry. Time how long it takes to show up somewhere you'd notice it, an email, a text, a CRM record. If it takes more than a minute or doesn't show up at all, that's a live leak.
- Check who receives form notifications. Ask whoever handles office admin: is there more than one email address on the notification list? Has anyone checked whether all of them are still monitored? Former employees' inboxes are a common silent leak point after a WordPress site changes hands over the years.
- Look at your Google Ads or GBP dashboard for call conversion data. If it says zero or shows suspiciously round numbers, tracking likely isn't wired to that account at all.
- Ask your CRM whether it's actually receiving website leads, or whether someone is still manually retyping form submissions into it. This is the single most common gap we find in a pre-migration audit: the CRM exists, the website exists, and nothing connects them.
None of these checks require special software or a developer on standby. They take about the time of one coffee break, and they tell you more about your current lead flow than a month of guessing ever will.
If any of these turn up gaps, that's useful information whether or not you rebuild the site: it tells you exactly what's costing you counted leads right now, today, with the site you already have.