AgentSIMReal numbers for AI agents
← Blog
25 min read

Why Your AI Agent's Phone Number Gets Blocked (And How to Fix It)

A technical deep-dive into carrier lookup APIs, LERG/NPAC/OCN databases, VoIP classification, and how to get a real mobile number your agent can actually use for SMS verification.


You built an AI agent that onboards to a new service, creates an account, fills in a form, and gets all the way to SMS verification — then hits a wall.

"This phone number cannot be used for verification."

Or worse: the code is never sent and no error appears at all. Your agent just sits there waiting.

This is the VoIP blocking problem. It affects every AI agent that needs a real phone identity, and it's getting worse as fraud rates on virtual numbers rise. This guide explains exactly what's happening, why every major service blocks VoIP numbers, and what the working alternatives are.


The Problem: VoIP Numbers Fail Production Verification

Most developers building phone-capable AI agents reach for the obvious choices: Google Voice, TextNow, Twilio programmable numbers, Telnyx, or Vonage. These are cheap, API-accessible, and work fine in development. They fail in production.

The services your agent needs to verify with — Stripe, Amazon, WhatsApp, Microsoft, financial institutions — all run carrier lookup checks before sending verification codes. If the lookup returns nonFixedVoip or fixedVoip, the request is rejected. The code is never sent.

Here's the list of confirmed blockers, with the evidence:

ServiceBlock TypeUser-Facing Message
StripeHard error"This phone number cannot be used for verification"
AmazonSilent delivery failureCode simply never arrives
WhatsAppHard error"Unsupported phone numbers, such as VoIP, landlines..."
Microsoft Entra IDRisk-based blockError 399287 "BadReputation"
VercelHard block at signupRegistration rejected
DocuSignHard block at signupRegistration rejected
Banks (BMO and others)Silent or misleadingCodes not delivered, vague errors

VoIP number rejected vs AgentSIM mobile number accepted by carrier check

These aren't edge cases. They're deliberate product decisions backed by fraud data, and the blocking is accelerating.

A fintech security professional on Hacker News described Stripe's logic directly:

"We reject VoIP phone numbers due to proven fraud activity. VoIP numbers can be obtained with no identity verification, recycled instantly after use, and are disproportionately associated with account takeover attempts."

WhatsApp's official FAQ states it explicitly:

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

Microsoft's documentation lists VoIP support status plainly:

"Phone extensions and VOIP numbers are not supported for MFA."

For AI agent developers, this creates a hard requirement: your agent needs a number that carrier lookup APIs classify as mobile, not voip. Understanding how that classification works is the first step to solving it.


How Carrier Lookup Works: The Technical Infrastructure

When Stripe, WhatsApp, or Amazon receives a phone number for verification, they don't just check a blocklist. They query a carrier lookup API that interrogates multiple interconnected telecom databases. Here's how the chain works.

Step 1: Parse NPA-NXX

Every US phone number in E.164 format starts with the country code (+1), followed by a 10-digit number. The first 6 digits — the NPA (Numbering Plan Area, aka area code) and NXX (exchange code, aka the first 3 of the 7-digit local number) — form the lookup key.

For example, +14155551234: NPA = 415, NXX = 555.

Step 2: Query the LERG

The Local Exchange Routing Guide (LERG) is a database published by iconectiv, the FCC-designated North American Numbering Plan Administrator. It maps every NPA-NXX block to an Operating Company Number (OCN).

The LERG contains multiple tables:

  • LERG1 — OCN information including carrier name, type, and state
  • LERG6 — NPA NXX assignments (which carrier owns which blocks)
  • LERG7 — Switch data
  • LERG12 — LRN (Location Routing Number) assignments

The OCN lookup tells you which carrier was originally assigned the number block.

Step 3: Check NPAC for Porting

Number portability changed everything. Under FCC LNP (Local Number Portability) rules, any US number can be ported from one carrier to another. The Number Portability Administration Center (NPAC), also operated by iconectiv, records every porting event.

