# Opt-out hygiene: keeping your internal suppression list tight enough to defend

> A practitioner's guide to building a defensible opt-out suppression list: timestamps, ported numbers, reassigned lines, and periodic revalidation with carrier data.

Published 2026-07-10, updated 2026-10-03 by Marcus Whelan. Canonical: https://checkthatphone.com/blog/opt-out-hygiene-keeping-your-internal-suppression-list-tight-enough-to-defend

## The lawsuit that started with a recycled number

Picture a company that gets sued under the TCPA. It pulls its records, finds a consent record for the number and a clean suppression history, and assumes it's covered. Then opposing counsel asks one question: when did that number get reassigned? The company has no answer. The consent was recorded two years ago. The carrier recycled the number eight months later. Every message since then went to a stranger who never consented to anything.

Consent and suppression records are supposed to prevent that scenario, and a poorly maintained list makes it worse. A list full of stale, unverified entries doesn't protect you. It just gives you false confidence.

## What a defensible suppression record actually needs

At minimum, every opt-out entry needs a UTC timestamp, the raw number as submitted, a normalized E.164 version, and the channel the opt-out came through (SMS STOP reply, web form, phone IVR, etc.). That's table stakes.

What most teams skip is the carrier snapshot at the time of opt-out. If you record that `+12125550198` opted out on 2023-11-14 and you know from your lookup at that moment that `dipPorted` was `"false"` and `dipLrn` was `2125550198`, you have a baseline. If the number later shows a different `dipLrn`, it has been ported since. Porting alone doesn't mean a new owner (more on that below), but it tells you the record needs a second look.

This matters in litigation because in a dispute you want a reasonable, documented basis for believing the person you contacted was the same person who opted in (or that someone genuinely opted out). A timestamp alone doesn't get you there.

## Porting and reassignment are not the same problem

Porting keeps the same person on a new carrier; reassignment puts a new person on the number. People conflate the two. Porting is when a subscriber moves their number from one carrier to another, keeping the same number. Reassignment is when a number is deactivated and later given to a completely different person.

For suppression purposes, a ported number is usually fine. The same person still owns it, just through T-Mobile now instead of Verizon. You check `dipPorted` in the CheckThatPhone response and if it's `"true"`, you also look at `dipLrn`. If the LRN changed but the subscriber profile you hold (name, address, account ID) still matches, you're probably looking at the same person on a new carrier. The opt-out still applies.

Reassignment is the real danger. A deactivated number sits in a pool, gets recycled by the carrier, and goes to someone new. No lookup can tell you who holds a number now, but you can catch the disconnection: `deactivationDate` appears while a number is recently deactivated (about 45 days) and clears once it's reactivated. If you see a deactivation dated after your opt-out timestamp, and a later lookup shows the number active again, that's a red flag. The opt-out may be from the previous subscriber, not the current one. For a definitive check, the FCC's [Reassigned Numbers Database](https://www.reassigned.us/) tells you whether a number was permanently disconnected after a given date.

The `blackList` field is also worth checking here. It comes back `"true"` for numbers on our internal blacklist and for litigator matches. Those numbers shouldn't be contacted regardless of opt-out status, and you should log why you suppressed them separately from a voluntary opt-out.

## Building the revalidation loop

One lookup at signup, one at opt-out, and then nothing forever is how you end up in that deposition. Numbers change. Carriers recycle. People port. You need a periodic revalidation pass.

In practice, I'd break your suppression list into buckets by age. Anything opted out in the last 90 days: leave it alone, it's fresh. 90 days to 18 months: revalidate quarterly. Older than 18 months: revalidate monthly and flag for review.

For large lists, the right tool is the [bulk CSV upload](/bulk-phone-validation) via the CheckThatPhone dashboard (Dashboard → Bulk CSV). You upload your suppression list as a CSV, it deduplicates, runs carrier DIP and line type validation against every row, and returns a downloadable result file. The upload and the result file are deleted within 24 hours, which matters for data minimization. You're not leaving a copy of your contact list sitting on a third-party server.

