If you're building AI agents that need to create Stripe accounts, you've hit this wall:
This phone number cannot be used for verification.
Your agent fills out the form perfectly, reaches phone verification, and — rejected. This guide explains exactly what's happening and how to solve it with real SIM-backed numbers.
Why Stripe Blocks Your Number
Stripe performs carrier lookups against multiple databases before sending any verification SMS:
- LERG (Local Exchange Routing Guide) — The authoritative database of North American phone numbers
- NPAC (Number Portability Administration Center) — Tracks number porting between carriers
- Real-time HLR queries — Verify active network registration on the carrier side
If your number comes back as voip or nonFixedVoip, it's rejected immediately. The code is never sent.
| Provider | line_type returned | Stripe result |
|---|---|---|
| Twilio | voip |
❌ Blocked |
| Google Voice | voip |
❌ Blocked |
| Vonage | voip |
❌ Blocked |
| TextNow | voip |
❌ Blocked |
| AgentSIM | mobile |
✅ Passes |
Why Twilio/VoIP Numbers Fail
Every VoIP provider's number ranges are catalogued in LERG. When Stripe queries:
{
"number": "+19875551234",
"carrier": "Twilio Inc",
"line_type": "voip"
}
Instant rejection. This isn't a bug — it's by design. Financial services block VoIP to prevent synthetic identity fraud.
The Fix: Real SIM Numbers via AgentSIM
AgentSIM provisions actual SIM-backed phone numbers from carriers like T-Mobile. These return mobile in carrier lookups because they ARE mobile numbers.
Install
pip install agentsim-sdk
Basic Usage
import agentsim
agentsim.configure(api_key="asm_live_xxx")
async with agentsim.provision(agent_id="stripe-setup", country="US") as num:
# num.number is a real mobile number (E.164 format)
print(f"Using: {num.number}") # +14155552671
# Enter the number in Stripe verification form
await enter_phone_on_stripe(num.number)
# Wait for the OTP to arrive via real SMS
otp = await num.wait_for_otp(timeout=60)
print(f"Code: {otp.otp_code}") # 391847
# Enter the code — verification passes
await enter_code_on_stripe(otp.otp_code)
# Number auto-released when context exits
With Playwright (Full Automation)
import agentsim
from playwright.async_api import async_playwright
agentsim.configure(api_key="asm_live_xxx")
async def verify_stripe_account():
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto("https://dashboard.stripe.com/register")
await page.fill("[name=email]", "agent@company.com")
async with agentsim.provision(
agent_id="stripe-setup",
country="US"
) as num:
await page.fill("[name=phone]", num.number)
await page.click("button:has-text(\"Send code\")")
otp = await num.wait_for_otp(timeout=60)
await page.fill("[name=code]", otp.otp_code)
await page.click("button:has-text(\"Verify\")")
await browser.close()
With MCP (Claude Code / Cursor / Windsurf)
If you're using an AI coding agent, AgentSIM has a native MCP server:
{
"mcpServers": {
"agentsim": {
"url": "https://mcp.agentsim.dev/mcp",
"headers": {
"Authorization": "Bearer asm_live_xxx"
}
}
}
}
Then your agent can call provision_number and wait_for_otp as MCP tools directly.
Why AgentSIM Numbers Pass
| Check | VoIP Number | AgentSIM Number |
|---|---|---|
| LERG lookup | voip |
mobile |
| Carrier name | Twilio Inc | T-Mobile USA |
| HLR query | No network reg | Active on tower |
| Fraud score | High (70-90) | Clean (0-10) |
AgentSIM uses real SIM cards on real carrier networks. The numbers aren't spoofed or masked — they're genuine mobile numbers that pass every verification check.
Cost Comparison
| Approach | Monthly cost | Stripe success rate |
|---|---|---|
| Twilio | $1-15/number | 0% |
| Google Voice | Free (ToS risk) | 0% |
| AgentSIM | $0.99/session | 100% |
10 free sessions per month. No subscription required.
Get Started
- Try it: agentsim.dev
- Docs: docs.agentsim.dev
- MCP Server: Smithery · npm · PyPI
- GitHub: github.com/agentsimdev
Stop fighting VoIP detection. Use real mobile numbers that work.
Top comments (0)