AgentSIMOTP sessions for agents
← Blog
6 min read

Why WhatsApp Blocks VoIP Numbers — and What AI Agents Should Use Instead

Understand why WhatsApp and other strict platforms reject programmable numbers, and how AgentSIM fits agent-driven auth testing for flows you own.


If you're building AI agents that need SMS-based OTP handling, you've likely seen this from WhatsApp:

Unsupported phone numbers, such as VoIP, landlines, and premium rate numbers

This post explains exactly why platforms like WhatsApp enforce that check, what it means for programmable numbers, and where AgentSIM genuinely fits in your stack.

How WhatsApp Classifies Phone Numbers

WhatsApp's official FAQ is explicit:

"Unsupported phone numbers, such as VoIP, landlines, and premium rate numbers, are not eligible for registration."

Unlike some platforms that reject silently, WhatsApp surfaces the reason. Their verification pipeline performs:

  1. Carrier database lookup — Checks LERG/NPAC for line type classification
  2. HLR query — Verifies active mobile network registration against a real carrier
  3. Historical abuse check — Numbers with prior spam history are permanently blocked
  4. Country-carrier validation — Number must belong to a carrier operating in the declared country

Why WhatsApp Is This Strict

WhatsApp is the primary communication platform in 180+ countries. They block VoIP and programmable numbers because:

  • Spam prevention: Non-mobile number ranges are statistically far more likely to be used for bulk abuse
  • Identity verification: Each WhatsApp account is meant to map to one real person or business
  • Carrier agreements: Meta has direct relationships with mobile carriers worldwide; those relationships depend on preserving that mapping

The Hard Truth: Programmable Numbers Don't Pass This Gate

The check WhatsApp runs is against the line-type classification in LERG/NPAC and the HLR response. A programmable number — from Twilio, Vonage, Bandwidth, or AgentSIM — does not have a real mobile carrier registration. It will be classified accordingly.

ProviderWhatsApp ResultWhy
Twilio❌ BlockedProgrammable number, VoIP line type
Vonage❌ BlockedProgrammable number, VoIP line type
Google Voice❌ BlockedProgrammable number, VoIP line type
Bandwidth❌ BlockedProgrammable number, VoIP line type
AgentSIM❌ Not reliableProgrammable number, same classification

AgentSIM is a programmable US number service. It provisions temporary numbers via API — the same category that WhatsApp's checks are designed to reject. Do not rely on AgentSIM to register a WhatsApp Business account. If you need to pass WhatsApp's consumer registration, you need a real mobile-classified number from a consumer carrier.

What LERG / NPAC / HLR Actually Check

  • LERG (Local Exchange Routing Guide): Maps number prefixes to line type (mobile, landline, voip). Programmable number blocks appear as VoIP or non-mobile.
  • NPAC (Number Portability Administration Center): Tracks ported numbers; can expose the originating carrier class.
  • HLR (Home Location Register): A real-time query to the mobile carrier's database confirming an active SIM registration. Programmable numbers have no entry here — there is no SIM, no IMSI, no carrier registration.

This is why the error message specifically names VoIP: the classification is deterministic from these databases.

Where AgentSIM Actually Fits

AgentSIM is built for a different problem: AI agents and browser agents that need to handle SMS OTPs programmatically — for auth flows you own or for verified-compatible services.

It provisions temporary programmable US numbers, waits for SMS, parses the OTP, and releases the number — all via API, SDK, or MCP.

Best-fit use cases:

  • Testing your own app's login, 2FA, or signup flow in CI/QA
  • Browser-agent QA that needs to complete an OTP step in a controlled environment
  • Staging and pre-production auth workflows where you control the sending side
  • Services on the verified-compatible list — acceptance is empirical and varies by service

Install

pip install agentsim-sdk

OTP Session for an Auth Flow You Own

import agentsim
import asyncio
 
agentsim.configure(api_key="asm_live_xxx")
 
async def test_signup_otp():
    async with agentsim.provision(
        agent_id="ci-signup-test",
        country="US"
    ) as num:
        print(f"Provisioned number: {num.number}")
 
        # Trigger your own app's OTP send to this number
        await your_app_send_otp(phone_number=num.number)
 
        # Wait for the OTP to arrive
        otp = await num.wait_for_otp(timeout=120)
        print(f"OTP received: {otp.otp_code}")
 
        # Complete the flow
        await your_app_verify_otp(code=otp.otp_code)
 
        print("Auth flow verified!")
    # Number auto-released after context exit
 
asyncio.run(test_signup_otp())

With Playwright (Browser-Agent QA)

import agentsim
from playwright.async_api import async_playwright
 
agentsim.configure(api_key="asm_live_xxx")
 
async def run_browser_agent_otp():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
 
        # Navigate to your app or a verified-compatible service
        await page.goto("https://your-app.example.com/signup")
 
        async with agentsim.provision(
            agent_id="browser-agent-qa",
            country="US"
        ) as num:
            await page.fill('[name="phone"]', num.number)
            await page.click('button:has-text("Send code")')
 
            # Wait for the OTP to arrive
            otp = await num.wait_for_otp(timeout=120)
 
            await page.fill('[name="code"]', otp.otp_code)
            await page.click('button:has-text("Verify")')
 
        await browser.close()

With MCP (Claude Code / Cursor / Windsurf)

{
  "mcpServers": {
    "agentsim": {
      "url": "https://mcp.agentsim.dev/mcp",
      "headers": {
        "Authorization": "Bearer asm_live_xxx"
      }
    }
  }
}

Delivery Diagnostics

If no OTP arrives, AgentSIM exposes the raw messages for the session so you can classify the outcome — rather than guessing whether it was a parser failure, a rejected number, or an anti-bot gate:

OutcomeWhat get_messages shows
OTP receivedParsed otp_code in the payload
SMS received, no OTPRaw message body for inspection
No SMS at allEmpty — service likely rejected the number before sending
Anti-bot gateDelivery logs show rejection at the service side

Check the supported services map before relying on AgentSIM for a specific third-party target. Acceptance is empirical — not guaranteed.

The Honest Summary

SituationRight tool
Testing your own app's OTP flow✅ AgentSIM
CI/QA for browser agents✅ AgentSIM
Verified-compatible third-party OTP✅ AgentSIM (check support map)
WhatsApp Business registration❌ Needs a real mobile-classified number
Stripe / Google / bank consumer signup❌ Programmable numbers not reliable

For flows you own, for CI/QA, and for verified-compatible targets, AgentSIM gives agents a programmable US number with parsed OTP delivery and raw-message diagnostics. For strict consumer-platform signups that require a mobile-classified number — WhatsApp, Stripe, Google, banks — programmable numbers including AgentSIM are not the right tool.

Get Started