Use case

CRM data hygiene and contact re-validation

Contact data decays as numbers are disconnected and mailboxes close. Re-check phone and e-mail fields in your CRM on a schedule and before every campaign.

Last updated

A phone number and an e-mail address flow into the MobileValidate gateway, which answers valid, invalid or unknown; badges read 42 checks, one API and unknowns are free.
Check phone numbers and e-mail addresses before you message, call or approve them.

CRM data hygiene means re-checking the phone numbers and e-mail addresses you already hold, because contact data decays. Numbers are disconnected and reassigned, mailboxes close. Run a bulk job before each campaign and on a schedule: an HLR lookup for numbers, the mailbox check for e-mails. Then suppress dead contacts and fix the rest.

Why does contact data decay?

A contact record is a snapshot of the day it was collected. After that, life moves on:

  • Numbers are disconnected and reassigned. People switch operators, drop second SIMs and leave numbers unused until the operator reclaims them. In the United States alone, the FCC estimated that about 35 million numbers are disconnected and made available for reassignment every year (FCC 18-177, 2018). A reassigned number in your CRM reaches a stranger who never gave you consent. See reassigned numbers explained.
  • Numbers are ported. The number still works but sits on a different network, so any stored carrier field is now wrong. See mobile number portability.
  • Mailboxes close. People abandon personal addresses and lose work addresses when they change jobs. Mail to a closed mailbox bounces, and repeated hard bounces damage your sender reputation.
  • Data entry errors pile up. Typos, numbers without country codes, and the same person imported twice in different formats.

Decay is invisible until you send. Then it shows up as failed SMS, bounced e-mail, wrong-person complaints and skewed campaign metrics. Checking before sending moves that discovery to a point where it costs a check, not a message and a complaint.

How does it work?

  1. Export the segment. Take the contacts you are about to message, or the slice of the database due for its scheduled check. Include the CRM record ID so you can match results back.
  2. Estimate for free. Call POST /v1/jobs/estimate with the numbers, e-mails and checks. It counts valid, invalid, duplicate, cached, unsupported and suppressed rows and gives the maximum cost, without checking or charging anything.
  3. Run a bulk job. Create it with POST /v1/jobs (up to 50,000 numbers and e-mails per job) and pass the estimate's amount as max_cost. Add a default_country if your CRM stores national formats.
  4. Wait for completion. Poll GET /v1/jobs/{id}?wait=30 or subscribe to the job.completed webhook.
  5. Download and import. Get the CSV (GET /v1/jobs/{id}/download?format=csv). It keeps your row order and adds a column per check.
  6. Apply the rules below. Suppress conclusive negatives, flag temporary problems, correct formats, and write checked_at to each record.
  7. Schedule the next run. Re-check contacts whose last check is older than your chosen interval, and always the segment before a campaign.

The CSV list cleaner recipe shows the same flow in code.

Which checks should you use?

CheckWhat it answersWhen to use itService
hlrIs the mobile number assigned and reachable now? Ported? Current network?Before SMS campaigns and on a schedule for mobile numbersHLR lookup
carrierMobile, fixed line, VoIP or toll-free? Current carrier?To separate SMS-capable numbers from landlines before a text campaignCarrier lookup
mnpWas the number ported, and which network is it on now?To refresh a stored network field cheaplyMNP lookup
emailDoes the mailbox exist at a major webmail provider?Before e-mail campaigns, to avoid hard bouncesE-mail mailbox check
network.carrier_usCurrent carrier for US and Canadian numbersBulk jobs on North American recordsUS/CA carrier lookup

You don't need every check on every record. A text campaign needs hlr (or carrier if you only need the line type). An e-mail campaign needs email. A full database refresh might run both.

How often should you re-validate?

There is no single right interval, because decay depends on your audience and on how often you use the data. A practical approach has three layers:

  • Before every campaign, check the segment you are about to message. This is the check that saves the most, because it runs right before you pay for sends.
  • On a schedule for the rest of the database, for example every quarter. Prioritize records you haven't messaged or heard from in a long time: silence is often the first sign a contact went stale.
  • On events, check again when a delivery fails, an e-mail bounces or a customer says "that's not my number". One failure is worth a fresh check with max_age: 0, not an immediate deletion.

Store the last checked_at per record. Then "re-check anything older than N days" becomes a simple CRM filter.

Example request

First, a free estimate. The list holds three test numbers, one of which appears twice in different formats, plus two addresses:

curl https://api.mobilevalidate.com/v1/jobs/estimate \
  -H "Authorization: Bearer mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym" \
  -H "Content-Type: application/json" \
  -d '{"numbers":["+447700900001","+447700900002","07700 900002","+447700900003"],"emails":["[email protected]","[email protected]"],"default_country":"GB","checks":["hlr","email"]}'

Runs 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):

JSON
{
  "object": "estimate",
  "total": 6,
  "valid": 5,
  "invalid": 0,
  "duplicate": 1,
  "cached": 0,
  "unsupported": 0,
  "suppressed": 0,
  "checks": ["number.hlr", "email.valid"],
  "checks_total": 6,
  "billable_max": 0,
  "max_cost": {"amount": "0", "currency": "USD"}
}

07700 900002 is the same number as +447700900002 once normalized to E.164, so it's marked duplicate and never checked. Test keys are never charged, so the cost is zero here. For a handful of records, for example when a sales rep opens an old contact, the same checks run in real time:

