Fraud prevention

How to reduce fake sign-ups with layered phone and e-mail checks

A layered sign-up defence: format, line type, messaging presence, spam reputation and e-mail checks, mapped to friction tiers you can measure.

By Published 8 min read

On this page

To reduce fake sign-ups, check the phone number and the e-mail address a person enters in layers: format first, then line type, messaging presence, spam reputation and mailbox validity. Then turn the combined signals into friction tiers, from "allow" through "confirm" and "step up" to "review", instead of a single block rule. Measure how many real users each tier catches, and adjust. This guide shows how to build and tune that defence.

Why do fake sign-ups need more than one check?

Because fake accounts come from different sources, and each source leaves a different trace. A bot filling forms with random digits fails a format check. A promotion farmer using app-based numbers shows up in line type. A made-up address fails a mailbox check. A number already used for robocalls shows up in reputation data. No single signal sees all of them.

A single strong rule also hurts real users. Many genuine people use VoIP numbers, company e-mail domains or messaging apps you don't check. If one weak signal can block a sign-up, you pay for it in lost customers. Layering lets you require agreement between signals before you add real friction.

The attacker's economics matter too. Sign-ups often trigger a paid action: an SMS code, a trial, a referral bonus. OWASP describes how an SMS-sending endpoint without limits can be turned into a cost attack, with the attacker triggering tens of thousands of paid messages. Our guides on OTP checks before sending a code and SMS pumping cover that pre-send step. This post covers the account itself.

A sign-up form with a one-time code; one number passes the checks while a VoIP number and a risky number are stopped.A sign-up form with a one-time code; one number passes the checks while a VoIP number and a risky number are stopped.
Check the number before you send the code, and hold back VoIP and high-risk numbers.

Which layers can you check at sign-up?

From cheapest to most sensitive:

LayerQuestionCostCatchesMisses
Format and normalizationIs it a dialable number or a valid address?FreeRandom digits, typos, junkWell-formed fakes
Your own historySeen this number, address or device before?FreeRepeat sign-ups, ban evasionFirst-time attackers
Line type and carrierMobile, fixed, VoIP, premium rate?Per checkThrowaway and non-mobile numbersReal SIMs used for fraud
Messaging presenceDoes the number have a WhatsApp or Telegram account?Per checkNumbers nobody uses day to dayNew numbers, privacy settings
Spam reputationHas the number been reported?Per check; US, CA, DENumbers with a report historyNew or rarely used numbers
Mailbox validationDoes the mailbox exist?Per checkMade-up and mistyped addressesReal throwaway mailboxes
Account existenceIs the address registered on well-known services?Per checkFreshly created addressesEstablished addresses bought or stolen

A few notes on reading each layer:

  • Line type. The carrier lookup returns line_type and the current carrier. Premium-rate and shared-cost numbers are poor sign-up numbers in almost any product. VoIP is a signal, not a verdict. Our VoIP detection guide explains why. NIST's current guidance even removed the earlier prohibition on VoIP numbers for out-of-band authentication, while still asking verifiers to consider risk indicators such as SIM change and number porting (NIST, 2025).
  • Messaging presence. A WhatsApp or Telegram account means the number passed that platform's own sign-up at some point. No account is weak evidence on its own. Adoption differs by country, and some people keep their number private.
  • Spam reputation. The spam reputation check (limited access; US, CA and DE numbers) reports risk_level with explainable reasons. no_reports means no negative signals in our data. It doesn't mean safe.
  • E-mail. The mailbox check covers major webmail providers and answers unknown (UNSUPPORTED_PROVIDER) for company domains. Account existence checks are more revealing. Our comparison of e-mail verification and account existence checks explains when each fits.

How do you run phone and e-mail checks in one request?

Send the number and the address together, with the checks you want for each. Phone checks run on numbers and e-mail checks on emails:

Shell
curl https://api.mobilevalidate.com/v1/lookup \
  -H "Authorization: Bearer $MOBILEVALIDATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"numbers": ["+447700900001"], "emails": ["[email protected]"],
       "checks": ["carrier", "whatsapp", "telegram", "spam", "email"], "wait": 5}'

Real test-mode output, trimmed to the answers:

JSON
"network.carrier":     {"status": "completed", "registered": true,
                        "attributes": {"line_type": "mobile", "carrier": "Test Carrier", "country": "GB"}},
"whatsapp.registered": {"status": "completed", "registered": true},
"telegram.registered": {"status": "completed", "registered": true},
"number.spam":         {"status": "completed", "registered": true,
                        "attributes": {"risk_level": "high", "risk_score": 95, "reason_regulator": true,
                                       "reason_community": true, "top_category": "robocall", "sources": 2}},
"email.valid":         {"status": "completed", "registered": true}

This test number is deliberately contradictory: a mobile line with messaging accounts and a high spam level. That's what real data looks like too, and it's why you need rules that weigh signals instead of reacting to the first one. Every answer also carries checked_at and billed. You're not charged for inconclusive results (unknown, unsupported country, timeout, invalid, duplicate). Test keys return fixed data and never bill; see test mode.

How do you turn signals into friction tiers?

Map combinations of signals to a small set of responses. Five tiers cover most products:

TierResponseUser impact
0: AllowCreate the account normallyNone
1: ConfirmRequire e-mail confirmation or a CAPTCHA before first useLow
2: Step upAsk for a second verification method, or verify by voice or a messaging app instead of SMSMedium
3: Hold valueCreate the account, but hold bonuses, credits or payouts until it has historyLow at sign-up, visible later
4: ReviewQueue for manual review, or refuseHigh

A simple points model is easy to explain and to tune. A starting point:

