# Phone number spam reputation

> See whether a US, Canadian or German number appears in spam and nuisance-call reports, with a level, a 0–100 score and the reasons behind it.

Canonical: https://mobilevalidate.com/services/spam-reputation · Last updated: 2026-09-25

![A shield and a risk gauge pointing into the high range, with an incoming call flagged as risky.](https://mobilevalidate.com/images/spam-reputation-risk-score.svg)

*Spam reputation gives a risk level and the reasons behind it, where the service is enabled.*


**Limited access:** this service is available to internal customers only for now.

The spam reputation check tells you whether a phone number appears in spam and nuisance-call reports, and why. Every answer includes a level (`high`, `medium`, `low` or `no_reports`), a 0–100 score and the classes of signal behind it. It covers numbers from the United States, Canada and Germany, in real time or in bulk.

## What does the spam reputation check tell you?

It tells you whether a number has a record of complaints, and how strong that record is. It is a **reputation signal, not a verdict**. It summarizes what others reported about a number. It doesn't prove who is calling.

The answer is built from these classes of signal, described here by type only:

- **Regulator actions**: a telecom regulator took action against the number.
- **Government complaint data**: the number appears in government nuisance-call complaint data.
- **Community reports**: people reported the number on public spam-report sites.
- **Unassigned-number signal**: the number was recently offered for sale as unassigned. This is a sign of a spoofed caller ID or a made-up lead.
- **VoIP-range hint**: the number range belongs to a VoIP carrier. This is shown for context only and adds no points.

Reports are refreshed daily. Report texts, reporter details and names are never returned.

## How are levels and scores decided?

The `risk_score` runs from 0 to 100. More reports and stronger reports raise it. Reports last seen more than 12 months ago count half, so a number that was abused years ago and has been quiet since slowly drifts down.

| Level | Rule |
|---|---|
| `high` | Score 80 or more **and** either a regulator action or at least two independent signal classes |
| `medium` | Score 50–79 |
| `low` | Score 20–49 |
| `no_reports` | We hold no reports for the number |

`sources` counts the independent signal classes behind the answer. `top_category` names the most frequent kind of report: `debt_relief`, `impersonation`, `robocall`, `medical`, `home_services`, `warranty`, `sms_spam`, `dialer`, `fraud_hacking` or `other`. `first_seen` and `last_seen` give the months (`YYYY-MM`) when the number first and last appeared in our data.

**`no_reports` is not a guarantee a number is safe.** It means we have no negative signals, nothing more.

## Who uses it, and why?

- **Call centers and inbound teams** use it to decide whether to answer, flag or route an incoming call, and to check that their own outbound numbers haven't collected complaints. See [call-center screening](/use-cases/call-center-screening).
- **Lead verification.** A web lead whose phone number was recently offered as unassigned (`reason_unassigned`) is likely fake. That is worth knowing before a sales team spends time on it. See [lead verification](/use-cases/lead-verification).
- **Fraud teams** add the level to sign-up and payment risk scoring. A `high` number with an `impersonation` or `fraud_hacking` category deserves a manual review.

Coverage is limited to the US, Canada and Germany because report data is dense enough there to give meaningful answers. We don't offer the check in countries where a thin data set would produce misleading `no_reports` answers.

## What do you get back?

| Field | Type | Meaning |
|---|---|---|
| `attributes.risk_level` | enum | `high`, `medium`, `low` or `no_reports` |
| `attributes.risk_score` | integer 0–100 | Higher means more and stronger reports |
| `attributes.reason_regulator` | boolean | A telecom regulator took action against the number |
| `attributes.reason_government` | boolean | Listed in government nuisance-call complaint data |
| `attributes.reason_community` | boolean | Reported on community spam-report sites |
| `attributes.reason_unassigned` | boolean | Recently offered for sale as an unassigned number |
| `attributes.voip_range` | boolean | Hint only: the range belongs to a VoIP carrier (no points) |
| `attributes.top_category` | enum | Most frequent report category (absent when none) |
| `attributes.first_seen` / `last_seen` | `YYYY-MM` | First and last month the number appeared in our data |
| `attributes.sources` | integer 0–10 | Number of independent signal classes |
| `registered` | boolean or null | `true` for every conclusive answer ("data found"); `null` otherwise |

In summaries, `high`, `medium` and `low` count as "registered" (reports found) and `no_reports` counts as "not registered".

## How is it billed?

Every conclusive answer is billed, **including `no_reports`**. The check was carried out and answered. You're not charged for inconclusive results (unknown, unsupported country, timeout, invalid, duplicate). An `unknown` answer, for example while reference data is temporarily unavailable, is free, and so is any number outside the US, Canada and Germany. See [pricing](/pricing).

Answers come from our own daily-refreshed reference data rather than a live call to another service, so real-time answers are fast. Repeat checks of the same number within 24 hours are served from your account's cache and are free.

## What are the limits?

- **Countries:** US, CA and DE. Other numbers return `unsupported_country`, which is free.
- **Modes:** real time (`POST /v1/lookup`, up to 100 numbers) and bulk jobs (`POST /v1/jobs`, up to 50,000). The MCP tool `check_spam_reputation` takes up to 100 numbers per call.
- Up to 20 checks per request. Numbers × checks is capped at 2,000 per lookup and 100,000 per job.
- Requests that look like sequential number ranges or generated e-mail lists are rejected (20 or more consecutive numbers → `suspected_enumeration`).
- Scores change over time. Store `checked_at` with any decision you make.

## How do I use it responsibly?

Treat the level as one signal among several. Don't treat it as proof that a person is a spammer. A number can be spoofed by someone else, and a number reported years ago can have a new owner. Don't use the result to deny someone credit, a job, housing or insurance. The [acceptable use policy](/legal/acceptable-use) forbids that.

We process report data about numbers as a controller. If your number appears in our data and you think it shouldn't, or you want it removed, use the [opt-out form](/opt-out). The [data-subject notice](/legal/data-subject-notice) explains your rights.

## Example request

With a test key, the whole test range `+44 7700 9xxxxx` works for this service, although live checks cover only US, CA and DE. `+447700900001` returns `high`, `…002` returns `no_reports`, `…003` returns `unknown`, `…004` is pending and then `medium`, and `…005` returns `unsupported_country`. See [test mode](/docs/test-mode).

```bash
curl https://api.mobilevalidate.com/v1/lookup \
  -H "Authorization: Bearer $MOBILEVALIDATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"numbers": ["+447700900001"], "checks": ["spam"]}'
```

Response (excerpt, test mode: the first item of `results`):

```json
{
  "kind": "phone",
  "input": "+447700900001",
  "e164": "+447700900001",
  "country": "GB",
  "number_status": "valid",
  "checks": {
    "number.spam": {
      "service": "number.spam",
      "status": "completed",
      "registered": true,
      "attributes": {
        "risk_level": "high",
        "risk_score": 95,
        "reason_regulator": true,
        "reason_government": false,
        "reason_community": true,
        "reason_unassigned": false,
        "voip_range": false,
        "top_category": "robocall",
        "first_seen": "2025-11",
        "last_seen": "2026-08",
        "sources": 2
      },
      "confidence": "high",
      "confidence_score": 0.99,
      "checked_at": "2026-09-25T14:25:31.435Z",
      "cached": false,
      "age_seconds": 0,
      "billed": false,
      "reason": null,
      "poll_after_ms": null
    }
  },
  "test": true
}
```

## Frequently asked questions

### Who can use the spam reputation check today?

It is in limited access: available to internal customers only for now. If you need it, say so in your access request and we will let you know when it opens up.

### Does no_reports mean the number is safe?

No. no_reports means we hold no reports for the number. A new number, a rarely used number or a spoofed caller ID can still be abusive. Treat it as the absence of negative signals and combine it with other checks.

### Why is a no_reports answer charged?

Because the check was carried out and answered conclusively. Every risk level, including no_reports, is billed. Unknown answers and numbers outside the US, Canada and Germany are free.

### Can I see the report texts or who reported a number?

No. The check returns levels, reasons and categories only. Report texts, reporter details and names are never returned.

### Can a number's score change?

Yes. Scores are recomputed as new reports arrive and old ones age. Reports last seen more than 12 months ago count half. checked_at shows when an answer was computed.

## Service code and modes

- Code: `number.spam` (input: phone number)
- Modes: realtime and bulk · countries: US, CA, DE
- Status: limited access

## Price (live)

- Realtime (POST /v1/lookup): $0.0008 per check ($0.80 per 1,000)
- Bulk (POST /v1/jobs): $0.0004 per check ($0.40 per 1,000)
- You're not charged for inconclusive results (unknown, unsupported country, timeout, invalid, duplicate).

## Response fields (from the public catalog)

| Field | Type | Meaning |
|---|---|---|
| registered | boolean or null | true when data was found; null when unknown (not charged) |
| status | enum | completed, pending, unknown, unsupported_country, failed |
| checked_at | timestamp | When the answer was obtained |
| attributes.risk_level | enum (high, medium, low, no_reports) | Overall reputation level. |
| attributes.risk_score | integer | Score 0–100 (higher = more reports). |
| attributes.reason_regulator | boolean | A telecom regulator took action against the number. |
| attributes.reason_government | boolean | Listed in government nuisance-call complaint data. |
| attributes.reason_community | boolean | Reported on community spam-report sites. |
| attributes.reason_unassigned | boolean | Recently offered for sale as an unassigned number (possible spoofed caller ID or fake lead). |
| attributes.voip_range | boolean | Hint only: the number range belongs to a VoIP carrier (not a risk by itself). |
| attributes.top_category | enum (debt_relief, impersonation, robocall, medical, home_services, warranty, sms_spam, dialer, fraud_hacking, other) | Most frequent report category. |
| attributes.first_seen | string | Month the number first appeared in our data (YYYY-MM). |
| attributes.last_seen | string | Month the number last appeared in our data (YYYY-MM). |
| attributes.sources | integer | Number of independent signal classes. |
