A TCPA scrub API checks each phone number against lists of known TCPA litigators and DNC complainers, so your platform can suppress the matches before a text goes out. On Ready, that check costs $0.005 per contact as a standalone scrub, or $0.003 per segment when it runs automatically on every send.

The rest of this post is about wiring it in. It covers what the scrub checks, the two places to call it (on import or right before send), what each placement costs at real volumes, what to do when a real customer matches, and how scrubbing fits with opt-outs, number validation and quiet hours. The examples assume you run a platform (a CRM, a vertical SaaS product, an agency tool) whose customers text their own contacts through sub-accounts. The same logic holds if you only send for yourself.

What a TCPA scrub API actually checks

A single scrub call takes one phone number and checks it against two kinds of list.

  • Known TCPA litigators. These are numbers tied to people who have filed TCPA suits, often more than once. Some of them file for a living. Texting one of them is the most direct path to a demand letter.
  • DNC complainers. These are numbers tied to people who have filed Do Not Call complaints. They have already shown they will report unwanted contact.

When a number matches, it is suppressed, and your platform should not text it.

People often mix these lists up with the National Do Not Call Registry and with your own internal opt-out list. They are three separate things, and passing one doesn't clear you on the others. Our post on the three lists compliance teams confuse covers the differences. The scrubbing docs list exactly what the endpoint checks and the shape of the response.

The call itself is a plain GET:

curl https://api.tryready.com/v1/scrub/+12125550199 \
  -H "X-API-Key: $READY_API_KEY"

We're not going to paste a response body here, because the field names belong in the docs and should not be guessed from a blog post. Read the match result from the response and set your own suppression flag on the contact.

Scrub on import or scrub before send?

You can call the scrub in two places. Each one handles a different risk.

Call site 1: on import

Scrub when a contact enters the system. That covers a CSV upload, a CRM sync, a webhook from a form, or a sub-account bulk-loading its old list. This is the cheapest place to catch the obvious problems, because you pay once per contact and the result follows the contact through every later campaign.

The weakness is that lists go stale. A number that was clean in January can land on a litigator list by March. New suits get filed, complaints get logged and numbers get reassigned. If you only scrub on import, you are trusting an old result. Our post on how fast each list source rots breaks down re-scrub cadence by source. As a rough guide, purchased or co-registered data goes stale fastest, and organic opt-ins from your own forms hold up longest.

Call site 2: immediately before send

The other option is to turn scrubbing on for the account, so every outbound text is screened at send time. You never act on an old result, because the check runs against current lists each time. The cost is that you pay per segment on every send, instead of once per contact.

Which one to pick

PatternBest forWeakness
Scrub on import onlySteady lists, mostly transactional textsResults go stale between imports
Scrub on import + scheduled re-scrubMost platforms sending campaigns monthly or lessYou have to build and run the scheduler
Scrub on every send (account setting)High-churn lists, frequent campaigns, sub-accounts you don't fully trustCost scales with segments and send frequency

For a multi-tenant platform, a sensible default is to scrub on import for everyone. Turn on send-time scrubbing for the sub-accounts whose list sources you can't vouch for.

What it costs: per contact versus per segment

The two prices look the same, $0.005 each, but they count different things.

  • Standalone scrub: $0.005 per contact. You pay when you call it, and only for the numbers you check.
  • Send-time compliance surcharge: $0.003 per segment, added to each send, and only when scrubbing is switched on for the account. It is off by default. Landline validation is a separate $0.003 per segment surcharge, also off by default.

Neither is included in the "all-in" send rate. On Standard, sending costs $0.0075/segment plus a $0.0045 carrier fee per segment.

Worked example

Assume a sub-account with 20,000 opted-in contacts. It sends four campaigns a month, and each text is 1 segment (under 160 GSM-7 characters, no emoji).

Option A: scrub on import, re-scrub monthly

  • Monthly re-scrub: 20,000 × $0.005 = $100
  • Sends: 4 × 20,000 × ($0.0075 + $0.0045). The $0.0075 part comes to $600, plus 80,000 × $0.0045 in carrier fees.

