The lead that looked fine until it wasn’t
A crypto exchange onboards 400 new users on a Tuesday. Forty of them pass ID checks, verify a phone number, and initiate withdrawals within 72 hours. The phone numbers all look like US mobiles. None of them are. They’re VoIP lines spun up through a reseller, tied to synthetic identities, and the accounts are drained before the compliance team flags the pattern.
This is not a hypothetical. Fintechs and crypto platforms deal with this constantly. The frustrating part is that the signal was there at signup. The phone data would have caught most of it. Nobody looked.
The fix isn’t a longer KYC form. It’s scoring the phone number the moment it arrives, before you send an OTP, before you write a row to your database, before you spend a dollar on verification infrastructure for someone who was never a real customer.
Why VoIP is your clearest fraud signal
Not every VoIP number belongs to a fraudster. Plenty of legitimate users have Google Voice or a business line through RingCentral. But in fintech and crypto onboarding, VoIP numbers show up in fraud clusters at a rate that makes them worth flagging hard.
The field you want is dipCarrierSubType. Where dipCarrierType tells you the broad category (wireless, wireline, VoIP), dipCarrierSubType goes narrower. You’ll see values like VoIP broken down further by provider type. Paired with dipCarrier, which names the actual carrier, you can distinguish a Twilio-provisioned number from a T-Mobile postpaid line.
In practice, I’d build a tiered response here rather than a binary block. A first-time signup with a VoIP dipCarrierSubType and a small deposit might just get flagged for manual review. A VoIP number submitting a $10,000 wire request on day one should hard-stop until a human sees it. The cost of a false positive is a 10-minute delay. The cost of ignoring this signal is the scenario I opened with.
You also want nanpType in this check. If the number comes back as landline or not-mobile, it can’t receive SMS OTPs in the normal sense, and it’s a strong indicator the user either mistyped or is trying to game your verification flow. Mobile is the expected value for almost every real consumer signup.
dipPorted as a SIM-swap proxy
SIM swapping is a real problem for any platform that uses SMS 2FA. The attacker convinces a carrier to move a victim’s number to a new SIM, then uses SMS intercept to take over the account.
dipPorted tells you whether a number has been ported away from its original carrier. A recent port isn’t proof of fraud, but it’s a meaningful risk signal when combined with other factors. A number that shows dipPorted: true, is registered to an account less than 30 days old, and is attempting a withdrawal is a pattern worth pausing on.
The more useful application in crypto is ongoing monitoring, not just signup. If you store the carrier snapshot at registration and re-query the number on a sensitive action (large withdrawal, password reset, linked bank account change), a new dipPorted: true where you previously saw false is a strong SIM-swap indicator. That’s a check worth running in real time against POST https://api.checkthatphone.com/v1/lookup with your Authorization: Bearer <key> header.
IP and phone geography mismatch
The ipResult field compares the geographic origin of the user’s IP address against the registered location of the phone number. A mismatch here doesn’t mean fraud. Someone signing up from a coffee shop in Miami with a Chicago area code is completely normal. But a signup IP resolving to a data center in Eastern Europe paired with a phone number ostensibly from a US carrier is a different story.
You can cross-reference this with geoState and timezone to build a simple coherence check. If the IP country doesn’t match the phone geography and the timezone is inconsistent with both, that’s three signals pointing the same direction. I’ve seen this combination show up on bot-driven account creation at a rate high enough that teams start routing it to a separate queue automatically.
Data center IPs are the clearest version of this. Consumer residential IPs moving around is normal. An IP registered to AWS us-east-1 is not a human sitting at a computer.
Building a score, not a binary block
The worst implementation mistake is treating any one of these fields as a kill switch. You’ll block real users. The better approach is additive scoring.
Here’s a simple starting model:
dipCarrierSubTypereturns VoIP: add 30 pointsnanpTypeis not mobile: add 25 pointsdipPortedis true on a new account: add 20 pointsipResultshows IP/phone geo mismatch: add 15 pointsipResultshows data center IP: add 25 points
Over 50 points: route to manual review. Over 80 points: require additional verification before any financial action. Over 100: consider declining the session outright.
You tune these thresholds against your actual fraud data over the first few weeks. The numbers above are a starting point, not gospel. Your fraud pattern will differ from a competitor’s based on your product, geography, and acquisition channels.
Running this at scale
For real-time signup flows, you call POST https://api.checkthatphone.com/v1/lookup per number as it arrives. Latency is low enough that you can do this synchronously before returning a response to the client. The user never sees it.
For batch work, like auditing a list of existing accounts you’re worried about, or cleaning up a lead list before a campaign, the right tool is Bulk CSV verification through the CheckThatPhone dashboard (Dashboard then Bulk CSV). Upload your file, it deduplicates and runs carrier DIP, nanpType, and any add-ons you’ve enabled across every row, then returns a downloadable result file. Files are deleted within 24 hours of delivery, which matters if you’re handling consumer data under any state privacy law.
If you’re also thinking about downstream liability from contacting any of these numbers, the litigator scrub add-on is worth running at the same time. Pass litigatorFilter: true in your request and you get back litigator, litigator_type, and litigator_name. A fraudulent number that also belongs to a serial TCPA plaintiff is a very specific problem you don’t want to discover after the fact. See the TCPA litigator scrub use case for how teams integrate this.
What this doesn’t catch
Phone validation is one layer, not a complete fraud stack. It won’t catch a fraudster using a real postpaid mobile number they bought off a grey market. It won’t detect a synthetic identity if the phone number attached to it is otherwise clean. And dipPorted has a lag, typically a few hours after a port completes before the data propagates.
Those are real limitations. But catching the VoIP farms, the obviously mismatched geos, and the freshly ported numbers on large transactions eliminates a significant slice of low-effort fraud without touching legitimate user experience at all. That’s the trade worth making.
If you want to see what the fields actually return for a number before building your scoring logic, the docs walk through the full response schema. Pricing for the DIP lookup and add-ons is on the pricing page. For a broader view of how this fits into identity verification workflows, the KYC phone verification use case covers the integration pattern in more detail.