
Author Name
Emtiaz Hossain
A home services company running paid traffic across Google and Meta, plus multiple location-specific landing pages, was tracking phone calls with static CallRail numbers and click-based GTM tags. That setup captures intent, someone tapped a phone number, but nothing about the call itself: no duration, no source attribution, no way to tell a Google Ads caller from an organic one or a Meta one. Here's how to replace static numbers with Dynamic Number Insertion (DNI) and get real call-level attribution.
A GTM tag that fires on phone number clicks tells you someone intended to call. It doesn't tell you whether they actually connected, how long the call ran, or which channel drove it, every visitor sees the same number regardless of how they arrived. For a business where a meaningful share of leads come in by phone rather than form fill, that's a real attribution gap: Smart Bidding never sees which keywords and campaigns are producing calls that convert.
DNI solves this by swapping the visible phone number per visitor based on their traffic source, so each call CallRail logs can be tied back to the specific channel, campaign, and even keyword that brought that visitor in.
CallRail's number swapping works through "website pools", groups of tracking numbers assigned to a page or set of pages. The right structure is one pool per physical location or service area, not one pool for the whole site, since each location needs its own local-area-code numbers and its own attribution:
Location Pool A → covers the main site page for that region + its dedicated landing page
Location Pool B → covers the main site page for that region + its dedicated landing page
Location Pool C → covers the main site page for that region + its dedicated landing pageEach pool needs enough numbers to avoid number collisions under concurrent traffic, 6-8 local numbers per pool is a reasonable starting point for moderate paid traffic volume. More concurrent visitors from paid channels means needing a larger pool so two visitors don't get assigned overlapping numbers.
1. Create the website pools in CallRail, one per location, each with its own set of local tracking numbers.
2. Deploy CallRail's swap.js via GTM, a single tag that fires on all pages. Configure it so each pool correctly targets and replaces the existing static number shown on that location's pages, and its matching landing page.
3. Connect the native CallRail → Google Ads integration. Once active, CallRail automatically creates conversion actions for qualifying calls, no manual GTM conversion tag needed for calls anymore.
4. Connect the native CallRail → Meta integration. CallRail fires a Lead event for calls that meet a configurable duration threshold, 30+ seconds is a reasonable qualifier to filter out accidental dials and wrong numbers, so only calls with real conversation intent count as a Meta conversion. No additional Pixel work needed on the Meta side.
5. Set the CallRail-generated conversion actions as Primary in Google Ads, replacing whatever click-based call conversion was Primary before.
6. Pause the old GTM click-based call tags. Once DNI and the native integrations are live, the click-tracking tags are redundant, they were only ever measuring intent to call, not the call itself.
7. Verify DNI is swapping correctly on every page and landing page in scope before calling the rollout complete, a broken swap silently reverts everyone to the static number and quietly kills attribution again.
Enough to avoid two concurrent visitors being assigned the same number, which would misattribute one caller's data to the other's source. For moderate paid traffic per location, 6-8 numbers is a reasonable starting point, higher-traffic locations or aggressive paid spend may need more.
No, when implemented correctly the swap only affects the number shown to trackable visitor sessions (typically those arriving via paid channels or specific referrers), and a static primary number is generally kept in structured data and for organic/direct visitors, so search engines still see a consistent number.
30 seconds is a reasonable default that filters out wrong numbers, accidental dials, and immediate hang-ups while still counting genuine conversations, including short ones that end in a quick no. It's configurable, and worth tuning against how the business's actual sales calls typically run.
Pausing first is safer than deleting immediately, it gives a rollback path if something in the DNI setup needs troubleshooting. Once the new call tracking has run cleanly for a couple of weeks, the old tags can be removed for good.
Discussed this on LinkedIn
Found this helpful?
Drop a comment on the LinkedIn post – I read every reply and love connecting with tracking folks.
Book a free 30-minute call. I will review your current tracking setup, show you where conversions are leaking, and tell you exactly what I would fix.
A full GA4/GTM/Google Ads audit on a UK Shopify store spending £18,000+/month found duplicate conversion tags inflating reported purchases 2x, a dropped GCLID at checkout, and misconfigured variables silently degrading Enhanced Conversions. Here's the audit, the fixes, and the migration off a legacy GTM setup before Shopify's deprecation deadline.
How a UK marketing agency's LinkedIn Insight Tag upgrade turned into a full conversion audit, catching duplicate tags and stale triggers across eight lead-gen conversions.
Duplicate form conversions in GA4 are usually a reload firing the same tag twice, not a real second submission. Here's the Custom JavaScript variable that catches it, plus other common causes to rule out.