Ready's all-in prices per segment include the carrier fee but not screening: Scrub lists and Number validation, the two switches in Settings under Compliance, each add $0.003 per segment when switched on, shown as screening on your bill, and both are off by default. Unless you turn the opt-out footer off, the first text to each contact, and one again from time to time, also gets "Reply STOP to opt out" and your business name if the message does not already have them, so a text close to the segment limit can bill one more segment.

Option B: send-time scrubbing on

  • Surcharge: 4 × 20,000 × 1 segment × $0.003 = $240
  • Sends: the same as Option A.

So for this list, Option B costs $300 a month more than Option A. In exchange, every send is checked against current lists instead of a result up to a month old.

Segment count changes the math more than most people expect. Add one emoji to a 140-character text and it becomes 3 segments, because an emoji drops the limit to 70 characters (67 per part in a multipart message). The send-time surcharge for Option B then triples to $1,200 a month. The standalone scrub stays at $100, because it charges per contact and ignores message length.

The rule of thumb that follows from this: frequent sends and long or emoji-heavy messages favor a scheduled standalone scrub. Infrequent sends to risky lists favor send-time scrubbing.

What you're paying to avoid

The TCPA allows statutory damages of $500 per text, and up to $1,500 per text if the violation is found willful. A single litigator receiving a five-message drip campaign can therefore claim between $2,500 and $7,500 before legal fees. Scrubbing 20,000 contacts costs $100. We cover the insurance math in more depth in why $0.005 a contact is cheap insurance.

To be clear, scrubbing reduces that risk. It does not make you immune to lawsuits, and compliance remains the sender's responsibility.

False positives: what to do when a real customer matches

Developers often ask about this case: a contact with a real opt-in also shows up on a litigator or complainer list. It happens for a few reasons:

  • Litigators are customers too. Someone who has sued another company may genuinely have signed up for your customer's appointment reminders.
  • Numbers get reassigned. The lists match on phone number, not on the person. A number that once belonged to a serial litigator may now belong to someone else entirely.
  • Complaints aren't verdicts. A DNC complaint shows that someone objected to some contact at some point. It doesn't show they objected to yours.

How you handle a match is a policy decision. Here are three approaches platforms use, from most to least conservative:

  1. Suppress everything that matches. This is the simplest and the safest. You lose a small slice of legitimate contacts. This is the right default for marketing texts.
  2. Suppress for marketing, flag for transactional. Keep matched contacts out of campaigns. Let a human decide whether they should get order or appointment texts, based on the consent record the customer holds.
  3. Override only with documented consent. Allow a send to a matched number only when the customer can produce a specific opt-in for that number: when the person agreed, what wording they saw, and on which page. A matched number is exactly the case where your consent record will be tested.

Whichever approach you choose, don't delete matched contacts. Mark them suppressed and record why, so a later import can't quietly bring them back. Also remember that a match means the number is risky. A clean result does not mean the number is safe, because no list is complete. Scrubbing is one layer, not the whole answer.

How scrubbing fits with opt-outs, validation and quiet hours

