Phone Reputation API Guide

Phone reputation APIs provide real-time intelligence about phone numbers, revealing spam likelihood, fraud signals, carrier information, and historical behavior patterns. This comprehensive guide covers how phone reputation systems work, what data they provide, integration best practices, and how to use reputation scores effectively in your fraud prevention stack.

Key Takeaways

  • Phone reputation APIs aggregate data from carriers, consumer reports, and behavioral analysis
  • Key data points include spam score, line type, carrier, CNAM, and activity history
  • Integrate at key touchpoints: registration, login, transaction, and communication
  • Combine reputation data with your own behavioral signals for best results

What is Phone Reputation?

Phone reputation is a quantified assessment of how likely a phone number is associated with spam, fraud, or malicious activity. Similar to email reputation or credit scores, phone reputation aggregates multiple data sources to produce actionable risk signals.

Data Sources for Phone Reputation

  • Carrier data - Line type, activation date, porting history
  • Consumer complaints - FTC reports, Do Not Call violations, app-based reports
  • Industry databases - Shared blocklists, fraud ring identifiers
  • Behavioral analysis - Call patterns, velocity, anomalies
  • STIR/SHAKEN attestation - Caller ID verification status
  • CNAM databases - Caller ID name registration

What Phone Reputation Reveals

Signal What It Tells You Risk Indication
Spam Score Likelihood of spam/fraud association Direct risk signal
Line Type VoIP, mobile, landline, toll-free VoIP = higher risk profile
Carrier Which network owns/routes the number Some carriers higher risk
Number Age How long number has been active New numbers = higher risk
Spam Type Robocaller, telemarketer, scam type Classification for blocking
CNAM Registered caller ID name Missing/generic = suspicious

How Phone Reputation APIs Work

Phone reputation APIs accept a phone number and return enriched data and risk scores. Understanding the underlying mechanics helps you use the data effectively.

API Request Flow

  1. Number normalization - Convert to E.164 format (+1XXXXXXXXXX)
  2. Cache check - Return cached data if fresh
  3. Data aggregation - Query carrier databases, spam databases, CNAM
  4. Score calculation - Apply algorithms to generate risk scores
  5. Response formatting - Return structured data

Example API Request and Response

# API Request
curl "https://api-service.verirouteintel.io/api/v1/lrn" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d "phone=+15551234567" \
  -d "lrn=true" \
  -d "cnam=true" \
  -d "spam=true"

# API Response
{
  "phone": "+15551234567",
  "valid": true,
  "lrn": {
    "line_type": "mobile",
    "carrier": "Verizon Wireless",
    "ocn": "6006",
    "lata": "132",
    "activation_date": "2019-03-15",
    "ported": false
  },
  "cnam": {
    "name": "JOHN SMITH",
    "type": "person",
    "presentation": "allowed"
  },
  "spam": {
    "score": 12,
    "is_spam": false,
    "is_robocaller": false,
    "spam_type": null,
    "reports": 0,
    "risk_level": "low"
  }
}

Understanding Spam Scores

The spam score is typically the most actionable data point from a phone reputation API. Understanding how scores are calculated helps you set appropriate thresholds.

Spam Score Components

  • Report volume - Number of consumer complaints (weighted by recency)
  • Report source diversity - Complaints from multiple independent sources
  • Robocall flags - Known robocaller database matches
  • Carrier reputation - Historical spam rates from carrier/OCN
  • Behavioral signals - Call volume anomalies, pattern matches

Score Interpretation Guidelines

Score Range Risk Level Typical Action
0-20 Low Proceed normally
21-40 Low-Medium Standard verification
41-60 Medium Enhanced verification
61-80 High Manual review or block
81-100 Critical Block

Get real-time phone reputation data. Spam scores, line type, carrier info, and more. Try 10 free lookups.

Get Free API Key

Integration Patterns

Phone reputation APIs should be integrated at key decision points in your application. Here are the most common integration patterns:

1. Account Registration

Screen phone numbers during account signup to prevent fraudulent account creation:

async function validateRegistration(phoneNumber, userData) {
  // Check phone reputation before creating account
  const reputation = await verirouteApi.lookup(phoneNumber, {
    lrn: true,
    spam: true
  });

  // Block high-risk numbers
  if (reputation.spam.score >= 80) {
    return {
      allowed: false,
      reason: 'high_risk_phone',
      action: 'block_registration'
    };
  }

  // Require additional verification for medium risk
  if (reputation.spam.score >= 50) {
    return {
      allowed: true,
      requireAdditionalVerification: true,
      verificationType: 'document_upload'
    };
  }

  // Flag VoIP numbers for monitoring
  if (reputation.lrn.line_type === 'voip') {
    await flagForMonitoring(userData.userId, 'voip_registration');
  }

  return { allowed: true };
}

2. Transaction Verification

Verify phone numbers before high-value transactions:

