How Phone Numbers Become Data (The Tech Behind DNI)
Dynamic Number Insertion sounds like magic. It's not. It's sophisticated engineering that transforms static phone numbers into attribution anchors. Here's how it works.
If you've ever wondered how call tracking "knows" where a phone call came from, you're asking the right question.
The answer isn't ESP. It's Dynamic Number Insertion (DNI).
And while it sounds like marketing jargon, it's actually one of the most elegant technical solutions in the attribution stack.
Here's how it works - no hand-waving, no fluff.
The Core Concept: Numbers as Attribution Anchors
At its simplest, DNI is a number swap system.
You have one "real" phone number (the number that actually rings your business). But on your website, visitors see different numbers depending on how they arrived.
Why? Because each number is tied to a specific traffic source.
When someone calls that number, you know - with high confidence - where they came from.
Example:
- Visitor from Google Ads sees:
02 9000 1001 - Visitor from Facebook sees:
02 9000 1002 - Visitor from Organic Search sees:
02 9000 1003
All three numbers forward to your real number (02 8765 4321). But because each visitor saw a unique number, you know the source of every call.
That's DNI at its most basic.
The JavaScript Layer (How the Swap Happens)
When a visitor lands on your website, a lightweight JavaScript snippet loads.
Step 1: Detect the Source
The script analyzes the visitor's session:
- Did they come from a Google Ad? (Check for
gclidparameter) - Did they come from Facebook? (Check for
fbclid) - Did they come from Organic? (Check referrer)
Step 2: Request a Number
The script makes a request to the call tracking platform:
"I have a visitor from Google Ads, Campaign X, Keyword Y. Give me a tracking number."
Step 3: Swap the Number
The script finds the phone number on the page and replaces it with the unique tracking number.
Step 4: Lock the Session
That tracking number is now "frozen" to that visitor's session for a set period (usually 30-90 minutes). If they call within that window, you know exactly which session it came from.
The Number Pool (Why You Need Multiple Numbers)
Here's where it gets interesting.
If you have 10 simultaneous visitors on your website, you need at least 10 tracking numbers to give each visitor a unique number.
This is called your number pool.
Pool size matters. If your pool is too small, numbers get reused before sessions expire, which reduces attribution accuracy.
Formula:Numbers needed = (Peak hourly visitors × Avg session duration in minutes) / 60
Example:
- Peak hourly visitors: 40
- Avg session duration: 2 minutes
- Numbers needed: (40 × 2) / 60 = 1.3 numbers
So for 40 visitors/hour, you'd need about 2-5 numbers depending on buffer.
The takeaway: Most businesses don't need hundreds of numbers. They need a smart pool that's sized correctly for their traffic.
Session-Level vs. Source-Level Tracking
There are two ways to do DNI:
Source-Level Tracking (Simple)
Every visitor from the same source sees the same number.
- All Google Ads visitors see:
02 9000 1001 - All Facebook visitors see:
02 9000 1002
Pro: You only need a few numbers (one per source).
Con: You can't track individual sessions. All Google Ads calls look the same.
Session-Level Tracking (Advanced)
Every visitor gets a unique number tied to their specific session.
- Visitor 1 from Google Ads sees:
02 9000 1001 - Visitor 2 from Google Ads sees:
02 9000 1002
Pro: You get session-level data - exact keyword, landing page, user journey.
Con: You need a larger number pool.
Session-level is what modern agencies need. It's the only way to optimize at the keyword and ad level.
The GCLID Connection (How Google Ads Attribution Works)
Here's where DNI gets really powerful.
When someone clicks a Google Ad, Google appends a GCLID (Google Click ID) to the URL:
yoursite.com/landing-page?gclid=abc123xyz
That GCLID is a unique identifier that contains:
- Campaign name & ID
- Ad group
- Keyword
- Device
- Time of click
When your DNI script runs, it captures that GCLID.
Now, when the visitor calls, you can:
- Link the call back to the exact Google Ads click
- Push the call back to Google Ads as a conversion (tied to that GCLID)
- Google's algorithm sees the call and learns which keywords drive phone conversions
This is how Smart Bidding works for phone calls.
Session Stitching with GA4 (The Missing Link)
DNI solves attribution. But there's another problem: linking the call to the GA4 session.
When someone calls, you want to see:
- What pages did they visit before calling?
- How long were they on the site?
- Did they watch a video or read reviews?
This is called session stitching, and it's how call tracking integrates with GA4.
How it works:
- Visitor lands on your site
- GA4 assigns them a Client ID and Session ID
- DNI script captures those IDs
- Visitor calls the tracking number
- Call tracking platform sends a
phone_callevent to GA4, including the Client ID and Session ID - GA4 links the call to the original session
Result: In GA4, you see the full journey - web behavior + phone call - in one timeline.
The Speed Problem (Why Numbers Need to Swap Instantly)
Here's a technical challenge most people don't think about:
The number swap needs to happen BEFORE the visitor sees the page.
If there's even a 1-second delay, the visitor might see the wrong number. They might dial the "default" number before the script runs. Attribution is lost.
How good DNI solves this:
- Lightweight script: Loads in <100ms
- Inline execution: Runs before the page fully renders
- Server-side rendering (SSR) support: For Next.js, Nuxt, and other SSR frameworks, the number is swapped on the server before the HTML is even sent to the browser
Speed isn't a nice-to-have. It's required.
The Edge Cases (What Breaks DNI and How to Fix It)
DNI is robust, but there are scenarios where it breaks. Here's what to watch for:
Problem #1: Single Page Apps (SPAs)
SPAs (React, Vue, Angular) don't do full page reloads. When a user navigates from /home to /services, the DNI script doesn't re-run.
Solution: Use a SPA-aware DNI script that hooks into route change events.
Problem #2: Phone Numbers in Images
If your phone number is embedded in a JPG or PNG (like a hero image), JavaScript can't swap it.
Solution: Use text-based phone numbers overlaid on images via CSS, or use SVG text.
Problem #3: Cached Pages
If your page is served from a CDN cache, the number might not swap dynamically.
Solution: Use edge-side rendering or exclude DNI script from caching.
The Privacy Layer (Recording Consent)
Here's the part most people forget: If you're recording calls, you need consent.
In Australia, the law requires:
- Implied consent (play a "This call may be recorded" message before the call connects), or
- Express consent (ask the caller if it's okay to record)
How modern platforms handle this:
- Pre-call message: "This call may be recorded for quality and training purposes."
- Opt-out option: "If you do not wish to be recorded, press 1."
- Compliance built-in: No manual configuration required.
If your call tracking doesn't handle this automatically, you're at legal risk.
The Evolution: From Numbers to Intelligence
DNI was revolutionary in 2010. In 2024, it's table stakes.
The next layer is call intelligence:
- What was said in the call?
- Was it a qualified lead?
- What objections were raised?
- Did they book or bail?
That's where AI transcription and intent tagging come in. But DNI is the foundation that makes it all possible.
Without accurate attribution, call intelligence is just noise.
The Strategic Takeaway
Dynamic Number Insertion isn't magic. It's engineering.
But the strategic impact is real:
- You know which campaigns drive phone calls
- You know which keywords drive qualified phone calls
- You can optimize for revenue, not just volume
- You can prove ROI when clients get nervous
That's the difference between activity tracking and revenue tracking.
DNI is how phone numbers stop being static contact info and start being attribution anchors.
Want to see DNI in action? Learn how Enfonica implements session-level tracking with GCLID capture and GA4 integration.