When a number is ported, NPAC stores:

  • The current SPID (Service Provider ID)
  • The LRN (Location Routing Number) for routing
  • The porting date and history

The SPID is critical: it encodes the line type directly.

SPID Carrier TypeLine Type
Type 0Wireline (ILEC)
Type 1Wireline (CLEC)
Type 2Wireless / Mobile
Type 3VoIP

SPID carrier type breakdown: Type 2 mobile passes, Type 3 VoIP is blocked

If NPAC shows a porting event and the current SPID has carrier type 3, the number is VoIP — even if the original LERG assignment was to a mobile carrier.

Step 4: Look Up OCN Type

Each OCN has a carrier type classification assigned by the FCC:

  • ILEC — Incumbent Local Exchange Carrier (traditional landline providers: AT&T, Verizon wireline)
  • CLEC — Competitive Local Exchange Carrier (alternative wireline providers)
  • WIRELESS — Mobile Network Operators (AT&T Mobility, T-Mobile, Verizon Wireless)
  • VOIP — Voice over IP providers (Google Voice, Twilio, Bandwidth, Lingo)
  • CABLE — Cable companies offering phone service (Comcast Xfinity, Cox)

Step 5: Classify and Return

The carrier lookup API combines the LERG OCN type and the NPAC porting data:

if current_spid_type == 3 → VoIP (ported to VoIP)
else if ocn_type == WIRELESS → mobile
else if ocn_type == VOIP → VoIP (never ported)
else if ocn_type == ILEC/CLEC/CABLE → landline

How carrier lookup classifies a number: Phone Number → LERG → NPAC → SPID type → mobile or VoIP

The result propagates into two major sub-categories for VoIP:

fixedVoip — VoIP numbers tied to a specific physical location or device. Examples: Comcast Business Voice, enterprise PBX systems, some CLEC offerings. These require a physical installation at a premises address. They're considered more legitimate and some services allow them.

nonFixedVoip — VoIP numbers that can be obtained online with no physical address or device requirement. Examples: Google Voice, TextNow, Vonage, Twilio programmable numbers, Telnyx numbers. These can be created with a credit card, no identity verification, and cancelled instantly. This is the category most aggressively blocked.

Additional Signals

Beyond the core LERG/NPAC/OCN chain, carrier lookup APIs may also query:

  • HLR (Home Location Register) — Mobile carrier subscriber databases. A failed HLR lookup for a supposedly mobile number is a strong VoIP indicator.
  • CNAM databases — Caller Name databases. VoIP numbers frequently show unusual or generic names.
  • ANI/SS7 Information Digits — In real-time call signaling, Information Digits classify the call origin. VoIP calls carry digit codes that differ from mobile calls.
  • Proprietary fraud databases — IPQS, Telesign, and others maintain additional lists of numbers with fraud history.

The Carrier Lookup API Ecosystem

There are eight major APIs developers use to perform carrier lookup. Understanding their differences helps you predict how the services your agent needs to verify with are classifying your numbers.

