What is Least-Cost Routing?
Least-cost routing (LCR) automatically selects the cheapest available route for outbound calls. Costs vary by:
- Terminating carrier — Different rates for Verizon vs. AT&T vs. T-Mobile
- Line type — Mobile termination often costs more than landline
- Geography — Some regions have higher termination costs
- Time of day — Peak vs. off-peak pricing
Why Carrier Lookup Matters
You can't do LCR based on area code alone because 30%+ of phone numbers have been ported to different carriers. For example:
- A 212 (NYC) number might have been ported to T-Mobile from AT&T
- A 415 (SF) number might now be served by a VoIP provider
- Only LRN lookup tells you the current carrier
Get accurate carrier data. LRN lookup shows the current carrier, not the original.
Get Free API KeyHow LCR Works
1. Carrier Identification
# Before routing, identify the terminating carrier
result = veriroute_lookup(destination_phone, lrn=True)
carrier = result['lrn']['carrier'] # "Verizon Wireless"
ocn = result['lrn']['ocn'] # "6006"
2. Rate Table Lookup
# Look up rates by carrier/OCN
rate_table = {
"6006": {"provider_a": 0.008, "provider_b": 0.009}, # Verizon
"6529": {"provider_a": 0.007, "provider_b": 0.008}, # T-Mobile
"6664": {"provider_a": 0.009, "provider_b": 0.007}, # AT&T
}
3. Route Selection
# Select lowest-cost route
def get_best_route(ocn):
rates = rate_table.get(ocn, default_rates)
return min(rates, key=rates.get)
Implementation Patterns
Real-Time LCR
Look up carrier before each call:
- Pros: Always accurate, handles recent ports
- Cons: Adds latency, per-lookup cost
- Best for: High-value calls, low volume
Batch Pre-Lookup
Pre-populate carrier data for your contact database:
- Pros: No real-time latency, lower cost
- Cons: Data may be stale for recent ports
- Best for: High volume, campaign dialing
Hybrid Approach
def get_carrier_for_routing(phone):
# Check cache first
cached = get_cached_carrier(phone)
if cached and cached.age < 30_days:
return cached.carrier
# Real-time lookup for uncached or stale
result = veriroute_lookup(phone, lrn=True)
cache_carrier(phone, result['lrn'])
return result['lrn']['carrier']
Balancing Quality and Cost
The cheapest route isn't always the best. Consider:
Quality Factors
- Audio quality — Some routes have compression artifacts
- Latency — More hops = more delay
- Reliability — Some providers have better uptime
- Caller ID handling — Will your CNAM pass through?
Quality-Weighted LCR
# Factor in quality scores
def get_best_route(ocn):
routes = available_routes.get(ocn, [])
def score(route):
cost = route.rate
quality = route.quality_score # 0-1
return cost / quality # Lower is better
return min(routes, key=score)
Using OCN for Routing
Use OCN (Operating Company Number) instead of carrier name for reliable matching:
- Carrier names vary ("Verizon Wireless" vs "Verizon")
- OCN is always consistent (4-character code)
- Build rate tables keyed by OCN
Best Practices
- Always use LRN lookup — Don't trust area codes
- Cache carrier data — Reduce lookup costs
- Use OCN for matching — More reliable than names
- Update rate tables regularly — Carrier rates change
- Monitor quality metrics — Don't sacrifice quality for cost
- Have fallback routes — When preferred route fails