SignalPoints
line_type is premium_rate or shared_cost+5
line_type is voip+2
No WhatsApp and no Telegram account, in a market where both are common+1
Spam risk_level is high+3
Mailbox doesn't exist (email.valid is false)+3
Number or device seen on a banned account+5
Many sign-ups from one carrier or IP range in the last hour+2
Any check unknown or pending0

Then set thresholds: 0–1 allow, 2 confirm, 3–4 step up or hold value, 5 or more review. The exact numbers matter less than two principles. Unknown adds nothing, because missing data isn't evidence. And no single weak signal reaches the review tier on its own.

Tier 3 is often the most effective and least visible. Fake accounts are usually created to extract something. If the bonus only arrives after a week of normal use, most farms move on, and real users barely notice.

Where should each check sit in the flow?

Not every check has to happen while the person waits.

  1. In the browser: format validation and obvious typos. Free and instant.
  2. On submit, synchronously: carrier and mailbox checks with a short wait, for example 3–5 seconds. These decide whether to send a code at all and whether to ask for a correction ("please check your e-mail address").
  3. After account creation, asynchronously: messaging presence, reputation and account existence. Use them to set the account's tier before it can earn or withdraw anything. Poll GET /v1/lookups/{id} or receive a lookup.completed webhook.
  4. At the moment of value: re-check just before a payout, a referral credit or a change of contact details. See account security.

If an answer is still pending when your wait expires, continue with the default path and apply the result later. A slow check should never become a failed sign-up.

How do you measure false positives?

Measure before you enforce, and keep measuring after.

  • Shadow mode. Run a new rule for two to four weeks without acting on it. Log the tier it would have assigned, then compare those accounts' behaviour with the rest: chargebacks, abuse reports, promotion redemptions, retention.
  • Step-up completion rate. Of the users sent to tier 2, how many complete the extra verification and go on to behave normally? A high completion rate with normal behaviour means the rule is catching real people.
  • Appeals and support contacts. Tag tickets that mention verification problems. A rise after a rule change is a direct false-positive signal.
  • Precision by signal. For each rule, track what share of flagged accounts turned out to be fake. Drop or down-weight rules with low precision.
  • Segment by country. Messaging adoption, VoIP use and mailbox providers differ by market. A rule that works in one country can fail in another.

Log decision codes (for example tier=2 reasons=voip,cluster) and checked_at, not full API responses. That's enough to analyse rules, and it keeps personal data to a minimum.

What do attackers do when you add friction?

They adapt, so expect your precision to drift. Common moves:

  • Switching number sources, for example from app-based VoIP numbers to cheap prepaid SIMs. Line type then shows mobile, and cluster signals (many sign-ups on one carrier in a short time) matter more.
  • Ageing accounts before using them, to get past holds. Re-check at the moment of value.
  • Using real but stolen contact details. Checks confirm that details are real, not that they belong to the person typing. That's where your own device and behaviour signals come in.

Review rule performance monthly and after any spike in abuse.

What privacy rules apply?

Checking a sign-up's number and address is processing of personal data, so you need a lawful basis and a clear purpose. The GDPR says in Recital 47 that processing strictly necessary for preventing fraud also constitutes a legitimate interest of the controller. The European Data Protection Board adds that this isn't automatic: the interest must be legitimate, and the processing must pass both a necessity and a balancing test (EDPB, 2024). In practice:

  • Run only the checks your tiers actually use (data minimisation, Article 5(1)(c)).
  • Mention fraud-prevention checks in your privacy notice.
  • Keep decisions, not raw results, and delete them when they are no longer needed.

This isn't legal advice. Consult your counsel for your case. Our privacy checklist for phone and e-mail checks goes through each point. Our acceptable use policy also forbids using results for eligibility decisions such as credit or employment.

What are the key takeaways?

  • Fake sign-ups come from different sources. Layer cheap checks (format, history) with paid ones (line type, messaging presence, reputation, mailbox) so each catches what the others miss.
  • Run phone and e-mail checks in one request, synchronously for what decides the next step and asynchronously for the rest.
  • Map signals to friction tiers. Require agreement between signals before adding heavy friction, and let unknown answers add nothing.
  • Holding rewards until an account has history stops a lot of abuse with little impact on real users.
  • Measure false positives with shadow mode, step-up completion and appeals, per country, and review rules regularly.
  • Keep only decision codes and timestamps, and document your lawful basis. Start with the OTP and sign-up fraud use case.

Sources

  1. NIST SP 800-63B-4: Digital Identity Guidelines — Authentication and Authenticator Management — NIST, 2025
  2. API4:2023 Unrestricted Resource Consumption — OWASP API Security Project, 2023
  3. General Data Protection Regulation (EU) 2016/679 — European Union, 2016
  4. Guidelines 1/2024 on processing of personal data based on Article 6(1)(f) GDPR (version 1.0) — European Data Protection Board (archived copy), 2024

Frequently asked questions

Which single check stops the most fake sign-ups?

There isn't one. Each check catches a different kind of fake: malformed input, throwaway numbers, numbers nobody uses, reported numbers, mailboxes that don't exist. Combining cheap layers, and adding friction only when several signals agree, works better than relying on one strong rule.

Should a sign-up be blocked when a check returns unknown?

No. Unknown means the check could not reach a conclusion, for example because of a timeout. Treat it as missing data, continue with your default path and, if needed, re-check later. Unknown answers are not charged.

How do I know whether my rules are turning away real customers?

Run new rules in shadow mode first, log the decision they would have made, and follow those accounts. Once live, track how many stepped-up users complete the extra verification and how many blocked users appeal successfully.

Can I use account existence checks on every sign-up?

You can, but they reveal more about a person than a mailbox check, so use them only where the fraud risk justifies it, such as sign-ups that unlock money or rewards. Store the resulting decision, not the list of services.

All articles

Know before you send.

Tell us about your use case. We review every request and set you up with test and live keys.