If you are running digital ads to a landing page with a single, static phone number, you are making a massive attribution error. You might know that 50 people called today, but you have no way of knowing which of those calls came from your high-intent 'Emergency Plumber' keyword and which came from a generic organic search. DNI solves this by treating your phone number as a dynamic variable.
The fix sounds simple—swap in a different number per visitor—but the engineering is subtle. You need a pool of numbers large enough to never collide during peak concurrency, a session store that links the assigned number to the visitor's attribution data (UTMs, gclid, referrer), a DOM-replacement script that runs before the visitor sees the page, and a telephony-side bridge that reconciles inbound calls back to the original session. Get any of those wrong and your reported attribution looks correct while being quietly broken.
How DNI Works: The Pool Logic
CallMatrix uses a 'Number Pool' architecture. When a visitor arrives at your site, our script assigns them a unique number from your pool. That number is 'leased' to that visitor for the duration of their session. If they call, we know exactly who they are because that number is currently only visible to them.
The lease lifecycle matters more than most operators realize. A typical CallMatrix session leases a number for 20 minutes by default. If the visitor doesn't call within that window, the number returns to the pool—but with a 7-to-30-day cooldown before it can be reassigned, so a call that arrives 2 hours after the session started still attributes correctly to the original visitor. That cooldown window is what separates production-grade DNI from the naive implementations that misattribute delayed calls.
Run the math for your own site. Look at your peak hourly concurrent visitors (Google Analytics, Real-time view). Divide by 4. That's your minimum pool size for 99% attribution accuracy. Double it if you serve multiple campaigns or landing pages that need isolation. Triple it if you're running seasonal spikes (tax season for accounting, open enrollment for insurance). Numbers are cheap; missed attribution isn't.
Source-Level vs. Session-Level Tracking
1. Source-Level: Uses one number for all Google Ads traffic, another for Facebook. Good for broad budgeting. 2. Session-Level: The gold standard. Assigns a unique number to every individual visitor. This allows for keyword-level, device-level, and landing-page-level attribution.
Session-level is where the real ROI lives. With per-visitor attribution, your call log answers questions a spreadsheet never could: which landing-page variant converts best, which specific search keyword produces the closers, whether returning visitors call at higher or lower rates, whether mobile vs desktop shifts your bidding strategy. Each of those insights is worth tens of thousands in ad spend reallocation per quarter for a mid-sized marketplace.
Technical Implementation & SEO Impact
Many marketers fear DNI will hurt their Local SEO or 'NAP' (Name, Address, Phone) consistency. CallMatrix DNI uses 'JavaScript Replacement' which ensures that search engine crawlers only see your primary static number (preserving SEO), while human visitors see the dynamic number (preserving attribution).
The rendering sequence matters. Our script runs early in page load and replaces the target selector's text content before Time-to-Interactive. Crawlers that don't execute JavaScript—Googlebot's older versions, most local-SEO aggregators, Facebook's OG scraper—see the static number embedded in the HTML. Crawlers that do execute JS (Googlebot current generation) see the dynamic number; this is harmless because they don't call the number and they don't index dynamic content for the static NAP listings that matter for local rank.
Debugging DNI: The Five Most Common Failures
1. Pool exhaustion. Calls attribute to the wrong session because the pool recycled too fast. Fix: increase pool size; extend cooldown from 7 days to 14.
2. Click-to-call on mobile doesn't fire tracking. The `tel:` link bypasses the DOM-replacement and calls the static number. Fix: bind a click handler to `a[href^='tel:']` that updates the href to the leased number before default action.
3. Selector mismatch after a template change. The DOM-replacement silently fails when `.phone-number-header` no longer exists. Fix: add an assertion in the callback; alert on 'no nodes matched' for more than 5% of sessions.
4. iframe isolation. The DNI script doesn't run inside embedded iframes (chatbots, widget forms). Fix: make sure the parent page's number is the one exposed for voice; iframe widgets should route through the widget's own callback flow.
5. Stale CDN cache after a pool migration. Visitors keep calling a number that's been pulled from the pool. Fix: bust the CDN cache on every pool change; confirm `Cache-Control: max-age=0` on the tracker bundle.