What Is Number Reputation?
Number reputation systems evaluate phone numbers to predict the likelihood of fraud, spam, or abuse. Like email reputation and IP reputation systems, number reputation aggregates multiple signals to generate a trust score that informs platform decisions.
Effective number reputation considers:
- Line type — Mobile, landline, VoIP, prepaid indicators
- Carrier information — Serving carrier and carrier reputation
- Porting history — Recent number changes and frequency
- Historical behavior — Previous fraud, spam, or abuse associations
- Real-time signals — Current spam reports, velocity patterns
Why Number Reputation Matters
Phone numbers are increasingly used as identity anchors:
- Account verification — SMS OTP for registration and 2FA
- Communication channels — SMS marketing, notifications, support
- Identity linking — Connecting accounts across services
- Fraud prevention — Detecting synthetic identities and account farms
Without reputation scoring, platforms accept all numbers equally, allowing fraudsters to use burner phones, VoIP services, and number farms for abuse.
Key Reputation Signals
Line Type Analysis
Line type is a primary fraud indicator. Risk varies significantly by type:
| Line Type | Fraud Risk | Typical Use | Recommendation |
|---|---|---|---|
| Postpaid mobile | Low | Individual consumers, businesses | Standard verification |
| Prepaid mobile | Medium | Legitimate users, but also fraud | Additional verification signals |
| Landline | Low | Residential, business | Voice verification (no SMS) |
| VoIP | High | Business, but commonly abused | Enhanced verification required |
| Virtual/Online | Very High | Burner services, number farms | Block or require alternatives |
| Toll-free | Medium | Businesses | Verify business context |
# Line type risk scoring
LINE_TYPE_RISK = {
'mobile': 10, # Low risk
'landline': 15, # Low-medium
'voip': 60, # High risk
'prepaid': 40, # Medium-high
'virtual': 80, # Very high risk
'tollfree': 30, # Business context needed
'unknown': 50 # Treat as medium-high
}
def calculate_line_type_risk(phone_intel):
line_type = phone_intel.get('line_type', 'unknown').lower()
return LINE_TYPE_RISK.get(line_type, 50)
Porting and Carrier Signals
Porting behavior reveals fraud patterns:
- Recent porting — Numbers ported in last 30 days have higher fraud rates
- Frequent porting — Multiple ports suggest number manipulation
- Carrier changes — Moves between carriers can indicate fraud
- Carrier reputation — Some MVNOs have higher fraud rates
# Porting risk analysis
def analyze_porting_risk(phone_intel, user_context):
risk_score = 0
signals = []
# Check for recent porting
lrn_date = phone_intel.get('lrn_activation_date')
if lrn_date:
days_since_port = (datetime.now() - parse_date(lrn_date)).days
if days_since_port <= 7:
risk_score += 40
signals.append('ported_last_week')
elif days_since_port <= 30:
risk_score += 25
signals.append('ported_last_month')
elif days_since_port <= 90:
risk_score += 10
signals.append('ported_last_quarter')
# Check if ported vs. original carrier
if phone_intel.get('ported'):
risk_score += 15
signals.append('is_ported_number')
# Carrier reputation check
carrier = phone_intel.get('carrier', '')
if carrier in HIGH_RISK_CARRIERS:
risk_score += 30
signals.append(f'high_risk_carrier:{carrier}')
return {'score': risk_score, 'signals': signals}
Get instant line type and carrier data. Real-time phone intelligence for fraud prevention and verification.
Get Free API KeyHistorical and Community Signals
Aggregate data from multiple sources:
- Spam reports — Numbers reported as spam by consumers
- Fraud databases — Known fraudulent numbers across platforms
- Velocity signals — Numbers used across many accounts rapidly
- Abuse history — Previous bans, suspensions, or chargebacks
Implementation Architecture
Reputation Scoring System
Build a modular scoring system that combines multiple signals:
class PhoneReputationScorer:
def __init__(self, phone_intel_client, abuse_db, spam_db):
self.intel = phone_intel_client
self.abuse_db = abuse_db
self.spam_db = spam_db
def score_number(self, phone_number, context=None):
"""
Generate comprehensive reputation score.
Returns score 0-100 where higher = more risky.
"""
# Get real-time phone intelligence
intel = self.intel.lookup(phone_number, lrn=True, spam=True)
# Calculate component scores
scores = {
'line_type': self._score_line_type(intel),
'porting': self._score_porting(intel, context),
'carrier': self._score_carrier(intel),
'spam': self._score_spam(intel, phone_number),
'velocity': self._score_velocity(phone_number),
'abuse_history': self._score_abuse(phone_number)
}
# Weighted combination
weights = {
'line_type': 0.20,
'porting': 0.15,
'carrier': 0.15,
'spam': 0.20,
'velocity': 0.15,
'abuse_history': 0.15
}
total_score = sum(scores[k] * weights[k] for k in scores)
return {
'phone': phone_number,
'score': round(total_score, 1),
'risk_level': self._categorize_risk(total_score),
'components': scores,
'recommendations': self._get_recommendations(total_score, scores)
}
def _categorize_risk(self, score):
if score >= 70:
return 'critical'
elif score >= 50:
return 'high'
elif score >= 30:
return 'medium'
else:
return 'low'
def _get_recommendations(self, total_score, components):
recommendations = []
if total_score >= 70:
recommendations.append({
'action': 'block_or_manual_review',
'reason': 'Very high fraud risk'
})
elif total_score >= 50:
recommendations.append({
'action': 'enhanced_verification',
'methods': ['id_verification', 'video_selfie', 'trusted_referral']
})
elif total_score >= 30:
recommendations.append({
'action': 'additional_signals',
'methods': ['email_verification', 'device_fingerprint', 'behavioral_check']
})
else:
recommendations.append({
'action': 'standard_flow',
'reason': 'Low risk number'
})
return recommendations
Integration Points
Integrate reputation checks at key platform touchpoints:
| Touchpoint | Timing | Action on High Risk |
|---|---|---|
| Registration | Before phone verification | Enhanced verification or rejection |
| Phone change | Before updating account | Re-verify identity |
| Password reset | Before sending SMS | Alternative recovery method |
| High-value transaction | Before processing | Step-up authentication |
| Outbound messaging | Before sending | Skip or flag for review |
Graduated Friction Model
Apply verification friction proportional to risk level:
class GraduatedVerification:
"""Apply verification friction based on phone reputation."""
def determine_verification_flow(self, reputation_result, context):
risk_level = reputation_result['risk_level']
if risk_level == 'low':
return {
'flow': 'standard',
'steps': ['sms_otp'],
'friction': 'minimal',
'expected_dropoff': '5%'
}
elif risk_level == 'medium':
return {
'flow': 'enhanced',
'steps': ['sms_otp', 'email_verification'],
'friction': 'moderate',
'expected_dropoff': '15%'
}
elif risk_level == 'high':
return {
'flow': 'high_assurance',
'steps': [
'sms_otp',
'email_verification',
'photo_id_verification'
],
'friction': 'significant',
'expected_dropoff': '40%',
'monitoring': 'enhanced_for_30_days'
}
else: # critical
return {
'flow': 'manual_review',
'steps': ['manual_review_required'],
'friction': 'maximum',
'alternative': 'suggest_different_phone',
'expected_dropoff': '80%'
}
Balancing Security and Conversion
Track metrics to optimize the balance:
- Conversion rate by risk level — Higher friction should target truly risky numbers
- False positive rate — Legitimate users incorrectly flagged
- Fraud rate post-registration — Did flagged numbers become problems?
- Cost per verified user — Verification costs vs. fraud losses
Implement phone reputation in minutes. Simple API integration for instant risk scoring.
View API DocsReal-Time API Integration
Registration Flow Integration
# Registration flow with reputation check
@app.route('/api/register', methods=['POST'])
def register():
data = request.json
phone = data.get('phone_number')
# Step 1: Get phone reputation
reputation = phone_reputation_scorer.score_number(phone, context={
'action': 'registration',
'ip': request.remote_addr,
'device_id': data.get('device_id')
})
# Step 2: Determine verification requirements
verification_flow = graduated_verification.determine_verification_flow(
reputation,
context={'action': 'registration'}
)
# Step 3: Log for analysis
log_reputation_check(phone, reputation, verification_flow)
# Step 4: Return appropriate response
if verification_flow['flow'] == 'manual_review':
return jsonify({
'status': 'review_required',
'message': 'Additional verification needed. Our team will contact you.',
'alternative_action': 'use_different_phone'
}), 202
# Continue with verification flow
return jsonify({
'status': 'verification_required',
'verification_steps': verification_flow['steps'],
'session_id': create_verification_session(phone, reputation)
}), 200
Caching and Performance
Optimize performance for high-volume platforms:
# Caching reputation lookups
import redis
class CachedReputationScorer:
def __init__(self, scorer, redis_client, cache_ttl=3600):
self.scorer = scorer
self.redis = redis_client
self.cache_ttl = cache_ttl
def score_number(self, phone, context=None):
cache_key = f"phone_rep:{phone}"
# Check cache first
cached = self.redis.get(cache_key)
if cached:
result = json.loads(cached)
result['cached'] = True
return result
# Calculate fresh score
result = self.scorer.score_number(phone, context)
# Cache the result
self.redis.setex(
cache_key,
self.cache_ttl,
json.dumps(result)
)
result['cached'] = False
return result
Monitoring and Tuning
Key Metrics to Track
- Distribution of risk scores — Should follow expected patterns
- Fraud rate by risk tier — Validate scoring accuracy
- Verification completion by tier — Measure friction impact
- False positive reports — Legitimate users blocked or over-verified
# Analytics for reputation system
class ReputationAnalytics:
def generate_report(self, date_range):
return {
'risk_distribution': self._get_risk_distribution(date_range),
'fraud_by_tier': self._get_fraud_rates(date_range),
'conversion_by_tier': self._get_conversion_rates(date_range),
'top_blocked_carriers': self._get_blocked_carriers(date_range),
'false_positive_rate': self._get_fp_rate(date_range)
}
def _get_fraud_rates(self, date_range):
"""Calculate actual fraud rates by risk tier."""
return {
'low': self._fraud_rate_for_tier('low', date_range),
'medium': self._fraud_rate_for_tier('medium', date_range),
'high': self._fraud_rate_for_tier('high', date_range),
'critical': self._fraud_rate_for_tier('critical', date_range)
}
Continuous Improvement
Regularly tune your reputation system:
- Weekly — Review fraud rates and adjust thresholds
- Monthly — Analyze false positive trends and carrier patterns
- Quarterly — Reassess signal weights based on actual outcomes
- Ongoing — Feed fraud outcomes back into scoring
Implementation Checklist
Foundation
- Integrate phone intelligence API for line type and carrier data
- Build scoring system with weighted signals
- Define risk tiers and corresponding thresholds
- Create verification flows for each risk tier
Integration
- Add reputation check to registration flow
- Integrate with phone change workflows
- Check before password resets and account recovery
- Implement caching for performance
Operations
- Set up monitoring dashboards
- Create alerting for unusual patterns
- Establish feedback loop from fraud outcomes
- Document escalation and override procedures
Common Implementation Patterns
E-commerce Platform
- Check reputation at checkout for guest purchases
- Higher friction for first-time buyers with VoIP numbers
- Link phone reputation to chargeback risk models
Financial Services
- Strict VoIP blocking for new account opening
- Continuous monitoring for carrier/porting changes
- Enhanced verification for wire transfers and large transactions
Social/Dating Platforms
- Focus on velocity signals (same number across accounts)
- Higher scrutiny for recently-activated numbers
- Link to spam/harassment report history
Marketplace Platforms
- Separate reputation for buyers vs. sellers
- Higher requirements for high-value item sellers
- Check reputation before enabling messaging features
Frequently Asked Questions
Should I block all VoIP numbers?
Blocking all VoIP numbers is generally too aggressive. Many legitimate business users have VoIP numbers from services like Google Voice, RingCentral, or their company's UCaaS platform. Instead, treat VoIP as a higher-risk signal that triggers enhanced verification. Combine with other signals like carrier reputation, account age, and behavioral patterns for better decisions.
How do I handle false positives without losing legitimate users?
Use graduated friction rather than binary accept/reject decisions. Offer alternative verification paths (ID verification, social sign-in, trusted referral) for users flagged as high-risk. Provide clear messaging and support channels for users who believe they were incorrectly flagged. Monitor false positive rates and adjust thresholds if legitimate users are consistently blocked.
How often should I re-check phone reputation for existing users?
Re-check reputation before sensitive actions rather than on a fixed schedule. Check before password resets, fund withdrawals, account settings changes, or any high-risk transaction. For ongoing monitoring, check periodically (weekly to monthly) for high-value accounts. A carrier or porting change on an existing account is a strong signal for investigation.
What's the typical latency impact of reputation checks?
Phone intelligence API calls typically complete in 100-300ms. With proper caching, repeat checks can be served in under 10ms. The latency is generally acceptable in registration and verification flows where users expect some processing time. For performance-critical paths, use asynchronous checks that complete before the user submits the next step.