async function verifyTransaction(transaction) {
  const { phone, amount, userId } = transaction;

  // Get current reputation
  const reputation = await verirouteApi.lookup(phone, { spam: true });

  // Calculate risk threshold based on transaction value
  const riskThreshold = calculateThreshold(amount);

  if (reputation.spam.score >= riskThreshold) {
    // Hold transaction for review
    await holdTransaction(transaction.id, {
      reason: 'phone_reputation',
      score: reputation.spam.score,
      threshold: riskThreshold
    });

    // Notify fraud team
    await alertFraudTeam({
      type: 'transaction_hold',
      transaction,
      reputation
    });

    return { status: 'held', requiresReview: true };
  }

  return { status: 'approved' };
}

function calculateThreshold(amount) {
  if (amount >= 1000) return 40;
  if (amount >= 500) return 50;
  if (amount >= 100) return 60;
  return 70;
}

3. Login Verification

Check reputation when phone is used for 2FA or account recovery:

async function verifyLoginAttempt(userId, phone, loginContext) {
  // Compare with registered phone
  const user = await getUser(userId);

  if (phone !== user.registeredPhone) {
    // New phone - full reputation check
    const reputation = await verirouteApi.lookup(phone, {
      lrn: true,
      spam: true
    });

    if (reputation.spam.score >= 60) {
      return {
        allowed: false,
        reason: 'suspicious_new_phone',
        action: 'require_alternate_verification'
      };
    }

    // Check for SIM swap indicators
    if (isRecentlyPorted(reputation.lrn)) {
      await alertSecurityTeam(userId, 'possible_sim_swap');
      return {
        allowed: false,
        reason: 'recently_ported',
        action: 'security_challenge'
      };
    }
  }

  return { allowed: true };
}

function isRecentlyPorted(lrnData) {
  if (!lrnData.ported || !lrnData.port_date) return false;
  const daysSincePort = daysBetween(lrnData.port_date, new Date());
  return daysSincePort < 7;
}

4. Inbound Call Screening

Screen incoming calls before routing to agents:

async function screenInboundCall(callerNumber) {
  const reputation = await verirouteApi.lookup(callerNumber, {
    spam: true,
    cnam: true
  });

  // Block known spammers
  if (reputation.spam.is_robocaller || reputation.spam.score >= 85) {
    return { action: 'block', sendToVoicemail: true };
  }

  // Warn agents about suspicious calls
  if (reputation.spam.score >= 50) {
    return {
      action: 'allow',
      agentWarning: true,
      warningDetails: {
        spamScore: reputation.spam.score,
        spamType: reputation.spam.spam_type,
        callerName: reputation.cnam?.name || 'Unknown'
      }
    };
  }

  // Enrich call data for agents
  return {
    action: 'allow',
    callerInfo: {
      name: reputation.cnam?.name,
      lineType: reputation.lrn?.line_type,
      carrier: reputation.lrn?.carrier
    }
  };
}

Combining Reputation with Other Signals

Phone reputation is most powerful when combined with other fraud signals:

Signal Fusion Framework

class FraudScorer {
  constructor(phoneApiKey) {
    this.phoneApi = new VeriRouteAPI(phoneApiKey);
  }

  async calculateRiskScore(userData, context) {
    const signals = {};

    // Phone reputation (weight: 30%)
    const phoneRep = await this.phoneApi.lookup(userData.phone, { spam: true });
    signals.phone = {
      score: phoneRep.spam.score,
      weight: 0.30
    };

    // Email reputation (weight: 20%)
    signals.email = {
      score: await this.checkEmailReputation(userData.email),
      weight: 0.20
    };

    // IP reputation (weight: 15%)
    signals.ip = {
      score: await this.checkIPReputation(context.ipAddress),
      weight: 0.15
    };

    // Device fingerprint (weight: 15%)
    signals.device = {
      score: await this.checkDeviceFingerprint(context.deviceId),
      weight: 0.15
    };

    // Behavioral signals (weight: 20%)
    signals.behavior = {
      score: this.analyzeBehavior(context.behaviorData),
      weight: 0.20
    };

    // Calculate weighted composite
    let compositeScore = 0;
    for (const [key, signal] of Object.entries(signals)) {
      compositeScore += signal.score * signal.weight;
    }

    return {
      compositeScore: Math.round(compositeScore),
      signals,
      recommendation: this.getRecommendation(compositeScore)
    };
  }

  getRecommendation(score) {
    if (score >= 75) return 'block';
    if (score >= 50) return 'challenge';
    if (score >= 30) return 'monitor';
    return 'allow';
  }
}

Caching and Performance

Phone reputation data has different freshness requirements. Implement intelligent caching:

Cache TTL Guidelines

Data Type Recommended TTL Rationale
Line Type 24-48 hours Rarely changes
Carrier 24 hours Changes only on porting
CNAM 4-12 hours Occasionally updated
Spam Score 1-4 hours Can change as reports come in
Robocaller Flag 1-2 hours Important to stay current
class CachedPhoneReputation {
  constructor(phoneApi, redis) {
    this.api = phoneApi;
    this.redis = redis;
  }