APIProviderPricingLine Type FieldNotes
Twilio LookupTwilio$0.008/req ($0.00385 volume)line_type_intelligence.type: landline, mobile, fixedVoip, nonFixedVoip, personal, tollFree, premium, unknownIndustry standard; real-time NPAC; Stripe and Vercel use this
Telnyx Number LookupTelnyxPay-as-you-go; free tiercarrier.type: voip, mobile, landline + OCN, SPID, LRN, ported_statusExposes raw OCN/SPID data; good for debugging
IPQS Phone ValidationIPQualityScoreFree tier + volumeVOIP (boolean) + line_type: mobile, landline, VoIP, prepaid + fraud_score (0–100)Includes fraud scoring; claims 99%+ accuracy
Vonage Number InsightVonage (Ericsson)Tiered: Basic/Standard/Advancednetwork_type: mobile, landline, virtual, unknown, pager"Virtual" maps to VoIP; Vonage uses it to block VoIP on their own platform
Abstract Phone ValidationAbstractAPIFree 250/mo → tiered paidphone_carrier.line_type: Wireless, Landline, VOIP + is_voip booleanGood free tier; 190+ countries
NumverifyapilayerFree 100/mo → $9.99–$99.99/moline_type: mobile, landline, special_servicesNo dedicated VoIP type; limited granularity
Ekata Phone IntelligenceEkata (Mastercard)Enterprise/customCarrier info, prepaid check, validity, velocity200M+ monthly queries; enterprise fraud context
Telesign Phone IDTelesign (TransUnion)Pay-as-you-go; free trialphone_type: landline, mobile, VoIP + carrier name, registration statusTransUnion identity network; banks and fintech use this

Code Example: Running Your Own Carrier Lookup

Before building anything, verify how your number is classified. Here's how to query Twilio's API directly:

from twilio.rest import Client
 
client = Client(account_sid, auth_token)
 
phone_number = client.lookups.v2.phone_numbers("+14155551234").fetch(
    fields="line_type_intelligence"
)
 
lti = phone_number.line_type_intelligence
print(f"Line type: {lti['type']}")          # e.g., "nonFixedVoip"
print(f"Mobile country code: {lti.get('mobile_country_code')}")
print(f"Mobile network code: {lti.get('mobile_network_code')}")
print(f"Error code: {lti.get('error_code')}")
import twilio from "twilio";
 
const client = twilio(accountSid, authToken);
 
const number = await client.lookups.v2
  .phoneNumbers("+14155551234")
  .fetch({ fields: "line_type_intelligence" });
 
const lti = number.lineTypeIntelligence;
console.log(`Line type: ${lti?.type}`);          // e.g., "nonFixedVoip"
console.log(`MCC: ${lti?.mobileCountryCode}`);
console.log(`MNC: ${lti?.mobileNetworkCode}`);

Run this on any number you plan to use with your agent. If you see nonFixedVoip or fixedVoip, that number will fail verification on Stripe, WhatsApp, and most financial services. Note: some services like Google apply additional behavioral and reputation checks beyond carrier lookup.


Why Every Major Service Blocks VoIP: Service-by-Service Breakdown

Stripe

Stripe's phone verification runs during identity verification (Stripe Identity), account security setup, and certain high-risk payment flows. The technical mechanism combines:

  1. Carrier lookup (Twilio Line Type Intelligence or equivalent)
  2. Rejection if line_type_intelligence.type is fixedVoip or nonFixedVoip
  3. Additional risk scoring: velocity checks, geographic mismatch between IP and carrier region, and number reputation

The error is explicit: "This phone number cannot be used for verification."

There's no workaround via retry or different country codes. The check is at the carrier level, not the number level. Using a different Twilio number won't help — all Twilio programmable numbers share the same OCN (Bandwidth, BW Communications, or similar CLEC/VoIP providers), and those OCNs are classified as VoIP.

A Hacker News thread from August 2025 surfaced detailed commentary from developers in fintech:

"Every major financial platform I've worked with blocks VoIP numbers. The fraud rate on VoIP-originated accounts is orders of magnitude higher than mobile-originated accounts. This isn't going to change — if anything it's getting stricter."

Google

Google's blocking is more nuanced and less consistent than Stripe's, which makes it harder to debug. The mechanisms include:

Line-type checking at account creation. New Google account registrations check carrier type. Numbers classified as nonFixedVoip fail with "Something went wrong" or "This number cannot be used for verification."

Carrier range blacklisting. Google maintains its own reputation database of carrier OCN ranges with abuse history. Even mobile numbers from certain prepaid carriers or MVNOs with high abuse rates get blocked.

