The problem scales faster than most teams expect
You send 800 calls in January without any validation and nothing bad happens. So in February you send 2,000. Then a litigator on your list picks up, documents the call, and you’re looking at a TCPA demand letter before Q2. Statutory damages start at $500 per violation and can reach $1,500 if the violation was willful or knowing (47 U.S.C. § 227(b)(3)). One bad list can wipe out months of campaign margin.
The frustrating part is that the right validation approach at 800 calls a month looks nothing like what you need at 100,000. Most teams either under-invest early or bolt on an expensive real-time pipeline before they actually need it. This is a playbook for matching your scrubbing strategy to your actual volume.
Tier 1: under 5,000 calls per month
At this volume, a pre-flight batch scrub before each campaign is completely sufficient. You are not running continuous outreach. You are probably working from a CRM export or a purchased list, and the list changes infrequently.
The right move here is CheckThatPhone’s bulk CSV verification. Upload your list from the dashboard (Bulk CSV), and the job deduplicates and validates every unique number: carrier lookup, line type via dipCarrierType and nanpType, deliverability flags including deliverable and blackList, and optionally the litigator add-on. The result file comes back downloadable, and both the upload and the result file are hard-deleted within 24 hours.
For a list of 2,000 numbers, this costs a fraction of what a single TCPA demand letter costs. If you’re running an SMS campaign, keep only rows where action is "send". For voice, drop rows where blackList is "true", and turn on the litigator add-on (litigatorFilter: true in the API) to catch known serial litigants. The litigator field comes back on any flagged number, along with litigator_type and litigator_name so you can log the specific risk.
A common mistake at this tier: teams scrub once when they build the list and then reuse it for three months. Number portability and deactivations mean a list degrades. A number that goes dark shows a deactivationDate for a while, then clears once the carrier reactivates it, possibly for someone new, so a three-month-old scrub can miss the whole episode. Scrub before every campaign send, not once at list acquisition.
The federal Do Not Call rules have their own cadence. To rely on the safe harbor, telemarketers must use a copy of the National Do Not Call Registry obtained no more than 31 days before the call (47 CFR 64.1200(c)(2)(i)(D); the FTC’s Telemarketing Sales Rule, 16 CFR 310.4(b)(3)(iv), says the same). Our API doesn’t check the federal registry, so scrub it separately. It does run free state DNC checks for 38 states plus DC.
Pricing for batch lookups at this volume is low enough that there is no real tradeoff. See the pricing page if you want to run the math.
Tier 2: 5,000 to 50,000 calls per month
Here the CSV workflow still works, but the operational shape changes. You are probably running multiple campaigns in parallel, your list is being refreshed from a lead source or CRM sync on some schedule, and manual uploads become a bottleneck.
The right pattern is an automated pre-flight job. A script pulls the new or updated numbers from your CRM or database, calls POST https://api.checkthatphone.com/v1/lookup per number (or exports them to a CSV for the dashboard uploader), writes the results back, and gates campaign enrollment on clean status. Run it nightly or on list-change events.
At this tier you care more about the carrier dip fields. dipCarrier and dipCarrierType tell you which carrier currently owns the number. dipPorted tells you if it has moved since it was first issued. A ported mobile number that now sits on a regional MVNO is a different deliverability risk than a stable T-Mobile line. If you’re using 10DLC registered traffic, knowing the carrier in advance lets you route or suppress traffic intelligently rather than learning about delivery failures after the fact.
For landline numbers where you want to know if SMS is possible anyway, pass landlineSmsLookup: true. The response adds dipMessagingLookup, dipMessagingEnabled, and dipMessagingProvider. About 7% of landlines we check are SMS-capable; the rest can’t take a text. Checking in advance avoids wasted sends and protects your sender reputation. Why your SMS campaign is silently dropping landlines goes deeper.
The latency tradeoff here is minimal. The /v1/lookup endpoint is fast enough that a pre-flight job processing 10,000 numbers overnight is not a bottleneck. The accuracy tradeoff is the same as Tier 1: you are scrubbing at job-time, not at send-time, so a number deactivated in the window between your scrub and your send will still slip through. At this volume, that is an acceptable risk if your job cadence is tight (24 hours or less before send).
The action field in the response is worth building your filtering logic around directly. It gives you an explicit recommended action rather than requiring you to combine multiple flags yourself.
Tier 3: 50,000+ calls per month
At this scale, pre-flight scrubs are necessary but not sufficient. Lists refresh constantly from multiple sources. Leads come in through web forms, partner feeds, and API integrations. A number that was clean at midnight may be a litigator-held line by the time your campaign fires at 10 AM.
You need on-the-fly validation at send-time, or as close to it as operationally feasible. A pattern that works: validate at lead ingestion (to catch obvious bad data early), run the pre-flight batch job to catch list-level issues, and then do a final spot-check lookup via the /v1/lookup endpoint immediately before a number enters the dialer queue.
Yes, this adds latency to your campaign pipeline. A single lookup call is fast, but if you’re injecting into a real-time dialer, you need to build the async handling correctly so validation doesn’t block the queue. The cost per lookup at 100K+ volume is worth running against your TCPA exposure. One litigator claim starts at $500 in statutory damages, which is more than the 100K plan’s $100 monthly price. The ROI math of running a litigator filter works through the numbers.
The ipResult and geoState fields become more useful here too. If a lead signed up with a Florida area code but the IP geolocation shows Montana and dipPorted is "true", that’s a pattern worth flagging for manual review before you call. It doesn’t necessarily mean fraud, but it surfaces mismatches that matter for your compliance documentation.
At this tier you should also be logging every lookup response and storing the key fields (dipCarrierType, deliverable, blackList, litigator, dipCarrier, dipPorted, action) against the contact record. If you ever face a TCPA claim, being able to show that you ran a litigator check at a specific timestamp is actual evidence of reasonable diligence.
See the TCPA litigator scrub use case for more detail on what that documentation workflow looks like.
Matching integration shape to volume
The point is not that every team needs real-time lookups. It’s that the right answer depends on how fast your list changes relative to how often you call into it.
Slow list, low volume: batch CSV before each send. Fast-changing list, high volume: real-time lookup at queue injection plus a nightly batch for the full list. Somewhere in between: an automated pre-flight job that runs on a tight cadence and writes results back to your CRM.
The API docs cover the full request and response schema and every add-on flag. Start there before you design your pipeline.