curl https://api.mobilevalidate.com/v1/lookup \
  -H "Authorization: Bearer mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym" \
  -H "Content-Type: application/json" \
  -d '{"numbers":["+447700900002"],"emails":["[email protected]"],"checks":["hlr","email"]}'

Runs 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 phone row, then of the e-mail row):

JSON
[
  {
    "number.hlr": {
      "service": "number.hlr", "status": "completed", "registered": true,
      "attributes": {"status": "unreachable", "ported": false, "roaming": false, "network": "Test Mobile", "mcc_mnc": "23415", "country": "GB"},
      "confidence": "high", "confidence_score": 0.99, "checked_at": "2026-09-28T22:42:26.188Z",
      "cached": false, "age_seconds": 0, "billed": false, "reason": null, "poll_after_ms": null
    }
  },
  {
    "email.valid": {
      "service": "email.valid", "status": "completed", "registered": false, "attributes": null,
      "confidence": "high", "confidence_score": 0.99, "checked_at": "2026-09-28T22:42:26.188Z",
      "cached": false, "age_seconds": 0, "billed": false, "reason": null, "poll_after_ms": null
    }
  }
]

The number exists but can't be reached right now: flag it and check again later. The mailbox doesn't exist: stop e-mailing this address and ask for a new one at the next contact.

What should you do with each result?

ResultCRM action
number_status: invalid_numberFix the format (often a missing country code) or clear the field
number_status: duplicateMerge the records
HLR status: reachableKeep. Store checked_at
HLR status: unreachableFlag and re-check before the next send. Don't delete on one answer
HLR status: invalidSuppress SMS and calls. The number is not assigned
line_type: fixed_lineMark as "no SMS"; use calls or e-mail
Mailbox registered: trueKeep
Mailbox registered: falseSuppress e-mail to this address; ask for an update at the next contact
Any check unknownKeep the record as it is. Unknown is not negative and is free

How much does it cost?

The HLR lookup is $0.005 per number and the MNP lookup $0.001 per number. Other checks, including the mailbox check, have separate real-time and bulk prices on the pricing page. You're not charged for inconclusive results (unknown, unsupported country, timeout, invalid, duplicate). The free estimate shows the maximum cost before you commit.

Two things keep hygiene cheap. Check only the segment you're about to use, not the whole database every time. And re-running an updated list inside each service's freshness window serves repeat numbers from your account's cache, free.

Re-validation is data accuracy, which privacy law expects of you: under the GDPR, personal data must be "accurate and, where necessary, kept up to date" (GDPR Art. 5(1)(d)). Mention contact verification in your privacy notice.

Checks don't create consent. Message only people who opted in, and treat a number that may have been reassigned as a reason to re-confirm consent, not to send. Our acceptable use policy forbids unsolicited bulk messaging and list building, and checks never return names or profiles. People can object through the opt-out form; suppressed contacts are never checked or charged.

What are common mistakes?

  • Checking the whole database once and never again. Decay is continuous. Check on a schedule and before each campaign.
  • Deleting on one unreachable answer. A switched-off phone isn't a dead number. Re-check first.
  • Treating unknown as bad. Unknown means no answer this time, and it's free. Keep the record.
  • Skipping normalization. Without a country, national numbers can't be checked. Set default_country or store E.164.
  • Overwriting the CRM with raw responses. Store the decision and checked_at, not the full JSON.
  • Cleaning only one channel. A record with a dead mailbox often has a stale phone too. When one field fails, re-check the other before the next campaign on either channel.
  • Ignoring suppression on import. Numbers and addresses that people asked you to stop using must stay suppressed after a clean-up. Re-importing a cleaned file must not bring them back into campaigns.
  • Assuming a reachable number still belongs to your contact. Reachable means assigned and live, not "same person". Re-confirm consent when a record is old.

Frequently asked questions

Why does CRM contact data go bad?

People change numbers, close mailboxes and leave jobs, and numbers that were given up are reassigned to new people. A record that was right when it was collected can point to nobody, or to someone else, a year later.

How often should I re-validate contacts?

Before every campaign for the contacts you are about to message, and on a regular schedule for the rest of the database. Contacts you message rarely are the ones most likely to have gone stale. Pick an interval that matches how often you use the data.

Which checks should I run on CRM records?

The HLR lookup for mobile numbers (assigned and reachable, and the current network), the carrier lookup for line type, and the e-mail mailbox check for addresses at major webmail providers. Start with the free estimate to find invalid and duplicate rows.

Should I delete a contact when a check says unreachable?

No. Unreachable means the phone couldn't be reached at that moment, for example because it was switched off. Flag it and check again later. Delete or suppress only on repeated conclusive negative answers, such as an unassigned number or a mailbox that doesn't exist.

Can re-validation tell me whether a number now belongs to someone else?

Not by itself. A check tells you whether a number is assigned and reachable, not who holds it. In the US, the FCC's reassigned numbers database answers whether a number was disconnected after a given date. Re-confirm consent with the person when in doubt.

Do I pay for duplicates and badly formatted numbers?

No. Duplicates and invalid entries are flagged per row and never checked or charged, and neither are unknown answers. The free estimate counts them before you run anything.

Can I use re-validation to make an old purchased list usable?

No. Checks clean data you already have a lawful basis to use. They don't create consent, and the acceptable use policy forbids unsolicited bulk messaging.

Know before you send.

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