---
title: CallRail Dynamic Number Insertion (DNI) — Strategy & Implementation
type: article
created: '2026-04-05'
updated: '2026-04-05'
source_docs:
- raw/2025-12-12-internal-adava-care-callrail-setup-108448388.md
tags:
- callrail
- call-tracking
- dni
- attribution
- google-ads
- marketing-ops
- wordpress
layer: 2
client_source: null
industry_context: null
transferable: true
---

# CallRail Dynamic Number Insertion (DNI) — Strategy & Implementation

## Overview

Dynamic Number Insertion (DNI) is a call attribution technique that bridges the gap between digital ad tracking and phone calls. Without it, a visitor who clicks an ad and then calls instead of filling out a form breaks the attribution chain — the resulting lead has no connection to its original source.

CallRail's DNI solves this by acting as a transparent forwarding layer: tracking numbers sit in front of the client's real phone numbers, recording calls and capturing source data before passing the call through.

**Evidence:** Implemented for [[clients/adava-care/_index|Adava Care]] during a hands-on setup walkthrough with Mark Hope, Melissa Cusumano, and Sebastian Gant.

---

## How DNI Pools Work

A DNI pool is a set of tracking numbers assigned to a single website. When a visitor lands on the site, a JavaScript snippet (injected via the CallRail WordPress plugin or manually) swaps the target phone number visible on the page with a unique number from the pool.

**Key mechanics:**

- The swapped number is reserved for that specific visitor for approximately **20 minutes**
- During that window, CallRail captures the **Google Click ID (GCLID)** and associates it with any call made to that number
- If the visitor calls within 20 minutes, the call is fully attributed back to the originating ad, keyword, and session
- If they call after 20 minutes, the call still forwards correctly but granular attribution data may be partial or lost
- Every call through any CallRail number (pool or static) is **recorded**

**Pool sizing:** Start with 4 numbers. If more than 4 concurrent visitors call within a 20-minute window, pool numbers are exhausted and swapping stops for subsequent visitors. Scale the pool up if data gaps appear at high call volumes.

**One pool per website:** Running two DNI pools against the same website causes conflicts and unpredictable behavior. If a client has multiple websites, each site gets its own pool.

---

## DNI vs. Static Tracking Numbers

CallRail supports two number types, and a hybrid approach is usually correct:

| Type | Use Case | Attribution Granularity |
|---|---|---|
| **DNI Pool** | Main website number (header, footer, general CTAs) | High — captures GCLID, keyword, session source |
| **Static Number** | Location-specific pages, offline campaigns, ad call extensions | Medium — captures source category (e.g., "website") but not keyword-level detail |

**Rule of thumb:**
- Use **one DNI pool** targeting the primary site-wide number
- Use **dedicated static numbers** for each location page, print ad, billboard, Google Ads call extension, or any other distinct offline or campaign-specific touchpoint

For granular Google Ads tracking (e.g., call-only ads or call extensions), create a dedicated static CallRail number named for that campaign (e.g., "Glendale Google Ads") rather than reusing the location's website number.

---

## WordPress Plugin Setup

The preferred installation method for WordPress sites uses the official CallRail plugin rather than manually injecting the JavaScript snippet.

**Steps:**

1. In WordPress admin, go to **Plugins → Add Plugin**, search for "CallRail," install and activate
2. In CallRail, navigate to **Integrations → WordPress** — copy the WordPress-specific integration code (this is *not* the general API key)
3. In WordPress admin, go to **Settings → CallRail** and paste the integration code, then save
4. The swap begins within a minute or two of saving

> **Important:** Use the code from the **Integrations → WordPress** page, not the API key from Account Settings. The API key may be needed for other integrations (e.g., HubSpot webhooks) but is not what the plugin expects.

---

## Creating a DNI Pool in CallRail

1. Go to **Numbers → Create a Number**
2. Select the **pool/swap** option (left box)
3. Set the **swap target** to the phone number currently displayed on the site (the number that will be replaced for visitors)
4. Choose pool size (start with 4) and area code (match the client's existing number for local familiarity)
5. Name the pool clearly (e.g., "Website Pool")
6. Under **Number Routing**, set the forwarding destination to the client's real phone number
7. Enable **Inbound Call Recording**
8. Activate the tracking number

---

## Creating a Static Tracking Number in CallRail

1. Go to **Numbers → Create a Number**
2. Select the **single number / other** option
3. Search for a local number matching the location's area code (use "local to" search for best results)
4. Name it clearly (e.g., "Glendale" or "Glendale Website")
5. Under **Number Routing**, forward to the location's actual phone number
6. Enable **Inbound Call Recording**
7. Optionally enable **Whisper Message** — this announces the call source to the recipient before they speak. Disable initially to avoid confusing staff; enable once they're trained
8. Activate the tracking number

---

## Updating Phone Numbers on the Website

After creating static numbers, every instance of the old number must be manually replaced on the site. For Elementor-based WordPress sites:

1. Open the relevant page in Elementor
2. Find each phone number widget/element — there are typically multiple instances per page (e.g., hero section, address block, footer)
3. Update **both** the visible display text and the `tel:` href link
4. Publish the page
5. Repeat for all location pages and the global footer

---

## Cache Clearing (Required After Any Number Changes)

After making edits, clear both caches or visitors may continue seeing old numbers:

1. In WordPress admin, click the **WP Engine** link in the top bar → **Caching → Clear All**
2. In WordPress admin, click the **WP Rocket** link in the top bar → **Clear Cache**

To verify changes are live without browser cache interference, use an **incognito window** to visit the site. Note: the DNI swap has a per-visitor timer, so repeated checks from the same browser session won't trigger a new swap — incognito ensures a fresh visitor session each time.

---

## Attribution Notes & Known Limitations

- **Google GCLID latency:** Google does not always connect keyword/search data to the click ID instantly. Population can take up to 12 hours on a rolling basis. A webhook can be configured to retroactively populate call records with keyword data the following day — this is a future enhancement
- **Static number attribution:** Static numbers record that a call came from "the website" or a named campaign, but do not capture keyword-level data the way a DNI pool does
- **Pool exhaustion:** If call volume exceeds pool size within a 20-minute window, some calls will not be attributed. Monitor for data gaps and increase pool size if needed
- **CRM integration:** Call recordings can be pushed to HubSpot via webhook after the call completes. This is a separate future task — see [[clients/adava-care/_index|Adava Care]] next steps

---

## Related

- [[knowledge/call-tracking/callrail-static-numbers|CallRail Static Numbers — Location & Campaign Tracking]]
- [[knowledge/call-tracking/callrail-hubspot-webhook|CallRail → HubSpot Webhook Integration]]
- [[clients/adava-care/_index|Adava Care]]
- [[knowledge/wordpress/wp-engine-cache-management|WP Engine Cache Management]]