Skip to content
Draft — not yet reviewedThis article is a starter draft. The steps may not match the product exactly yet.

Set up Dynamic Number Insertion

Who this is for: Engineers and marketers instrumenting landing pages so inbound calls can be attributed to campaigns and ad clicks. What you’ll need: Access to Integrations → Snippets and Numbers → Number Pools, plus the ability to edit the landing page markup. Time required: About 30 minutes, plus site deploy time.

Dynamic Number Insertion replaces the phone number shown on your website with a Moja tracking number drawn from a number pool, and ties that number to the visitor’s session. When the visitor calls, Moja can connect the call back to the landing page, the traffic source, the UTM parameters, and the ad click that brought them there.

Without DNI, a website call is tracked as a call but carries no visitor-session context. A static number tells you the phone rang. DNI tells you which ad made it ring.

The same session context powers conversion uploads to connected ad platforms. For Google Ads the snippet captures gclid, gbraid, or wbraid; for Meta it can capture fbclid, _fbc, and _fbp.

Piece What it does Where it lives
Tracking tag / snippet JavaScript on the landing page that captures visitor-session data Integrations → Snippets
Number pool The group of tracking numbers available for dynamic assignment Numbers → Number Pools
Session attribution Connects the call to UTM parameters, referrer, browser data, and click IDs Reporting / Call Tracking
Cross-domain tracking Keeps the visitor ID intact when visitors move between your domains Edit Snippet → Linked Domains

Snippet configuration fields: Snippet Name, Campaign (Default) Number, Number to Replace, Number Pool, Linked Domains.

  1. A visitor lands on the page from an ad, search result, referral, or email.
  2. The snippet loads and captures session data — UTM parameters, referrer, browser data, and supported click identifiers.
  3. DNI selects a number from the configured pool and replaces the target number on the page.
  4. The visitor calls the inserted number.
  5. Moja ties the call back to that visitor session.
  6. Reporting and connected integrations use the attribution.
  • Decide which static number on the page should be replaced, and which numbers should stay static.
  • Estimate concurrent landing-page traffic so you can size the pool.
  • For paid traffic, enable Google Ads auto-tagging so click identifiers reach the landing page.
  1. Create or confirm a number pool.

    Go to Numbers → Number Pools. Create a pool or select an existing one, choose the number type and pool size for expected traffic, and confirm the numbers are provisioned and available.

    Expected result: the pool shows provisioned, available numbers.

  2. Create or edit the snippet.

    Go to Integrations → Snippets. Set a clear Snippet Name, select the Campaign (Default) Number, enter the Number to Replace exactly as it appears on the site, select the Number Pool, and turn on Enable Number Replacement. Configure Linked Domains if visitors move across your domains.

    Expected result: the snippet saves with a pool attached and replacement enabled.

  3. Install the snippet on the page.

    Copy the snippet code from Moja and paste it into the <head> of every landing page that should use DNI, then publish. Load the page and confirm the number on screen is a Moja tracking number.

    Expected result: the displayed number differs from your static number and changes across fresh sessions.

  4. Test attribution.

    Visit the landing page with test tracking parameters on the URL, confirm the number was replaced, place a test call, then open the call in Moja and confirm the attribution data is attached.

    Expected result: the call record shows the tracking identifiers and campaign context from your test URL.

A number pool gives each visitor session its own trackable number. The pool has to be large enough that concurrent visitors do not collide.

Moja sends a one-time warning when a pool reaches 85% utilization. It will not warn again for that pool until utilization drops below 85% and later crosses the threshold again. When you get the warning, add numbers or release ones you no longer need. Running a pool near capacity risks fallback behaviour and the loss of visitor-level attribution.

Static number Pool number via DNI
Attribution Call is tracked, but usually carries no visitor-session context Call is tied to the session, source, UTMs, and click IDs
Assignment Same number for everyone A number from the pool per visitor session
Sizing One number Sized to concurrent traffic; needs headroom
Ad-platform conversion uploads Not reliably supported Supported when click identifiers were captured

Existing static numbers keep receiving and tracking calls. DNI only affects pages where the snippet is installed and configured to replace a number.

  • The displayed number changes from your static number when the snippet is live.
  • A fresh browser session gets a number from the pool.
  • Your test call appears in Reporting / Call Tracking with attribution attached.
  • Useful labels to look for: Tracking IDs, WITH GCLID / Click ID, CONVERSIONS, UPLOADED, and Conversion Value / Type.
Symptom Likely cause Fix
Number is not replaced Snippet not in the page <head>, Enable Number Replacement off, or Number to Replace does not match the number on the page Check all three, then retest in a fresh browser session with cache cleared
Number is not replaced, config looks right Pool has no available numbers Check pool utilization and add numbers
Wrong number replaced Number to Replace matches more than one number on the page Narrow the value; confirm which numbers should stay static
Call tracked but attribution missing Visitor dialed a static number, or the snippet had not loaded before they called Confirm the dialed number came from the pool and that the snippet loads early in <head>
Attribution missing across domains Visitor moved between domains and the visitor ID was not carried Configure Linked Domains
UTMs missing on the call Landing page URL dropped the query string, often via a redirect Confirm parameters survive every redirect hop
Google Ads conversions not uploading No gclid, gbraid, or wbraid on the call Enable Google Ads auto-tagging and confirm the snippet is on every paid landing page
Meta conversions not uploading fbclid, _fbc, or _fbp not captured Confirm the landing page can capture Meta identifiers and that the integration is connected
Attribution degrades under traffic spikes Pool at or near capacity, triggering fallback Raise pool size ahead of campaign launches