VoIP vs Real SIM: How Carrier Lookup Works and What It Means for Your AI Agent
Deep technical comparison of VoIP and real SIM numbers. LERG/NPAC database analysis, how services detect and block VoIP numbers, and where programmable numbers fit in agent workflows.
Every week, a developer posts on Stack Overflow or Reddit: "My Twilio number gets rejected at Stripe/WhatsApp/Amazon." The answer is always the same — VoIP numbers fail carrier lookup. But why?
This is the deep technical explanation of how carrier detection works, what databases are involved, and what that means for AI agent workflows that need phone verification.
The Carrier Lookup Infrastructure
When a service like Stripe verifies your phone number, it doesn't just check a blocklist. It queries a chain of authoritative databases:
LERG (Local Exchange Routing Guide)
The LERG is the master database of North American phone numbers. Maintained by iconectiv (formerly Telcordia), it maps every NPA-NXX (area code + exchange) to:
- Operating Company Number (OCN) — Who owns this number block
- Line type — Mobile, landline, VoIP, toll-free
- Rate center — Geographic location
- LATA — Local Access and Transport Area
When Twilio buys a block of numbers from Bandwidth, those numbers are registered in LERG under Bandwidth's OCN with line_type voip. This is permanent and public.
NPAC (Number Portability Administration Center)
NPAC tracks ported numbers. If a number was originally Verizon mobile but got ported to a VoIP provider, NPAC records this. Services that do deep verification check NPAC to see if a mobile number was ported to a VoIP provider.
HLR (Home Location Register)
The HLR is the real-time database on each carrier's network. When you query a T-Mobile number via HLR, it returns:
- Whether the number is currently registered on the network
- The IMSI (International Mobile Subscriber Identity)
- The serving MSC (Mobile Switching Center)
- Roaming status
VoIP numbers don't exist in any HLR — they route through internet gateways, not cell towers.
How Services Use This Data
Stripe's Approach
1. Receive phone number
2. Query LERG → Get OCN and line_type
3. If line_type = "voip" → REJECT
4. If line_type = "mobile" → Query HLR for active registration
5. If HLR active → SEND SMS
Google's Approach (More Aggressive)
1. Receive phone number
2. Query LERG → Get carrier and line_type
3. If line_type = "voip" → REJECT
4. If carrier is known VoIP provider → REJECT
5. Query HLR → Check active mobile registration
6. Check behavioral patterns (creation velocity, geo-consistency)
7. If all checks pass → SEND SMS
WhatsApp's Approach (Strictest)
1. Receive phone number
2. Query LERG + NPAC for current carrier
3. Check against WhatsApp's internal VoIP blocklist
4. Query HLR for active mobile registration
5. Check number history (spam reports, previous bans)
6. If all checks pass → SEND SMS
Why VoIP Numbers Are Detectable
It's not just about databases. VoIP numbers have fundamental technical differences:
Network Topology
- Mobile: Phone → Cell tower → MSC → SMS Center → Delivery
- VoIP: API call → Internet → SIP gateway → SMS aggregator → Delivery
The routing path is different. Services can detect SIP gateways in the delivery chain.
Number Allocation
- Mobile carriers get number blocks directly from regulators
- VoIP providers lease from wholesale carriers (Bandwidth, Peerless)
- LERG records who owns each block — this is public information
Registration Status
- Mobile: Continuously registered with a cell tower via SIM card
- VoIP: No network registration. Numbers exist only in software databases
VoIP vs Real SIM: Technical Comparison
| Characteristic | VoIP Number | Real SIM Number |
|---|---|---|
| LERG line_type | voip or nonFixedVoip | mobile |
| HLR registration | ❌ None | ✅ Active on tower |
| Carrier in LERG | Twilio/Bandwidth/Vonage | T-Mobile/AT&T/Verizon |
| Physical SIM card | ❌ No | ✅ Yes |
| Cell tower connection | ❌ No | ✅ Yes |
| IMSI on network | ❌ No | ✅ Yes |
| SMS routing | Internet → SIP gateway | Carrier SMS Center |
| Strict consumer platform verification | ❌ Blocked before SMS | ✅ Passes carrier lookup |
┌─────────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐
│ Service │────▶│ LERG │────▶│ NPAC │────▶│ HLR │────▶│ Accept or │
│ (Stripe, │ │ Lookup │ │ Check │ │ Query │ │ Reject │
│ WhatsApp, │ │ │ │ │ │ │ │ │
│ Google) │ │ carrier? │ │ ported? │ │ active? │ │ VoIP → ❌ │
│ │ │ type? │ │ to VoIP? │ │ on tower?│ │ Mobile → ✅ │
└─────────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────────┘
What This Means for Strict Consumer Platforms
If a reader needs to pass Stripe, Google, WhatsApp, Meta, Amazon, or bank verification as a consumer — those platforms require a real, mobile-classified number with active HLR registration. A genuine mobile SIM is the right tool for that scenario.
Programmable numbers (from any CPaaS provider — Twilio, Bandwidth, or AgentSIM) are blocked at the LERG or HLR step on those platforms. That's not a bug to work around; it's intentional fraud prevention.
Where AgentSIM Fits: Programmable Numbers for Agent Workflows
AgentSIM is a programmable US number API built for AI agent and CI/QA workflows. It provisions temporary numbers, waits for SMS, parses OTPs, and releases the session — all via API or MCP. The numbers are VoIP-class (not mobile-classified), which means they're the wrong tool for strict consumer-platform signups but the right tool for a different set of problems:
Good fits:
- Auth flows you own — testing your own app's login, 2FA, or signup pipeline
- CI / QA automation — SMS verification steps in automated test suites
- Browser-agent QA — agents navigating signup flows for services you control
- Verified-compatible targets — services empirically known to accept programmable numbers (check the support map)
Not a good fit:
- Consumer signup for Stripe, Google, WhatsApp, Meta, Amazon, banks, or any platform that runs LERG/HLR checks and requires a mobile-classified number
import agentsim
agentsim.configure(api_key="asm_live_xxx")
async with agentsim.provision(agent_id="my-agent", country="US") as num:
print(num.number) # +14155552671
# Trigger the SMS in your app or a verified-compatible service,
# then wait for the OTP to arrive
otp = await num.wait_for_otp(timeout=60)
print(otp.otp_code) # "391847"
# Auto-releasedMCP Integration
{
"mcpServers": {
"agentsim": {
"url": "https://mcp.agentsim.dev/mcp",
"headers": {
"Authorization": "Bearer asm_live_xxx"
}
}
}
}The Bottom Line
VoIP detection isn't going away. It's getting more sophisticated as fraud scales. For strict consumer platforms that demand a mobile-classified number, a real mobile SIM is the only reliable path — programmable numbers, including AgentSIM, won't clear those gates.
For flows you own, CI/QA, browser-agent testing, and verified-compatible targets, AgentSIM gives agents a programmable US number with parsed OTP and delivery diagnostics — without the overhead of managing physical SIMs.
- Install:
pip install agentsim-sdk - Try it: agentsim.dev — 10 free sessions/month
- Docs: docs.agentsim.dev
- Support map: docs.agentsim.dev/supported-services
- GitHub: github.com/agentsimdev