For real-time checks, say during an opt-out intake flow or before a single outbound call, use the `POST https://api.checkthatphone.com/v1/lookup` endpoint with your `Authorization: Bearer <key>` header. The response gives you `dipPorted`, `dipLrn`, `deactivationDate`, `blackList`, and the `deliverable` flag in one shot. Build that into your opt-out handler so every new suppression entry gets a carrier snapshot baked in at creation time.

## The litigator scrub layer

This is separate from opt-out hygiene but it belongs in the same workflow. Some numbers belong to serial TCPA plaintiffs who sign up specifically to manufacture lawsuits. An opt-out record does nothing for you here because the harm is the contact itself, not the failure to honor an opt-out.

Add `litigatorFilter: true` to your lookup request; the litigator data is refreshed daily. If the response returns `litigator: "true"`, you get `litigator_type` and `litigator_name` as well. Suppress that number entirely and log it separately from your standard opt-outs. Do not commingle them. You want to be able to show in discovery that your litigator suppression is a distinct, proactive control, not something you stumbled into.

More detail on how that flag works is at [/use-cases/tcpa-litigator-scrub](/use-cases/tcpa-litigator-scrub). Your internal opt-out list also isn't the only suppression layer worth automating: the free [state DNC scrub](/use-cases/state-dnc-scrub) covers 38 states plus DC and a complainer list on the same lookup. [Litigator scrub vs DNC registry vs internal opt-out](/blog/litigator-scrub-vs-dnc-registry-vs-internal-opt-out-why-you-need-all-three) lays out how the layers fit together.

## What the carrier data actually costs you to skip

Validating a number through CheckThatPhone at opt-out time costs a fraction of a cent ($0.0009 to $0.005 a lookup, depending on plan). TCPA statutory damages run $500 per violation, up to $1,500 if willful ([47 U.S.C. § 227(b)(3)](https://www.law.cornell.edu/uscode/text/47/227)), and class actions multiply that fast. The math is not close.

The less obvious cost is operational. A suppression list that's never revalidated fills up with numbers that were disconnected long ago, and the opt-outs attached to them may no longer belong to whoever holds those numbers now. Periodic revalidation tells you which entries are dead and which came back to life, so you know which opt-outs still describe a real person.

See [/use-cases/contact-list-hygiene](/use-cases/contact-list-hygiene) for how this fits into a broader list maintenance workflow.

## The minimum viable suppression schema

If you're rebuilding or auditing your suppression table, here's what each row should carry:

- Raw number as entered by the user
- E.164 normalized number
- UTC timestamp of opt-out
- Channel (SMS, voice, web, etc.)
- `dipPorted` value at time of opt-out
- `dipLrn` value at time of opt-out
- `deactivationDate` from most recent revalidation
- `blackList` flag from most recent revalidation
- Last revalidation timestamp
- Suppression reason (voluntary opt-out, litigator flag, deactivated, etc.)

That last field is the one most schemas omit. Mixing voluntary opt-outs with litigator flags with dead numbers in a single undifferentiated list makes it much harder to explain your controls to a regulator or opposing counsel. The same discipline applies on the consent side; see [prior express written consent under the TCPA](/blog/prior-express-written-consent-under-the-tcpa-what-survives-the-2024-fcc-changes).

The [/docs](/docs) reference covers every field returned by the lookup endpoint if you want the full schema while you're building this out. Pricing for bulk validation runs is at [/pricing](/pricing).

## Where to start

Pull your current suppression list. Filter for entries older than 18 months. Run that subset through a bulk CSV validation and look specifically at `deactivationDate` and `dipLrn` changes relative to your opt-out timestamps. That one pass will tell you whether your list is a genuine compliance asset or a liability dressed up as one.

---

CheckThatPhone is a phone validation API for US and Canada numbers: https://checkthatphone.com (docs: https://checkthatphone.com/docs.md, pricing: https://checkthatphone.com/pricing.md).
