A plumber in Denver watched 40% of his paid calls route to callers in Colorado Springs — 70 miles south, well outside his service area. He was paying $65 per call for leads his techs couldn't service. The campaign had "Colorado" targeting. That was the entire geo-filter.
This happens constantly. Buyers set broad state or metro targeting, run spend, and wonder why close rates tank. The answer is almost always misaligned geography: callers outside the service area, routed to buyers who can't help them, burning money on both sides.
This tutorial walks through building proper geo-targeting using ZIP-code radius and DMA boundaries. I'm going to be honest — I've botched this setup myself more times than I'd like to admit. But by the end, you'll have a routing setup where local callers hit local buyers, edge-zone callers hit regional overflow, and out-of-area callers go somewhere useful (or get a polite IVR exit) instead of wasting everyone's time. For general routing fundamentals, see our call routing best practices guide.
Prerequisites
- A pay-per-call platform that supports geo-routing rules (VeloCalls, Ringba, CallRail, or similar)
- A list of your buyers' actual service areas — ZIP codes, city names, or "X miles from our shop" radius
- Access to a ZIP-radius lookup tool (free ones work: zip-codes.com, unitedstateszipcodes.org)
- DMA boundary data if you're targeting media markets (Nielsen publishes the list; most platforms have it built in)
Step 1: Define Each Buyer's Service Area in Writing
Before you touch routing config, get explicit answers from each buyer.
Ask the right question. "What's your service area?" gets vague answers. "What's the farthest ZIP code you'll dispatch a tech to, and what's your average response time at that distance?" gets useful ones.
For a Phoenix HVAC contractor, the answer might be: "We'll go anywhere in Maricopa County, but response time past the I-101 loop is 90+ minutes. Prefer calls inside a 15-mile radius of our shop at 85016."
Document this for every buyer:
| Buyer | Primary Zone | Secondary Zone | Won't Service |
|---|---|---|---|
| Phoenix HVAC | 15-mile radius from 85016 | Maricopa County, outside primary | Outside Maricopa |
| Tucson Plumbing | Pima County | Santa Cruz County (emergency only) | Outside those counties |
| National Overflow | All US | N/A | N/A |
Why this matters: Routing logic built on guesses routes to the wrong places. A buyer who "covers Phoenix" might mean central Phoenix, or might mean the entire MSA. I've seen campaigns where the buyer's real service area was 12 ZIP codes and the campaign was targeting 400. Four months of burned spend before anyone noticed. The key to TCPA compliance starts with accurate service area documentation.
Look, this stuff isn't glamorous. Nobody gets excited about ZIP code spreadsheets. But getting this wrong costs real money — and I've sat in calls where operators realized they'd burned $15K on out-of-area leads because nobody asked the buyer to define "service area" in actual ZIP codes.
Step 2: Build Your ZIP-Radius Lists
Take each buyer's service area and convert it to an explicit ZIP code list.
For radius-based areas:
- Grab the central ZIP (the buyer's shop or dispatch location)
- Use a ZIP-radius lookup tool — punch in the center ZIP and the radius in miles
- Export the list of ZIPs whose centroids fall within that radius
- Audit the edges: ZIP boundaries are weird shapes, not circles, so you'll get partial overlaps
Example: A 20-mile radius from 85016 (central Phoenix) returns approximately 140 ZIP codes. A 25-mile radius bumps that to ~190. The marginal ZIPs at the edge are where you need to decide: include them (risk of edge-case calls to far locations) or exclude them (risk of rejecting valid calls).
My take: include edge ZIPs in the primary zone, but flag them for monitoring. If callbacks from edge ZIPs show high cancel rates or dispatch complaints, move them to secondary. Your mileage may vary — some buyers get weirdly territorial about edge ZIPs and you'll spend more time arguing than it's worth.
For county or DMA-based areas:
DMAs are county-based. The Phoenix DMA (market #11) covers Maricopa, Pinal, Yavapai, La Paz, and parts of Gila counties. If your buyer thinks in DMA terms — usually because they're matching TV or radio buys — use the DMA as your zone.
VeloCalls and Ringba both have DMA targeting built in. CallRail requires you to upload a custom ZIP list for DMA-equivalent coverage.
What you should have now: A spreadsheet with one sheet per buyer, listing every ZIP code in their primary and secondary zones. Export this to CSV — you'll upload it to your routing platform.
(Yes, a spreadsheet. In 2026. I know.)
Step 3: Configure Primary Zone Routing
This is the "caller is in our sweet spot, route to the local buyer" logic.
In your platform's routing config:
IF caller_zip IN [buyer_primary_zone_list]
THEN route_to("Local Buyer")
In VeloCalls, you upload the ZIP list to a "Geo Zone" object, then reference that zone in your routing node. The visual IVR builder makes this drag-and-drop — create a geo-filter node, attach the zone, wire it to the buyer.
On Ringba, you build this as a geo-filter in your routing plan. CallRail's geo-routing is state and metro only unless you use their custom-rules add-on.
Layer on additional filters. ZIP match alone isn't enough — just like filtering bot traffic from your ads matters before calls arrive. Combine with:
- Business hours check (don't route to a closed buyer)
- Capacity check (don't route if the buyer's already on 3 concurrent calls)
- Day-of-week check (some buyers only take weekend calls for premium)
IF caller_zip IN [Phoenix_HVAC_primary]
AND current_time(America/Phoenix) BETWEEN 07:00 AND 18:00
AND buyer.available = TRUE
THEN route_to("Phoenix HVAC")
What you should see: Test calls from ZIPs inside the primary zone routing to the local buyer. Test calls from ZIPs outside the zone not routing to them. Place real test calls; don't just trust the preview.
Step 4: Configure Secondary Zone and Overflow
Callers in the buffer zone (outside primary, inside secondary) need somewhere to go. So do callers completely outside all zones.
Secondary zone routing:
IF caller_zip IN [buyer_secondary_zone_list]
AND NOT caller_zip IN [buyer_primary_zone_list]
THEN route_to("Regional Overflow")
The secondary buyer might be the same company's second location, a partner contractor, or a regional aggregator who buys fringe-area calls at lower payout.
Out-of-area routing (three options):
-
Route to national overflow buyer. If you have a buyer who'll take any-US calls at reduced payout ($25 instead of $65), send them here. Good for monetizing traffic you'd otherwise waste.
-
Route to voicemail with callback. "We don't currently service your area, but leave a message and we'll call back if our coverage expands." Low conversion, but captures intent data.
-
IVR exit with referral. "We don't service [caller's area]. For a contractor near you, try HomeAdvisor or search '[service] near me.'" Sounds weird, but some operators do this to avoid burning brand goodwill on calls they can't fulfill.
What this looks like in a full routing chain:
Route Priority:
1. Primary Zone → Phoenix HVAC (if available)
2. Secondary Zone → Regional Overflow (if Phoenix closed or unavailable)
3. Out of Area → National Overflow (if caller is outside AZ entirely)
4. No Match → IVR Exit Message
Never let a call route to nowhere. Even a polite "we can't help you" is better than ringing into the void.
Strong opinion: Option 3 (the honest IVR exit) is underrated. Most operators hate "wasting" a call, but sending someone to a buyer who can't help them burns trust faster than admitting you don't service their area.
Step 5: Capture ZIP at Call Start (Optional but Recommended)
For campaigns where routing accuracy matters more than call speed — legal intake, home services dispatch, insurance — capture the caller's ZIP in the IVR before routing.
IVR prompt: "To connect you with a local specialist, please enter your 5-digit ZIP code."
This takes 8-12 seconds. In exchange, you get caller-stated location instead of guessing from area code.
Why this matters: Area code lookup fails for ported mobile numbers. A Phoenix resident with a Chicago 312 number shows up as Illinois. IP geolocation only works for web-originated calls. Asking the caller is the only way to know for certain where they need service.
VeloCalls captures DTMF ZIP input and passes it to the routing engine as caller_input_zip. You can then build rules like:
IF caller_input_zip IN [Phoenix_primary_zone]
THEN route_to("Phoenix HVAC")
ELSE IF caller_input_zip IN [Tucson_primary_zone]
THEN route_to("Tucson Plumbing")
ELSE
route_to("National Overflow")
The tradeoff: 10 seconds of IVR time. On a high-volume campaign, this adds up. On a campaign where misroutes cost $65 each, it pays for itself fast.
The frustrating part? You'll still get callers who enter 00000 or mash random digits. Humans gonna human. Build in a retry prompt and a fallback — you can't engineer your way out of user error entirely.
For the landing page side of geo-targeting, JustAnalytics can pass visitor ZIP through to your click-to-call widget — capturing location before the call even starts.
Step 6: Monitor and Adjust Zone Boundaries
Geo-targeting isn't set-and-forget. Service areas change. Buyers expand. Response time complaints surface.
Weekly audit (first 30 days):
- Pull a report of calls by ZIP code
- Flag ZIPs with high return rates, long talk time but no conversion, or buyer complaints about distance
- Move problem ZIPs from primary to secondary, or from secondary to out-of-area
Monthly review (ongoing):
- Ask buyers: "Any ZIPs we're sending you that you can't actually service?"
- Check close rates by geo-zone. If secondary zone close rates drop below 50% of primary zone, tighten the boundary.
- Compare buyer feedback against caller-entered ZIP vs. area-code-inferred ZIP. If area-code callers from certain codes are consistently misrouted, add explicit ZIP capture for those area codes.
DMA shifts: Nielsen updates DMA boundaries annually. If you're using DMA targeting, check for county reassignments every January. (Ask me how I learned this the hard way. Actually, don't.)
For campaigns with click-fraud exposure — where fake clicks inflate traffic before calls arrive — ClickzProtect handles the pre-call ad fraud layer. Geo-targeting won't help if the traffic is fake in the first place.
Common Errors and How to Fix Them
Error: Caller entered invalid or non-existent ZIP
Cause: Typo, fat-fingered input, or international caller entering a postal code.
Fix: Validate ZIP format (5 digits, numeric). Prompt retry on invalid input: "That ZIP code wasn't recognized. Please enter your 5-digit ZIP code again." After two failures, fall back to area-code routing or send to overflow.
Error: Edge-zone callers routed to primary buyer who can't service them
Cause: ZIP centroid inside radius, but ZIP boundary extends well outside.
Fix: Audit edge ZIPs quarterly. ZIPs like 85087 (New River, AZ) have centroids that suggest Phoenix proximity but actual addresses 45+ miles from central Phoenix. Move these to secondary or add a confirmation step: "You're calling from [ZIP]. Just to confirm, you need service in the Phoenix metro area?"
Error: Calls routing to national overflow when local buyer is available
Cause: Caller's area code doesn't match their actual location (ported number), and the platform defaulted to area-code geo.
Fix: Prioritize caller-entered ZIP over area code in your routing logic. If you're not capturing ZIP, at minimum add IP geolocation for web-originated calls as a second signal before falling back to area code.
Error: DMA targeting includes unwanted counties
Cause: DMAs are county-based, and some DMAs span 100+ miles. The Phoenix DMA includes La Paz County, which is 180 miles from Phoenix proper.
Fix: Use DMA for broad targeting, then layer ZIP-radius exclusions on top. Or skip DMA entirely and build explicit ZIP lists for each buyer.
Next Steps
You've got ZIP-radius and DMA targeting wired up, overflow routing in place, and (ideally) caller ZIP capture at IVR start.
Add capacity-based routing. Once a buyer's on 3 concurrent calls, route new calls to the next buyer in the chain instead of queueing. VeloCalls handles this via concurrency caps in buyer profiles; Ringba has similar settings. See route calls by caller location for the full setup — that post covers runtime routing where this one covered campaign targeting. For tracking your web traffic before it converts to calls, JustBrowser helps with session attribution.
Layer on conversion weighting. After 30+ days of close data, weight routing toward buyers who close at higher rates within their zones. A buyer closing 28% of primary-zone calls should get more volume than one closing 14%.
Build a quality scorecard by geo-zone. Track pickup time, talk time, and booking rate by ZIP grouping. Publish monthly. Zones with consistently low booking rates either have bad traffic (publisher problem) or bad buyers (routing problem). Figure out which.
For more on IVR design and routing optimization, see the home services playbook and fixing low answer rates.
Frequently Asked Questions
What's the difference between ZIP radius targeting and DMA targeting?
ZIP radius draws a circle around a central point and includes all ZIP codes whose centroid falls within that radius — good for service-area contractors who say "we cover 25 miles from the shop." DMA targeting uses Nielsen's designated market areas, which are county-based media market boundaries — better for matching ad buys and for buyers who think in metro terms. Use ZIP radius for tight local coverage, DMA for metro-wide campaigns.
How do I handle callers who fall just outside my buyer's service area?
Build an overflow chain. Callers inside the primary zone go to the local buyer. Callers in a buffer zone (say, 5 miles past the radius edge) hit a secondary regional buyer or queue for callback. Callers clearly outside both zones route to a national overflow buyer at lower payout — or get a polite IVR message explaining you don't service their area. Never black-hole a call without routing somewhere.
Should I use caller ZIP or area code for geo-targeting?
Caller-entered ZIP code is most accurate — the caller tells you where they need service. Area code is a fallback but breaks for ported mobile numbers (10-15% error rate). IP geolocation works for web-originated calls but not for direct dials. For local service-area campaigns, capture ZIP in the IVR; the extra 10 seconds of call time beats misrouting 1 in 8 calls.
How many ZIP codes are typically in a 25-mile radius?
Depends on density. In Phoenix, a 25-mile radius from downtown covers roughly 180-220 ZIP codes. In rural Montana, the same radius might hit 15-30. Use a ZIP-radius lookup tool to generate the list, then audit it — ZIP boundaries don't respect circles, so you'll get partial overlaps. Err on the side of inclusion for edge ZIPs, with a secondary check if volume matters.
Try VeloCalls for Your Vertical
AI calling + pay-per-call platform built for HVAC, plumbing, roofing, PI lawyers, Medicare brokers, and insurance. Smart routing, real-time bidding, visual IVR builder, AI conversation intelligence. Per-minute pricing — Managed starts at 4¢/min, BYOC at 2¢/min, both drop as you scale.