eSIM complications. A March 2026 Reddit thread in r/GMail documented widespread blocking of Philippine eSIM numbers despite them technically registering as mobile. Google appears to apply additional geographic and carrier-origin checks beyond the basic line-type lookup.

Amazon OTPs stopped routing to Google Voice. As documented in Google Support forum posts from May 2024: "Amazon will no longer send OTP codes to Google Voice numbers." This means Amazon specifically targeted the Google Voice OCN range for SMS filtering.

Amazon

Amazon's blocking operates at the SMS routing layer through AWS SNS (Simple Notification Service), which Amazon uses to send OTP codes for its verification flows.

The mechanism is carrier-type filtering: SNS checks the carrier type of the destination number before routing. If the number is VoIP, the message is silently dropped. No error is returned to the sender, and no code arrives for the recipient.

For AI agents, this is the worst type of failure: the agent triggers the verification request, receives a success response from the API call, then waits indefinitely for a code that was discarded before it left Amazon's infrastructure.

The only way to detect this is a timeout — which is why services like AgentSIM return a carrier_retry_required status on timeout, allowing the agent to provision a different number rather than waiting indefinitely.

WhatsApp

WhatsApp's policy is explicit and documented. From their official FAQ:

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

The technical check happens at WhatsApp account registration. The carrier lookup is performed before the verification SMS is sent. VoIP numbers receive an immediate rejection error.

WhatsApp also blocks verification via short-code SMS to VoIP numbers as a secondary mechanism — even if a VoIP number somehow passed the initial registration check, the short-code routing would filter it.

For business automation use cases (WhatsApp Business API onboarding, managing multiple WhatsApp accounts), VoIP numbers are entirely unusable.

Microsoft Entra ID (Azure AD MFA)

Microsoft's multi-factor authentication blocks VoIP via error code 399287, classified as "BadReputation" in their carrier reputation database.

Microsoft Learn documentation (updated March 2026) is direct:

"Phone extensions and VOIP numbers are not supported for MFA."

Microsoft applies per-number reputation tracking, not just per-OCN classification. A number that passes carrier lookup as "mobile" but has been associated with fraud attempts on other Microsoft accounts may still receive a BadReputation score.

Reddit threads document developers failing MFA enrollment even with mobile numbers from certain high-fraud prepaid carriers.

Vercel and DocuSign

Both Vercel and DocuSign use Twilio Lookup's Line Type Intelligence directly in their onboarding flows. The code path is approximately:

register(phone) → lookup(phone).line_type_intelligence →
  if type in ["nonFixedVoip", "fixedVoip"] → reject("Invalid phone number")

This is straightforward to verify: register with a Google Voice number and the rejection is immediate. The same number used for Stripe verification also fails Vercel signup.

Banks and Financial Institutions

Banks present a more heterogeneous blocking landscape because each institution implements its own carrier check. The patterns are:

Silent blocking: The verification SMS is simply never sent. The bank's UI shows a spinner and eventually times out. No error message indicates the phone type issue. This is the most common pattern among US retail banks.

Misleading errors: BMO's documented case (Reddit r/PersonalFinanceCanada, February 2026): "BMO seems to have blocked 2FA verification from a landline VoIP number." The user received a generic error that didn't indicate the carrier type issue, making diagnosis difficult.

Post-enrollment blocking: Some banks validate at SMS routing time rather than at enrollment. This means an agent may successfully register a VoIP number, only to find that OTP codes are never delivered at login time.


Technical Alternatives: What Actually Works

Given that VoIP numbers fail, what are the realistic alternatives?

1. Physical SIM Cards

How it works: Physical SIM cards inserted in modems or smartphones. AT&T, Verizon, T-Mobile SIM cards register the OCN in LERG as WIRELESS. HLR lookups succeed. Carrier lookup returns mobile across all APIs.

Classification result: Mobile on 100% of carrier lookup APIs. Passes all verification services.

