Marketplaces use phone and e-mail checks at seller and buyer onboarding, before in-app messaging opens up, and before promo rewards are paid. The checks show whether a number is reachable, mobile or VoIP, whether the mailbox exists and whether a WhatsApp Business account is set up. Doubtful accounts get extra verification or review. They are signals, not identity checks.
Where do contact signals help a marketplace?
A two-sided marketplace has two groups to protect and several moments where a bad account does damage:
- Seller onboarding. A seller who can't be reached when a buyer complains, or who signs up with throwaway details, is a support and refund risk. Payouts make this more serious.
- Buyer sign-up. Fake buyer accounts are used for fake reviews, harassment of sellers and testing stolen cards.
- Messaging between users. Scammers try to move conversations off-platform, where your protections don't reach. Accounts that only just signed up with weak contact details are the usual starting point.
- Promotions and referrals. First-order discounts and referral bonuses attract people who create many accounts to redeem them again and again.
In each case the question is the same: do the contact details on this account hold up? A number that is assigned and reachable, and a mailbox that exists, are cheap evidence of a normal account. An unassigned number, a mailbox that doesn't exist or a pattern of VoIP lines is evidence worth a second look.
How does it work?
- At sign-up, normalize. Parse the number to E.164. Unparseable input is
number_status: invalid_number, free, so the form can ask for a correction. - Check the contact details. Call
POST /v1/lookupwith the number and e-mail. For sellers, a typical set is["carrier", "hlr", "whatsapp.business", "email"]; for buyers,["carrier", "email"]. - Combine with your own data. Add device, payment, IP and behaviour signals, and check whether the same number or address is already on another account in your own database.
- Set trust levels. For example: full access, limited access (no payouts, messaging limits, no promos), or manual review.
- Gate promotions. Before paying a referral reward or first-order discount, look up the result you stored at sign-up. Re-check only if it's old.
- Re-check at risky moments. Before a payout-account change or when a seller changes their contact number, run an MNP lookup and compare the network with what you stored.
- Record decisions. Store the trust level and
checked_at, not the raw response.
Which checks should you use?
| Check | What it answers | When to use it | Service |
|---|---|---|---|
carrier | Mobile, fixed line or VoIP? Current carrier? | Every sign-up; VoIP lines get an extra step | Carrier lookup |
hlr | Is the mobile assigned and reachable right now? | Seller onboarding and before first payouts | HLR lookup |
email | Does the mailbox exist at a major webmail provider? | Every sign-up, before you rely on the address | E-mail mailbox check |
whatsapp.business | Does the number have a WhatsApp account, and is it a business account? | Seller onboarding, as context for the review | WhatsApp Business check |
mnp | Was the number ported, and which network is it on now? | Re-checks before payout or contact changes | MNP lookup |
spam | Does the number appear in spam and nuisance-call reports? | As one review signal, where enabled (limited access) | Spam reputation |
How do you screen promo abuse without hurting genuine users?
Most people who redeem a first-order discount are exactly the customers the promotion is for. The aim is to make repeat abuse expensive, not to make every new customer prove themselves.
- Screen at the moment of value. Run or reuse the checks when the reward is paid, not only at sign-up. A referral bonus paid to an account whose number is unassigned is the case to stop.
- Use your own duplicate detection. The same number or address, normalized, on several accounts is the clearest promo-abuse signal, and it comes from your database. Normalizing to E.164 before comparing catches the same number typed in different formats.
- Limit rather than block. A VoIP number or a missing mailbox can mean "no promo on this account until the e-mail is confirmed", while the person can still shop.
- Review in batches. Export redemptions for a campaign and run them as a bulk job; look at clusters, not single accounts.
Example request
With a test key, +447700900006 is a ported mobile number with a WhatsApp Business account. See test values. This is a seller-onboarding request:
curl https://api.mobilevalidate.com/v1/lookup \
-H "Authorization: Bearer mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym" \
-H "Content-Type: application/json" \
-d '{"numbers":["+447700900006"],"checks":["carrier","mnp","whatsapp.business"]}'// npm install mobilevalidate · Node.js 20+ · save as check.mjs and run: node check.mjs
import { MobileValidate } from "mobilevalidate";
// Omit apiKey to read MOBILEVALIDATE_API_KEY from the environment.
const mv = new MobileValidate({ apiKey: "mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym" });
const { data, error } = await mv.lookup({
numbers: ["+447700900006"],
checks: ["carrier", "mnp", "whatsapp.business"],
});
if (error) console.error(error.code, error.message);
else console.dir(data.results, { depth: null });// Node.js 18+, Deno, Bun or the browser console (ES module: save as .mjs or use "type": "module").
const res = await fetch("https://api.mobilevalidate.com/v1/lookup", {
method: "POST",
headers: {
Authorization: "Bearer mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym",
"Content-Type": "application/json",
},
body: JSON.stringify({
numbers: ["+447700900006"],
checks: ["carrier", "mnp", "whatsapp.business"],
}),
});
console.log(res.status, res.headers.get("x-request-id"));
console.dir(await res.json(), { depth: null });# pip install mobilevalidate-sdk
from mobilevalidate import MobileValidate
# Omit api_key to read MOBILEVALIDATE_API_KEY from the environment.
mv = MobileValidate(api_key="mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym")
result = mv.lookup(
numbers=["+447700900006"],
checks=["carrier", "mnp", "whatsapp.business"],
)
print(result)<?php
$ch = curl_init('https://api.mobilevalidate.com/v1/lookup');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'numbers' => ['+447700900006'],
'checks' => ['carrier', 'mnp', 'whatsapp.business'],
]),
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL, $response, PHP_EOL;package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"numbers":["+447700900006"],"checks":["carrier","mnp","whatsapp.business"]}`)
req, err := http.NewRequest("POST", "https://api.mobilevalidate.com/v1/lookup", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}require "net/http"
require "json"
uri = URI("https://api.mobilevalidate.com/v1/lookup")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym"
req["Content-Type"] = "application/json"
req.body = JSON.generate({
"numbers" => ["+447700900006"],
"checks" => ["carrier", "mnp", "whatsapp.business"]
})
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.code, res.bodyRuns as pasted with the public sandbox key, which answers the test values only. In the SDKs, omit the key to use MOBILEVALIDATE_API_KEY.
Response (excerpt, test mode: the checks of the first item of results):
{
"network.carrier": {
"service": "network.carrier", "status": "completed", "registered": true,
"attributes": {"line_type": "mobile", "carrier": "Test Carrier", "country": "GB"},
"confidence": "high", "confidence_score": 0.99, "checked_at": "2026-09-28T22:40:27.052Z",
"cached": false, "age_seconds": 0, "billed": false, "reason": null, "poll_after_ms": null
},
"number.mnp": {
"service": "number.mnp", "status": "completed", "registered": true,
"attributes": {"porting": "ported", "mcc_mnc": "23410", "country": "GB"},
"confidence": "high", "confidence_score": 0.99, "checked_at": "2026-09-28T22:40:27.052Z",
"cached": false, "age_seconds": 0, "billed": false, "reason": null, "poll_after_ms": null
},
"whatsapp.business": {
"service": "whatsapp.business", "status": "completed", "registered": true,
"attributes": {"business": true},
"confidence": "high", "confidence_score": 0.99, "checked_at": "2026-09-28T22:40:27.052Z",
"cached": false, "age_seconds": 0, "billed": false, "reason": null, "poll_after_ms": null
}
}A mobile line, a business account on WhatsApp and a normal port: consistent with a seller who runs their shop from that number. Store mcc_mnc: 23410 so a later change of network before a payout stands out. The flag says how the account was set up, not that the business is genuine, so your own seller checks still apply.
What should you do with each result?
| Signals | Suggested action |
|---|---|
| Mobile, reachable, mailbox exists | Normal trust level |
line_type: voip, everything else normal | Allow; hold promos or payouts until the e-mail is confirmed |
HLR invalid or number_status: invalid_number | Ask for a correction; no promos, messaging or payouts until fixed |
Mailbox registered: false | Ask for a working address before messaging opens up |
| Seller claims a business, number has no WhatsApp account | Context only; weigh with your seller checks |
| Several accounts in your own data share one number or address | Review. Hold promo redemptions on the extra accounts |
Current mcc_mnc differs from the stored one before a payout change | Step up: confirm by e-mail or hold the payout |
Spam risk_level: high (where enabled) | Manual review |
Any check unknown | Normal handling. Unknown is not negative and is free |
Start with limits that are easy to lift, such as a hold on promos or a payout delay, and watch how often reviewed accounts turn out fine. Tighten only where the review shows real abuse.
How much does it cost?
The MNP lookup costs $0.001 and the HLR lookup $0.005 per number. The carrier lookup, the mailbox check and the WhatsApp Business check each have their own real-time and bulk prices; see pricing. You're not charged for inconclusive results (unknown, unsupported country, timeout, invalid, duplicate). Buyer sign-ups can run a cheaper set than seller onboarding, and repeat checks inside the freshness window come from your account's cache for free.
For promo abuse, weigh the price of a check against the discount or reward you pay out. Checks at sign-up, stored and reused at redemption time, mean you usually pay once per account.
What about consent and acceptable use?
Check the contact details users give your platform, and say in your privacy notice that you verify them to keep the marketplace safe. The checks never return names, photos or profiles, and reverse lookups are not offered. Don't use them to research people outside your platform, or to find out which of a user's contacts use a messaging app.
Results are signals, not proof. They don't verify identity, detect bots or show that two accounts belong to the same person. The acceptable use policy forbids eligibility decisions about credit, employment, housing or insurance based on results. People can object through the opt-out form, and suppressed contacts are never checked or charged.
What are common mistakes?
- Blocking all VoIP numbers. You lose genuine users. Limit risky actions instead.
- Treating a business flag as business verification. Anyone can set up a business account.
- Checking only at sign-up. Contact changes before payouts are the riskier moment.
- Re-checking on every promo redemption. Reuse the stored result inside its freshness window.
- Treating unknown as a failure. It means no answer this time, and it's free.
- Comparing raw strings for duplicates.
07700 900001and+447700900001are the same number. Normalize to E.164 before you look for shared contacts across accounts, or duplicates slip through. - Letting trust levels never change. Recalculate them when a seller changes contact details, and let good history lift early limits.
- Showing results to other users. A "verified" badge implies an identity check you didn't do. Keep results internal.
Frequently asked questions
What can phone and e-mail checks add to marketplace trust and safety?
Facts about the contact details an account signs up with: whether the number is assigned and reachable, whether it is a mobile or a VoIP line, whether the mailbox exists and whether a WhatsApp Business account is set up on the number. You combine them with your own account, device and behaviour data.
Can the checks tell me whether a seller is a real business?
No. The WhatsApp Business flag only shows how the account on that number was set up; anyone can install the business app. The checks describe contact details, not who owns them, and they are not identity or business verification.
Can the checks detect bots or tell me that two accounts belong to the same person?
No. They don't detect bots or identify people. Duplicate use of one phone number or e-mail across accounts is something you see in your own data. The checks add context, such as a VoIP line or an unassigned number, that makes those patterns easier to judge.
How do phone checks help against promo abuse?
Promo abuse often relies on many cheap or throwaway contact details. Checking the line type, reachability and mailbox before a first-order discount or referral reward is paid lets you hold redemptions from contacts that don't hold up, and route them to review.
Should I block every VoIP number?
No. Many genuine buyers and sellers use VoIP numbers. Treat VoIP as a reason for an extra step, for example confirming the e-mail, a delay before payouts, or a limit on promos, not as an automatic block.
What do the checks cost per account?
The MNP lookup is $0.001 and the HLR lookup $0.005 per number. The carrier lookup, the mailbox check and the WhatsApp Business check have their own prices on the pricing page. Unknown answers are free.
Can I check the numbers of users who message my sellers?
You can check contact details that users gave your platform, under your privacy notice. You can't use the checks to look up people outside your platform, and they never return names or profiles.
Related
- ServiceCarrier and line type lookup for any phone number
- ServiceCheck if a number is a WhatsApp Business account
- ServiceCheck if an e-mail mailbox exists
- ServiceHLR lookup API: live mobile network status
- Use caseOTP and sign-up fraud prevention
- ArticleVoIP number detection for sign-ups: what works and what to watch out for


