KYC phone verification for fintech and crypto onboarding

Fraud rings have figured out that the cheapest part of a fake-account stack is the phone number. A burner VoIP line from a reseller costs under a dollar, accepts SMS verification codes the same way a real mobile does, and can be discarded after the bonus, credit line, or payout has been pulled. By the time your KYC document workflow runs, the cost of investigating a single fake account is already an order of magnitude higher than what it cost the fraudster to start it.

The signals to filter this out are visible at the moment of signup — before you send the SMS code, before you ask for the ID upload. POST /v1/lookup returns them in a single call, scored against the IP address the user is registering from.

The signals that actually matter

Four fields do most of the work for KYC risk scoring. None of them is decisive on its own; they're inputs to your scorecard.

See the full field reference for every available signal.

A complete request

Pass the user's IP address along with the phone number so the response can score IP/phone geo agreement:

curl --request POST \
  --url 'https://api.checkthatphone.com/v1/lookup' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "phone": "8182925409",
    "ip": "136.38.145.14"
  }'

A clean response — what you want a real user's signup to look like:

{
  "success": true,
  "credits_used": 1,
  "data": {
    "subscriber": "8182925409",
    "optDate": "2026-05-23T21:56:26.108Z",
    "action": "send",
    "deliverable": "true",
    "nanpType": "mobile",
    "blackList": "false",
    "ipResult": "valid-v4",
    "dip": "success",
    "dipLrn": "8182925409",
    "dipPorted": "false",
    "dipOcn": "6010",
    "dipCarrier": "AT&T",
    "dipCarrierSubType": "WIRELESS",
    "dipCarrierType": "mobile",
    "dipMessagingLookup": "false",
    "dipMessagingEnabled": "false",
    "geoCountry": "US",
    "geoState": "UT",
    "geoCity": "Salt Lake City",
    "geoMetro": 770,
    "geoSource": "ip",
    "timezone": "America/Denver",
    "tzOffset": 7,
    "error": "false"
  }
}

And a high-risk response — VoIP carrier sub-type, recently ported, IP/phone geo mismatch:

{
  "success": true,
  "credits_used": 1,
  "data": {
    "subscriber": "4159656300",
    "optDate": "2026-05-23T21:59:32.941Z",
    "action": "unsubscribe",
    "deliverable": "false",
    "reason": "Not a valid mobile number",
    "nanpType": "not-mobile",
    "blackList": "false",
    "ipResult": "valid-v4",
    "dip": "success",
    "dipLrn": "4157042000",
    "dipPorted": "true",
    "dipOcn": "506J",
    "dipCarrier": "Twilio International",
    "dipCarrierSubType": "IPES",
    "dipCarrierType": "landline",
    "dipMessagingLookup": "false",
    "dipMessagingEnabled": "false",
    "geoCountry": "US",
    "geoState": "UT",
    "geoCity": "Salt Lake City",
    "geoMetro": 770,
    "geoSource": "ip",
    "timezone": "America/Denver",
    "tzOffset": 7,
    "error": "false"
  }
}

Neither response is automatically "approve" or "deny" — that decision belongs to your scorecard. The point is that you have the signals in front of you before your KYC pipeline runs the expensive checks.

Wiring it into the signup flow

Three integration shapes that map cleanly onto common fintech / crypto KYC stacks:

1. Pre-OTP gate

Call /v1/lookup the moment the user enters their phone, before you spend money sending an SMS code. Reject obviously bad numbers (undeliverable, on the litigator list, a blocked carrier). For borderline cases — IPES + IP mismatch + recently ported — still send the OTP but flag the registration for a stronger document-verification path downstream.

2. Inline scorecard with adjudication thresholds

Combine each lookup field into a numeric risk score: +30 for IPES, +35 for dipPorted: "true", +15 for ipResult: "mismatch", +50 for blackList: "true". Auto-approve under 30, route to manual review between 30 and 70, auto-decline above 70. Tune from the back-test of your last 30 days of charged-back accounts.

3. Post-signup batch re-scoring

For users who have already signed up, run the same lookup on the phone numbers in your existing book and surface high-risk accounts to fraud-ops for proactive review. Particularly useful when you've just changed your acceptance rules and need to find anyone who slipped in under the older policy.

Inline FAQ

Is this a replacement for KYC document verification?

No. Phone risk signals are a fast first-pass filter that runs before you spend on document verification. Use them to decide whether to challenge a signup, route to manual review, or proceed straight through.

What does ipResult actually compare?

The geo derived from the IP address (country/state/city) against the geo derived from the phone number's area code. A "mismatch" by itself isn't a failure — travelers and remote workers mismatch routinely — but it stacks with other signals.

How do you flag VoIP versus mobile?

dipCarrierSubType returns "IPES" (IP-Enabled Service) for VoIP carriers like Bandwidth, Twilio, Telnyx, and similar reseller infrastructure. Mobile networks return "WIRELESS". A truly residential landline returns "ILEC" or "RBOC".

What this isn't

Phone-based KYC signals are one defensive layer; they don't replace document verification, sanctions screening, or behavioral analytics. A clean phone lookup does not certify identity, and a flagged one isn't proof of fraud. Use the fields as inputs to a multi-signal scorecard that you tune against your own outcomes.

Pricing for this use case

A KYC lookup is the standard call, no add-ons needed. Most fintech onboarding teams sit comfortably on the 10K or 100K plan; PAYG ($0.010/credit) is the right pick during pre-launch when daily volume is unpredictable.

See the pricing page for the full grid, or contact us about enterprise volume if you're putting more than 500K signups through per month.

Related