Problems for agents:

  • Requires physical hardware (SIM tray modems, smartphones)
  • $50–$80/month per number for a postpaid plan
  • No programmatic provisioning — you order a SIM, activate it, insert it
  • Scale is limited by hardware (each modem holds 1–4 SIMs)
  • High latency for receiving SMS (modem polling intervals, not API webhooks)

This is how AgentSIM works at the infrastructure layer. The difference is that AgentSIM operates this hardware at scale and exposes it via API, abstracting the SIM management from the developer.

2. eSIM (Embedded SIM)

How it works: eSIM profiles provisioned remotely via the SM-DP+ (Subscription Manager Data Preparation) protocol, as specified by GSMA's eUICC (Embedded Universal Integrated Circuit Card) standard. The device with the eSIM connects to the carrier's mobile network exactly like a physical SIM.

Classification result: Functionally identical to physical SIM for LERG/NPAC classification. The OCN is still the mobile carrier's OCN. Carrier lookup returns mobile.

Problems for agents:

  • Google has documented blocking eSIM numbers from certain carriers and regions (Philippines example above). The specific mechanism is unclear — Google may apply additional geographic or carrier origin checks.
  • Requires eSIM-capable hardware or eSIM management platform
  • Not all carriers support programmatic eSIM provisioning (most require consumer/enterprise agreements)
  • Some platforms may distinguish eSIM from physical SIM in their checks

eSIM is a promising direction for AI agent phone infrastructure, but the Google blocking pattern introduces uncertainty for high-stakes verifications.

3. MVNO Numbers

How it works: MVNOs (Mobile Virtual Network Operators) like Mint Mobile, Google Fi, Tracfone, Boost Mobile, and Cricket Wireless lease network capacity from the three major MNOs (AT&T, T-Mobile, Verizon). They assign numbers using OCNs that are registered as WIRELESS in LERG (since they ride mobile infrastructure).

Classification result: Generally classified as mobile by carrier lookup APIs. More affordable than direct MNO plans.

Problems for agents:

  • Some MVNO OCN ranges are specifically blacklisted by high-fraud services. If a particular MVNO is frequently used for fraud, Stripe, Google, or IPQS may add that OCN range to their reputation database.
  • Google Fi is particularly suspect because it supports VoIP calling over Wi-Fi. Some platforms treat Google Fi numbers as VoIP despite the mobile OCN.
  • No programmatic provisioning API — you still need physical or eSIM hardware.

4. Number Porting (VoIP to Mobile)

How it works: Under FCC Local Number Portability rules, any US number can be ported from one carrier to another. Porting a VoIP number to a mobile carrier reclassifies it in NPAC: the SPID changes from type 3 (VoIP) to type 2 (wireless), and the LRN changes to the mobile carrier's LRN.

Classification result: The number becomes mobile permanently. All carrier lookup APIs will return mobile after the porting is reflected in NPAC.

Problems for agents:

  • Takes hours to days to complete. FCC rules require porting within 2.5 hours for simple ports, but realistically it takes longer.
  • Requires accounts with both the source VoIP carrier and a destination mobile carrier.
  • The destination mobile carrier will require a phone with a SIM (or eSIM) to activate the ported number.
  • One-time operation — you can't port the same number back to VoIP and then re-port to mobile.

Number porting is a good solution for preserving a specific number you've already established a presence with. It's not practical for programmatic provisioning at scale.

5. Silent Network Authentication (SNA)

How it works: SNA is a carrier-level authentication mechanism that verifies phone number ownership using the SIM's authenticated data session. Instead of sending a code, the carrier validates that the device initiating the request is the same device with the SIM for the number being verified. This happens invisibly in 1–4 seconds.

Classification result: SNA requires a real mobile SIM and an active mobile data connection. It cannot be spoofed by VoIP numbers or any non-mobile network connection.