  async lookup(phone, options = {}) {
    const cacheKey = `phone:${phone}`;

    // Check cache
    const cached = await this.redis.get(cacheKey);
    if (cached && !options.bypassCache) {
      const data = JSON.parse(cached);

      // Check if spam data is stale
      const spamAge = Date.now() - data._cachedAt;
      if (spamAge < 2 * 60 * 60 * 1000) { // 2 hours
        return data;
      }

      // Refresh spam data, keep static data
      const freshSpam = await this.api.lookup(phone, { spam: true });
      data.spam = freshSpam.spam;
      data._cachedAt = Date.now();
      await this.redis.set(cacheKey, JSON.stringify(data), 'EX', 86400);
      return data;
    }

    // Full lookup
    const data = await this.api.lookup(phone, {
      lrn: true,
      cnam: true,
      spam: true
    });
    data._cachedAt = Date.now();

    // Cache for 24 hours
    await this.redis.set(cacheKey, JSON.stringify(data), 'EX', 86400);

    return data;
  }
}

Error Handling Best Practices

Robust error handling ensures your application degrades gracefully:

async function lookupWithFallback(phone, options) {
  try {
    const result = await phoneApi.lookup(phone, options);
    return { success: true, data: result };
  } catch (error) {
    // Log the error
    logger.error('Phone reputation lookup failed', {
      phone: maskPhone(phone),
      error: error.message,
      code: error.code
    });

    // Handle specific error types
    if (error.code === 'INVALID_PHONE') {
      return {
        success: false,
        fallback: true,
        assumedRisk: 'high', // Invalid phone is suspicious
        reason: 'invalid_phone_format'
      };
    }

    if (error.code === 'RATE_LIMITED') {
      // Use cached data if available
      const cached = await getCachedData(phone);
      if (cached) {
        return { success: true, data: cached, fromCache: true };
      }

      // Fail open with monitoring
      await alertOps('Phone API rate limited, failing open');
      return {
        success: false,
        fallback: true,
        assumedRisk: 'medium',
        reason: 'rate_limit_fallback'
      };
    }

    if (error.code === 'SERVICE_UNAVAILABLE') {
      // Queue for retry
      await queueForRetry(phone, options);

      return {
        success: false,
        fallback: true,
        assumedRisk: 'medium',
        reason: 'service_unavailable'
      };
    }

    // Unknown error - fail safe
    return {
      success: false,
      fallback: true,
      assumedRisk: 'medium',
      reason: 'unknown_error'
    };
  }
}

Compliance Considerations

Using phone reputation data requires attention to regulatory compliance:

Key Compliance Areas

  • TCPA - Phone reputation can help avoid calling numbers that would create TCPA liability
  • GDPR/CCPA - Phone number is PII; ensure proper data handling
  • Fair Credit Reporting Act - If used for credit decisions, additional requirements apply
  • Disparate Impact - Ensure scoring doesn't discriminate against protected classes

Best Practices

  1. Document your scoring methodology and thresholds
  2. Provide appeal/review processes for blocked users
  3. Retain audit logs of reputation-based decisions
  4. Regularly review for bias in outcomes
  5. Ensure data retention complies with regulations

Best Practices Summary

  1. Integrate at key decision points - Registration, transactions, and authentication
  2. Don't block on reputation alone - Use as one signal in a multi-factor system
  3. Cache intelligently - Balance freshness vs. API costs
  4. Handle errors gracefully - Plan for API failures
  5. Monitor and tune thresholds - Review false positive/negative rates
  6. Combine with behavioral data - Reputation + your own signals = better accuracy
  7. Stay compliant - Document decisions and provide appeal processes

Frequently Asked Questions

How often is phone reputation data updated?

Phone reputation data is updated continuously. Static data like line type and carrier changes infrequently (only on porting events). Spam scores and reputation signals are updated as new complaints are filed, typically within minutes to hours of reports being received. VeriRoute Intel recommends caching static data for 24 hours and spam data for 1-4 hours.

What if a legitimate customer has a high spam score?

False positives do occur, especially with numbers that were previously owned by spammers or have common area codes. Best practice is to offer alternate verification paths (document upload, video verification, different phone) rather than outright blocking. Implement appeal processes where customers can request review, and adjust your thresholds based on false positive rates you observe.

Should I treat VoIP numbers as high risk?

VoIP numbers have statistically higher fraud rates because they're inexpensive and easy to obtain. However, many legitimate users have VoIP numbers (Google Voice, business lines, etc.). Rather than blocking VoIP outright, use line type as one factor in your risk scoring, perhaps requiring additional verification for VoIP numbers. Industry averages suggest VoIP fraud rates are 3-5x higher than mobile, but blocking all VoIP would reject many good customers.

How does phone reputation compare to device fingerprinting for fraud detection?

Phone reputation and device fingerprinting are complementary, not competing technologies. Phone reputation identifies risky phone numbers regardless of device, while device fingerprinting identifies risky devices regardless of phone. The most effective fraud prevention combines both: a fraudster may use a new phone on an old device, or a known fraud device with a new phone. Using both catches more fraud than either alone.

Related Articles

← Back to Phone Fraud Detection

Start Using Phone Reputation Data Today

Get spam scores, line type, carrier data, and CNAM with our simple API. 10 free lookups every month.