A scrub checks lists from outside your system. Your opt-out list is the record of people who told you directly to stop. Both have to be in place, and on Ready they work together like this.

  • Opt-outs. When a contact replies STOP or UNSUBSCRIBE, the opt-out is honored and applied everywhere, so the contact can't be texted again by any campaign. You can read opt-outs with GET /v1/opt-outs or check a single number with GET /v1/opt-outs/:phone. If a send targets an opted-out number, it is refused up front and you are not charged.
  • Number validation. GET /v1/validate/:phone tells you whether a number is a mobile, a landline or disconnected before you text it. Known landlines are refused at send and not charged. Validating on import still keeps your contact counts and reports accurate. See our phone number validation API post.
  • Quiet hours. An API send outside permitted local hours (based on the recipient's area) is held if the window opens within 6 hours, and charged only when it goes out; otherwise it is refused with 409 QUIET_HOURS_BLOCK and your pipeline must resend it. A text to a clean, consented number can still create risk if it arrives at 6 AM.
  • Consent attestation. Set consent_attested: true on every send through POST /v1/messages or /v1/messages/bulk; Ready then records who sent, to how many, and when. A send without it still goes out today, with a warning, and leaves no attestation. That record is an audit trail of the sender's promise. It is not a per-contact consent record. The opt-in time, wording and page URL for each contact have to live with the customer who collected them.

Put together, a send pipeline on import looks like this: validate → scrub → store result. At send time it looks like this: check suppression flag → send with consent_attested → let Ready refuse opt-outs and landlines, and hold or refuse quiet-hour sends (handle the 409).

curl -X POST https://api.tryready.com/v1/messages \
  -H "X-API-Key: $READY_API_KEY" \
  -H "Idempotency-Key: 3f6c1e9a-8b2d-4c7e-9a1f-2d5b8e0c4a71" \
  -H "Content-Type: application/json" \
  -d '{"to": "+12125550199", "body": "Your order #1042 has shipped.", "consent_attested": true}'

The Idempotency-Key makes sure a retry after a timeout never sends the same text twice. That's easy to forget until a litigator receives a duplicate.

Wiring it into a multi-tenant platform

If your customers text through sub-accounts, each with its own numbers and 10DLC registration, a few design choices help:

  • Store scrub results per sub-account, not globally. One customer's consent record doesn't extend to another customer's contact, even when the phone number is the same.
  • Set send-time scrubbing once at the agency. Every new sub-account starts with your choice, so you only change it for the few clients whose list sources you can't vouch for.
  • Expose the reason for each suppression in your UI. "Suppressed: litigator match" stops a customer from opening a support ticket asking why 40 contacts never got the campaign.
  • Bill it transparently. Charges are itemized and prepaid through Stripe, so you can pass scrub costs through to your customers or absorb them, and the line items show which is which.

What a scrub does not do

Being honest about the limits will save you a bad assumption later:

  • It doesn't create consent. Cold contact belongs on the phone and in the mail. SMS should go to contacts who opted in or who replied to you.
  • It doesn't fix a list with no consent behind it. Scrubbing a purchased list removes the most litigious numbers, but the rest of the list still lacks consent.
  • It doesn't replace registration. Unregistered traffic gets filtered by carriers whether or not the list is clean.
  • It isn't permanent. Re-scrub on a schedule that matches how fast your list sources go stale.

The practical takeaway

Scrub on import, because $0.005 per contact is the cheapest compliance step you will run. Re-scrub on a schedule, or switch on send-time scrubbing for risky sub-accounts, but do the segment math first, since emoji and long messages multiply the per-segment surcharge. Suppress matches instead of deleting them, and record why. Let opt-outs, landline refusal and quiet hours handle the rest of the screening.

If you want to test it, the scrubbing docs cover the endpoint, and you can create an account and scrub a sample of your own list before you change your pipeline.

FAQ

What does a TCPA scrub API check?

It checks a phone number against lists of known TCPA litigators and DNC complainers, and flags any match so you can suppress it before texting. It is separate from your internal opt-out list. It doesn't prove that a clean number is safe to text without consent.

How much does a TCPA and DNC scrub cost per number?

On Ready, a standalone scrub costs $0.005 per contact, and you pay only for the numbers you check. If you switch scrubbing on at send time instead, it adds $0.003 per segment to each text. That surcharge is off by default.

Should I scrub my list on import or before every send?

Scrub on import for every list, then either re-scrub on a schedule or turn on send-time scrubbing for high-risk lists. Import-only results go stale as new suits and complaints are filed. Send-time scrubbing stays current but costs more as segment counts and send frequency grow.

What if a customer who opted in shows up as a litigator match?

Treat it as a policy decision, not an automatic send. Most platforms suppress matches from marketing texts and allow a send only when the customer holds a specific, documented opt-in for that number. Either way, keep the contact marked as suppressed instead of deleting it.

Does scrubbing protect me from TCPA lawsuits?

No. Scrubbing reduces your risk but doesn't make you immune. It removes the numbers most likely to sue, but compliance still depends on real consent, honoring opt-outs, respecting quiet hours and registering your traffic. The sender remains responsible for all of it.