Problems for agents:

  • SNA works only when the device is on mobile data, not Wi-Fi.
  • Not all carriers and not all services support SNA yet.
  • Only works for verifying that a device has a specific SIM — it's an authentication mechanism, not a provisioning mechanism. Your agent still needs a real mobile number.

SNA is increasingly relevant for AI agent identity because it eliminates the OTP delivery problem entirely. When a service supports SNA, your agent can verify phone ownership without waiting for a code. AgentSIM is monitoring carrier SNA API availability for integration.

6. Real SIM Number APIs (The Programmatic Solution)

How it works: Services like AgentSIM operate physical SIM cards in carrier-connected modems, and expose those numbers via API. When you provision a number through the API, you get a real AT&T, T-Mobile, or Verizon mobile number — not a VoIP number, not an MVNO number, not a ported number. The SIM is physically present in a modem that receives SMS.

Classification result: mobile on all carrier lookup APIs. Passes Stripe, Google, Amazon, WhatsApp, Microsoft Entra, and bank verifications.

Why this matters for AI agents: The SIM is managed for you. No hardware to buy, no carrier contract to maintain, no SIM swap to orchestrate. Provision a number, receive an OTP via API webhook or long-poll, release the number when done. Three API calls.


AgentSIM: Real Mobile Numbers via API

AgentSIM is built specifically for this use case. Every provisioned number is backed by a physical SIM on a US carrier network. Carrier lookup returns mobile.

Quick Start

# Python
pip install agentsim
 
# TypeScript
npm install @agentsim/sdk
export AGENTSIM_API_KEY="asm_live_..."

Python: Complete OTP Flow

import agentsim
 
client = agentsim.AgentSimClient()
 
# 1. Provision a real mobile number
session = await client.provision(agent_id="stripe-onboarding", country="US")
print(f"Phone number: {session.number}")
# e.g. +14085551234 — carrier lookup returns "mobile"
 
# 2. Enter session.number into the service that will send the OTP
 
# 3. Wait for the OTP (blocks until received, up to 60s)
try:
    result = await session.wait_for_otp(timeout=60)
    print(f"OTP code: {result.otp_code}")
    # e.g. "847291"
 
except agentsim.OtpTimeoutError:
    # Carrier cold-start: swap to a fresh number on the same session
    print("Timeout — retry with new number")
 
finally:
    # 4. Always release the number when done
    await session.release()

TypeScript: Complete OTP Flow

import { provision, OtpTimeoutError, PoolExhaustedError } from "@agentsim/sdk";
 
async function verifyWithStripe() {
  // await using releases the number automatically on exit (TypeScript 5.2+)
  await using session = await provision({
    agentId: "stripe-onboarding",
    country: "US",
    ttlSeconds: 300,
  });
 
  console.log(`Phone number: ${session.number}`);
  // e.g. +14085551234 — carrier lookup returns "mobile"
 
  // Enter session.number into Stripe's phone verification...
 
  try {
    const otp = await session.waitForOtp({ timeout: 60 });
    console.log(`OTP: ${otp.otpCode}`);
    return otp.otpCode;
 
  } catch (err) {
    if (err instanceof OtpTimeoutError) {
      console.log("No OTP in 60s — carrier retry may be needed");
    } else if (err instanceof PoolExhaustedError) {
      console.log("No US numbers available");
    } else {
      throw err;
    }
  }
}

MCP Integration: OTP for Claude Code and Cursor

If you're using Claude Code, Cursor, or any MCP-compatible assistant, AgentSIM can provision numbers directly from the AI assistant's context:

{
  "mcpServers": {
    "agentsim": {
      "type": "streamable-http",
      "url": "https://mcp.agentsim.dev/mcp",
      "headers": {
        "x-api-key": "asm_live_..."
      }
    }
  }
}

Once configured, your assistant can call provision_number, wait_for_otp, and release_number autonomously — no human intervention required.

Handling Carrier Cold-Start Timeouts

