Contact list hygiene for CRM and B2B sales

Phone numbers go stale in ways that email addresses don't. A Gmail address that was valid in 2019 is still valid in 2026 — it'll just bounce or sit unread. A phone number that was valid in 2019 may have been disconnected, reassigned to a different person, ported to a different carrier, or all three. By 2026 it is statistically likely to have moved at least once. Standard email-style validation cannot see any of that.

Sales operations and CRM teams treat this as an annual data-decay cost — somewhere between 5% and 15% of records per year, depending on the segment. The cheap fix is a scheduled rescrub: run every phone number in the list through POST /v1/lookup on a cadence, and update the record's status from the fields that actually change.

The fields that flag a stale record

See the full field reference for every signal returned per lookup.

A complete request

One lookup per number — no add-ons needed for hygiene:

curl --request POST \
  --url 'https://api.checkthatphone.com/v1/lookup' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "phone": "4155550100",
    "ip": "136.38.145.14"
  }'

A disconnected or unassigned number returns:

{
  "success": true,
  "credits_used": 1,
  "data": {
    "subscriber": "4155550100",
    "optDate": "2026-05-23T22:01:00.211Z",
    "action": "unsubscribe",
    "deliverable": "false",
    "reason": "Not a valid mobile number",
    "nanpType": "not-mobile",
    "blackList": "false",
    "ipResult": "valid-v4",
    "dip": "success",
    "dipLrn": "4155550100",
    "dipPorted": "false",
    "dipOcn": "MULT",
    "dipCarrier": "MULTIPLE OCN LISTING",
    "dipCarrierSubType": "GENERAL",
    "dipCarrierType": "landline",
    "dipMessagingLookup": "false",
    "dipMessagingEnabled": "false",
    "geoCountry": "US",
    "geoState": "UT",
    "geoCity": "Salt Lake City",
    "geoMetro": 770,
    "geoSource": "ip",
    "timezone": "America/Denver",
    "tzOffset": 7,
    "error": "false"
  }
}

A reassigned number is the trickier case: it answers the call, the SMS goes through, the contact looks reachable — but the human on the other end is somebody new. There's no static sample we can show that's permanently in that state (numbers move in and out of reassignment over time), but the signal is a deactivationDate in the recent past combined with deliverable: "true".

A scoring rule that treats records matching that pattern as "reachable but unverified — pause outreach until we confirm" catches the reassignment problem cleanly without false-positive purging real customers who simply switched carriers. The deactivationDate is the load-bearing signal here.

Wiring it into the CRM

1. Quarterly rescrub job

A scheduled job (cron, dbt, Airflow — whatever owns your data pipeline) pulls every phone number in the CRM that hasn't been verified in the last 90 days, calls /v1/lookup on each, and updates the contact's status fields. Cheap, low-effort, and catches the long-tail decay.

2. On-event verification

Fire the lookup at lifecycle moments — opportunity created, deal closed-won, list added to a campaign. Avoids the "we found out two months later that the number was disconnected" story when you push a stale record into a campaign tool.

3. CSV one-shot

Sometimes you just want to clean a list once and import it. Upload the file straight from your dashboard's bulk uploader — we deduplicate, look up every unique number, and hand back a results CSV with the same fields as the live API alongside your original columns. No SDK or batching code; useful for one-off scrubs, list-buyer QA, and pre-import audits. Up to 1M rows per file.

For continuous validation on new-lead arrival, the live API in workflow 2 is the better fit — the CSV uploader is for existing lists you've already collected.

Inline FAQ

How is this different from email validation?

Email validation checks SMTP reachability; it does not see when a Gmail address gets re-issued (Gmail does not re-issue). Phone numbers do get re-issued. A number that was your customer last year may be answered by a stranger today — email validation cannot detect that, but the deactivationDate and reason fields can.

What does a deactivationDate of "2024-08-12" mean if deliverable is also "true"?

The number was deactivated by its previous owner on that date, then later reassigned to a new subscriber. It is reachable now, but it is not the same person it was on your list. Treat it as a re-verify candidate, not a confirmed contact.

How often should we rescrub?

Phone-number churn in the US runs around 0.5–1% per month, so a quarterly rescrub catches most decay. Lists that drive SMS or outbound calling are worth a monthly cadence — the marginal cost of a single lookup per number is small compared to the cost of contacting wrong people.

Will this clean my emails too?

No — CheckThatPhone is phone-number only. We deliberately do not bundle email validation; we are not the right product for that. Most teams pair us with a dedicated email-validation vendor.

What this isn't

Phone hygiene is not a substitute for consent management. A number can be perfectly reachable and still wrong to contact under TCPA, an internal opt-out, or a DNC list. If your use case is SMS or outbound calling, pair this with the TCPA litigator scrub add-on rather than relying on hygiene alone.

Pricing for this use case

One credit per number, no add-on cost. The math for a rescrub job is easy to predict:

For lists in the millions or per-day rescrub cadence, talk to us about enterprise pricing — we are happy to quote against a real list size and frequency.

Related