Dynamic number insertion swaps the phone number on your website per visitor. One script tag, automatic source attribution, and zero impact on page speed.
Dynamic number insertion (DNI) automatically swaps the phone number on your website based on how each visitor found you. CallScaler ships DNI free on every plan, while many competitors charge extra or restrict it to higher tiers. The async script weighs under 5 KB, has no impact on page speed, and captures gclid, fbclid, msclkid, and every UTM parameter for full visitor-level call attribution.
Written by Curran Van Waarde, Founder, CallScaler
Quick facts about Dynamic Number Insertion
Price
Free on every plan
Setup time
About 5 minutes
Page weight
Under 5 KB, async
Click IDs captured
gclid, fbclid, msclkid, UTM
Works with
WordPress, Shopify, GTM, custom HTML
Multi-domain
Yes, one pool, many sites
In-depth guide to Dynamic Number Insertion
What is dynamic number insertion?
Dynamic number insertion (DNI) automatically swaps phone numbers on your website based on how each visitor found you. A visitor from Google Ads sees one number, a visitor from Facebook sees another, and an organic search visitor sees a third. The swap happens invisibly through a single JavaScript snippet. When any of these visitors call, you know which channel, campaign, and keyword drove the call.
Call log showing every call tagged to its tracking number — the visitor-level attribution dynamic number insertion produces
How dynamic number insertion works under the hood
You add a lightweight async JavaScript snippet to your website, or deploy it through Google Tag Manager. When a page loads, the script reads the visitor's referral source, captures click IDs like gclid, fbclid, and msclkid, and assigns a unique tracking number from your pool. That number is displayed everywhere on the page in place of your default business number. The assignment sticks to the visitor session, so if they browse multiple pages and call back later, the attribution still holds.
Dynamic number insertion vs static call tracking
Static call tracking assigns one number per campaign. If you run 10 Google Ads campaigns, you use 10 numbers. That tells you which campaign drove the call, but not which keyword or which specific visitor. Dynamic number insertion goes further by assigning numbers per visitor session, capturing the full click path including keyword, landing page, and device. For any business running online ads, DNI is the only path to accurate ROI measurement.
Impact on page speed and SEO
The CallScaler dynamic number insertion script loads asynchronously and weighs under 5 KB. It does not block page rendering or affect Core Web Vitals. The number swap happens after the page paints, so visitors do not see any layout shift. Search engines like Google index your real business number from the HTML source, which keeps your local SEO and Google Business Profile consistent. The swap is JavaScript-only, so Googlebot sees one number while users see tracking numbers.
Setting up dynamic number insertion for the first time
Build a number pool in CallScaler with at least 5 to 10 tracking numbers. Set the target number, which is the real number DNI replaces on your site. Copy the one-line snippet from your dashboard and paste it in your site header or in Google Tag Manager. The script auto-detects your phone number formats on the page and swaps them. No template changes needed. End-to-end setup takes about 5 minutes.
Pool detail dialog with member numbers, session timeout, and the actual install snippet ready to copy
Best practices for DNI number pools
Get the most out of your dynamic number insertion setup:
Start with 8 to 12 numbers and add more once pool use crosses 80 percent
Use local area codes that match your business region for higher answer rates
Set session length to 20 to 30 minutes for most business websites
Check the pool analytics dashboard weekly to right-size your pool
Pair DNI with call recording and AI summaries so every visitor call gets analyzed
Troubleshooting common dynamic number insertion issues
If numbers are not swapping on your site, check these common causes:
The tracking script must load before the page finishes rendering, so place it in the head tag
The target number on the page must match the format configured in CallScaler exactly
Phone numbers inside images or iframes cannot be swapped, so use text-based numbers
Ad blockers in your own browser may block the script, so test in incognito mode
Cached pages from your CDN may serve stale snippets, so purge after install
Deploying dynamic number insertion through Google Tag Manager
If your site uses Google Tag Manager, deploy the DNI snippet as a custom HTML tag that fires on all pages. This skips editing your site code and lets your marketing team manage the tracking script without developer involvement. Set the tag to fire on DOM Ready for the fastest number swap. GTM deployment is identical to a direct install in attribution, speed, and reliability.
Using dynamic number insertion alongside form tracking
The same tracking script that powers dynamic number insertion also captures form submissions on your site. When a visitor fills out a form, it gets the same source attribution as a phone call, including UTM parameters, gclid, landing page, and referrer. You can compare call and form conversion rates by source in one dashboard, with no extra code.
Forms log showing each submission tagged with its source (Google Ads, Meta Ads, Direct, Bing) and captured contact fields
How it works
One script tag, automatic visitor-level attribution.
01
Add the DNI Script
Drop one async script tag in your site header. Loads in under 5 KB with no impact on page speed.
02
Configure Number Pools
Build a pool of tracking numbers and set the swap target. CallScaler handles the rest.
03
Numbers Swap Per Visitor
Each visitor sees a unique number based on their referral source, campaign, and keyword. The swap is invisible and instant.
04
Track Every Visitor
When they call, CallScaler matches the number back to the exact visitor session, including source, keyword, landing page, and device.
Number pool with 3 tracking numbers swap-ready for dynamic number insertion on a website
Key capabilities
Dynamic number insertion that tracks everything without slowing your site.
Visitor-Level Tracking
Tie every call back to the individual visitor session that drove it, not just the campaign.
One-Line Install
A single async script tag. Works with any website, CMS, or landing page builder.
Referrer Detection
Detects Google Ads, Facebook, Bing, organic search, direct, and custom UTM sources automatically.
gclid and UTM Capture
Captures gclid, msclkid, fbclid, and every UTM parameter from the visitor URL.
Number Recycling
Numbers recycle after visitor sessions expire. Track more traffic with fewer numbers.
Multi-Domain Support
Use one pool across many domains. Built for agencies managing several client sites.
The dynamic number insertion install snippet
Paste this in your site header or drop it in Google Tag Manager. Replace YOUR_BUSINESS_ID with the ID from your CallScaler dashboard.
html
<!-- CallScaler Dynamic Number Insertion -->
<script>
(function(c,a,l,s){
c._cs=c._cs||[];
var t=a.createElement('script');
t.async=1;
t.src=l+'/api/v1/public/tracking.js?bid='+s;
a.head.appendChild(t);
})(window,document,'https://v3.callscaler.com','YOUR_BUSINESS_ID');
</script>
Loads asynchronously, so page rendering is never blocked
Find your business ID in CallScaler under Settings, then API
Works the same in plain HTML, WordPress, Shopify, Webflow, and Google Tag Manager
Fires from your real domain, so first-party cookies and click IDs survive most ad blockers