US longcode numbers (10DLC) occasionally experience a "cold-start" filtering window where the first SMS to a new number is delayed or dropped by the sending carrier's abuse filters. This is a real carrier behavior, not a bug.

AgentSIM handles this automatically. When wait_for_otp times out with auto_reroute=True (the default), it provisions a replacement number on the same session and returns carrier retry instructions:

result = await session.wait_for_otp(timeout=60)
 
if result.get("status") == "carrier_retry_required":
    new_number = result["new_number"]
    print(f"Enter this new number instead: {new_number}")
    # Re-enter new_number on the target service
    result = await client.wait_for_otp(session_id=result["session_id"], timeout=60)

The session ID remains the same. The carrier retry is transparent from the agent's perspective.


Implementation Guide: Verifying Numbers Before Use

If you're building a service that accepts phone numbers and want to understand what your users are sending, here's how to run carrier lookup checks:

Python: Check Number Type Before Sending OTP

from twilio.rest import Client
 
def get_line_type(phone_number: str, account_sid: str, auth_token: str) -> str:
    """Returns the line type: mobile, landline, fixedVoip, nonFixedVoip, etc."""
    client = Client(account_sid, auth_token)
    number = client.lookups.v2.phone_numbers(phone_number).fetch(
        fields="line_type_intelligence"
    )
    lti = number.line_type_intelligence
    return lti.get("type", "unknown") if lti else "unknown"
 
def is_mobile(phone_number: str, account_sid: str, auth_token: str) -> bool:
    line_type = get_line_type(phone_number, account_sid, auth_token)
    return line_type == "mobile"
 
# Usage
phone = "+14155551234"
if not is_mobile(phone, TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN):
    raise ValueError(f"Phone number type must be mobile for verification")

TypeScript: Check Number Type with Multiple APIs

import Telnyx from "telnyx";
 
interface LineTypeResult {
  type: "mobile" | "landline" | "voip" | "unknown";
  carrier?: string;
  portedStatus?: "ported" | "not_ported";
}
 
async function getLineType(phoneNumber: string): Promise<LineTypeResult> {
  const telnyx = new Telnyx(process.env.TELNYX_API_KEY!);
 
  const result = await telnyx.numberLookup.retrieve(phoneNumber, {
    type: "carrier",
  });
 
  const carrier = result.data?.carrier;
  return {
    type: carrier?.type ?? "unknown",
    carrier: carrier?.name,
    portedStatus: carrier?.ported_status as "ported" | "not_ported" | undefined,
  };
}
 
async function requireMobileNumber(phoneNumber: string): Promise<void> {
  const { type, carrier, portedStatus } = await getLineType(phoneNumber);
 
  if (type !== "mobile") {
    throw new Error(
      `Phone number ${phoneNumber} is ${type} (${carrier ?? "unknown carrier"}). ` +
      `Mobile numbers required for verification.`
    );
  }
 
  if (portedStatus === "ported") {
    // Ported numbers can be mobile today but may have been VoIP before
    // Log for monitoring but don't reject
    console.log(`Note: ${phoneNumber} is a ported number`);
  }
}

Detecting Ported VoIP-to-Mobile Numbers

Number porting creates an interesting edge case: a number that was VoIP last month might be mobile today. Telnyx's API exposes porting history that you can use to flag potentially risky ported numbers:

import httpx
 
async def check_ported_status(phone: str, api_key: str) -> dict:
    async with httpx.AsyncClient() as client:
        r = await client.get(
            f"https://api.telnyx.com/v2/number_lookup/{phone}",
            params={"type": "carrier"},
            headers={"Authorization": f"Bearer {api_key}"},
        )
        data = r.json()["data"]
        carrier = data.get("carrier", {})
        return {
            "type": carrier.get("type"),           # "mobile", "voip", etc.
            "name": carrier.get("name"),           # "T-Mobile", "Google Voice", etc.
            "ported": carrier.get("ported_status") == "ported",
            "lrn": carrier.get("lrn"),             # Current LRN (changes on port)
            "spid": carrier.get("spid"),           # Service Provider ID
        }

Frequently Asked Questions

Q: Does this affect Twilio numbers specifically, or all VoIP?

All VoIP numbers are affected, not just Twilio. Twilio programmable numbers are classified nonFixedVoip because Twilio's OCN is classified as a VoIP/CLEC provider in LERG. The same applies to Telnyx, Bandwidth, Vonage, Plivo, Sinch, and every other CPaaS provider's programmable numbers. These services provision numbers from their own OCN blocks, which are all classified as non-mobile.

Q: My Twilio number worked on Google last year. Why is it failing now?

VoIP blocking has been tightening progressively. Services update their carrier lookup policies and reputation databases. A number or OCN range that was tolerated in 2023 may now be explicitly blocked. Google in particular has been documented increasing eSIM and VoIP restrictions in early 2026.

Q: What about prepaid mobile numbers? Do they pass?

Prepaid mobile numbers from major carriers (AT&T Prepaid, T-Mobile Prepaid, Verizon Prepaid) pass carrier lookup as mobile. The OCN is still the mobile carrier's OCN. However, some fraud-sensitive services (Stripe, certain banks) apply additional velocity and reputation scoring. If a prepaid number has been associated with previous fraud attempts, it may be blocked by reputation even if the carrier type is correct.

Q: Can I port my existing Twilio number to a mobile carrier?

Yes, in principle. The FCC requires carriers to accept ports under LNP rules. You would need to:

  1. Contact a mobile carrier with an active account
  2. Initiate a port-in request with the Twilio number information
  3. Wait for the port to complete (hours to days)
  4. Activate the number on a physical or eSIM device

After porting, NPAC updates the SPID and the number is reclassified as mobile. This is a one-time operation — it's not suitable for dynamic number provisioning.

Q: Will this change as AI agent use cases grow?

The direction is toward stricter verification, not looser. Fraud rates on VoIP numbers continue to increase. Silent Network Authentication (SNA) is emerging as a more secure alternative to SMS OTP — it requires a real SIM and a mobile data connection, making it impossible to fake with VoIP. Services that adopt SNA will be even harder to verify with VoIP infrastructure.

Q: What about international numbers?

VoIP blocking is primarily a US/Canada phenomenon due to the specific LERG/NPAC infrastructure. International carrier lookup is less standardized — the equivalent databases (MSISDN lookup via HLR, MNP databases in the EU and UK) have different coverage and freshness characteristics. AgentSIM currently supports US numbers.

Q: My agent needs to maintain the same number across multiple sessions. Is that possible?

AgentSIM provisions numbers from a shared pool that returns numbers after sessions end. For agents that need persistent phone identity (the same number across many sessions over time), reach out about dedicated number allocation, which reserves a specific number to your account.


Summary

The VoIP blocking problem is structural, not accidental. Services block VoIP numbers because:

  1. The LERG/NPAC/OCN infrastructure exposes carrier type information that carrier lookup APIs surface reliably
  2. VoIP numbers have statistically higher fraud rates than mobile numbers
  3. Blocking is technically trivial once you're already running carrier lookups for routing

For AI agents that need SMS verification to pass Stripe, Google, WhatsApp, Amazon, Microsoft, or financial institutions, the only path forward is a number that carrier lookup APIs classify as mobile. That means physical SIM infrastructure.

AgentSIM provides that infrastructure via API. Three calls: provision, wait, release. The SIM management, carrier relationships, and OCN classification are handled for you.

  • Documentation: agentsim.dev/docs
  • MCP server: mcp.agentsim.dev/mcp — install with claude mcp add agentsim -e AGENTSIM_API_KEY=asm_live_xxx -- uvx agentsim-mcp
  • Get an API key: console.agentsim.dev