A phone number validation API tells you, before you send, whether a number is a mobile that can receive texts, a landline that can't, or a number that is no longer in service. Run it when a number enters your system and again before you send a campaign to an old list, and you stop paying for texts that were never going to arrive.
If you run a platform that texts on behalf of your customers, you inherit their lists. That means CSVs exported from a CRM someone stopped maintaining in 2021, web forms where people typed their office line, and contact records where half the "mobile" fields hold a front-desk number. None of that is your customer's fault, and none of it shows up until the campaign goes out and the failures come back. Validation is how you find those numbers on import instead of in the delivery report.
What a phone number validation API actually checks
Different providers return different fields, so read the docs for the exact response. The checks themselves fall into a few categories that matter for texting.
Format and plausibility
This is the cheapest check and the one most forms already do badly. Is it a real North American number shape? Is the area code assigned? Is it a 555 placeholder, or a string of nines someone typed to get past a required field? Normalizing to E.164 (+12125550199) at this stage saves you from duplicate contacts that differ only by a dash.
Line type
This is the check that saves money. The broad buckets are:
- Mobile: can receive SMS. Text it.
- Landline: generally can't receive SMS. Don't text it. Route it to a call or mail if the contact has consented to those.
- VoIP: a mixed bag. Some VoIP numbers receive texts fine, others don't. Many app-based and business phone numbers are VoIP. Dropping every VoIP number by default will cut real, reachable contacts, so treat it as "send, but watch the result" rather than "suppress."
- Toll-free: usually a business line. It rarely belongs on a consumer marketing list.
Disconnected or unassigned
A number can be correctly formatted and correctly typed as mobile and still be dead because the person cancelled the line. Sends to unassigned numbers fail at the carrier. You still pay in throughput, and depending on your provider, you may also pay in segments.
Why texting landlines costs more than the segment
The obvious cost is the text itself. The less obvious cost is what a high failure rate says about your sending.
Carriers filter traffic based on patterns. A campaign where a noticeable share of sends hit landlines and unassigned numbers looks like a purchased or stale list, which is exactly the traffic carrier filtering exists to catch. Your 10DLC registration says you send to consented contacts. A delivery pattern full of dead numbers argues otherwise. Registration does not protect you from content-level and pattern-level filtering. We cover that gap in why approved campaigns still get filtered.
There's also a reporting cost. Dead numbers inflate your "sent" count and muddy your metrics. If you're already squinting at the gap between sent, delivered and actually read, the delivery-receipt post explains what each status confirms. Validating first removes one whole class of noise from that report.
The third cost is throughput. Every segment you push to a landline uses part of your per-second rate and, on T-Mobile, part of your daily brand cap. A fresh standard campaign with no vetting gets roughly 1 to 4 segments per second. Spending that on numbers that can't receive anything is a poor use of a narrow pipe.
The math on a stale import (worked example)
Here is an example with stated assumptions, not a measured result.
Assumptions:
- A customer on your platform imports 20,000 contacts from an old CRM.
- 10% of the list is landlines or disconnected numbers. This is an assumption for illustration. Real lists vary widely by source and age.
- The message is 210 GSM-7 characters with no emoji, which makes it 2 segments (153 characters per segment once a message splits).
- They send one campaign a week.
- Rates are Ready Standard: $0.0075/segment plus a $0.0045 carrier fee per segment.
Dead numbers per campaign: 2,000 contacts × 2 segments = 4,000 segments.
On a provider that bills every attempt, that is 4,000 × $0.0075 = $30 in rate per campaign, plus 4,000 × $0.0045 in carrier fees. Over 52 weekly campaigns, the rate portion alone is 52 × 4,000 × $0.0075 = $1,560 a year spent on numbers that cannot receive a text.
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.
On Ready, known landlines are refused up front and not charged. That shrinks the direct waste on the landline share. Disconnected numbers and the deliverability pattern are a separate problem, so validation still pays for itself in filtering risk even where the per-text waste is smaller. If you're on another provider, check whether failed sends to unassigned numbers are billed.
The honest tradeoff on per-segment validation
Ready has an account-level landline validation option. When it's switched on, it adds $0.003 per segment. It's off by default. Applied to the live part of this list, the cost is:
- 18,000 live contacts × 2 segments = 36,000 segments
- 36,000 × $0.003 = $108 per campaign
That is more than the direct waste it prevents in this example. The reason is that the surcharge applies to every segment of every send, not once per contact.
Validating through the API is billed per number instead: $0.003 for each number that gets an answer, so checking all 20,000 contacts once costs up to 20,000 × $0.003 = $60. For a stable list you text often, validating once on import through the API usually makes more sense. The per-segment switch fits better where lists churn constantly, or where sub-accounts upload their own CSVs and you can't put a check in front of every import. Run your own numbers before you pick one.
Single checks vs bulk checks
The same lookup serves two very different moments, and they have different requirements.
| Single check | Bulk check | |
|---|---|---|
| When it runs | A number enters through a form, an API call or a manual add | A list import, migration or pre-campaign cleanup |
| What matters | Latency: the user is waiting on a form | Throughput and job tracking: thousands of numbers at once |
| What you do with the result | Prompt "that looks like a landline, got a mobile?" inline | Tag, suppress or route rows before anyone sends |
| Failure mode to plan for | Lookup timeout, so accept the number and validate async | Partial completion, so make the job resumable |
The single check at capture is the highest-value spot. You get to ask the person for a better number while they're still on the page. Once they've left, a landline is just a dead row.
The bulk check is where most of the cleanup happens on a platform, because that's where inherited data arrives. Run it as a background job, write the line type onto the contact record, and let campaign audience filters exclude non-mobile numbers by default. For batch options, see the docs at https://docs.tryready.com/api/validate-numbers.
Where validation sits in a platform's pipeline
If you're building texting into a CRM or vertical SaaS product, validation shouldn't be a button a user remembers to press. It belongs at fixed points in the data flow:
- At capture. Run a single check on form submit or contact create. Store the line type and the date you checked it.
- At import. Run a bulk check on every CSV or migration, per sub-account. Each customer's data quality stays scoped to their own sub-account and doesn't drag down another's sending.
- Before a campaign to an old segment. Numbers you validated a year ago may be disconnected now. Re-check anything past your staleness threshold before it goes into a campaign.
- At send. This is the last net, not the first. On Ready, known landlines, opt-outs and numbers on your Ban list are refused at send time and not charged. Don't rely on the send call as your only filter, because by then the campaign is already built and the user is already looking at a lower count than they expected.
Steps 1 and 2 do most of the work. Step 3 is what teams skip, and it's why a list that was clean on import is dirty a year later. Phone numbers decay, and consent decays faster. If you're deciding whether to keep texting old contacts at all, the re-engagement vs delete math is worth running alongside validation.
For the broader integration pattern (auth, idempotency, webhooks), our SMS API integration walk-through covers the plumbing around these calls.
What validation doesn't tell you
This is the part buyers most often get wrong. A validation result describes the line. It says nothing about the person or their permission.
| Check | Answers | Doesn't answer |
|---|---|---|
| Number validation | Is this a mobile? Is it in service? | Did this person agree to texts? |
| DNC / litigator scrub | Is this number on a Do Not Call or known-litigator list? | Is the line live? |
| Opt-out list | Did this contact text STOP to you? | Anything about other senders |
| Consent record | When and how did they opt in? | Whether the number still belongs to them |
Two gaps are worth calling out:
- Validation is not consent. A perfectly valid mobile number still needs a documented opt-in before you text it. Validation makes your consented list cleaner. It does not turn a cold list into a textable one. Cold outreach goes by phone and mail, and SMS goes to people who opted in or replied.
- Valid doesn't mean same owner. Disconnected numbers get reassigned. A number that validates as an active mobile today may belong to someone other than the person who opted in. The FCC's Reassigned Numbers Database exists for exactly this question, and it's a separate check from line type.
The scrub is also separate. Ready's standalone TCPA and DNC litigator scrub is $0.005 per contact, and it checks each number against known TCPA-litigator and DNC-complainer lists. As an account-level option, scrubbing is $0.003 per segment when switched on, and it's off by default. If you're unclear which list covers what, the three lists compliance teams confuse untangles them. None of these checks makes you immune to a TCPA claim. Compliance stays the sender's responsibility, and these tools reduce risk.
How it works on Ready
Validation is one call:
GET https://api.tryready.com/v1/validate/:phone
X-API-Key: <your key> The response fields and the batch options are documented at https://docs.tryready.com/api/validate-numbers. Read them there rather than coding against a guess.
When you send, the request carries your consent attestation:
POST https://api.tryready.com/v1/messages
X-API-Key: <your key>
Idempotency-Key: <any UUID>
{"to": "+12125550199", "body": "Your order #1042 has shipped.", "consent_attested": true} If that number is a known landline, an opt-out or blocklisted, the send is refused and not charged. If it arrives during the recipient's quiet hours, an API text is held only if their window opens within 6 hours; otherwise it is refused with 409 QUIET_HOURS_BLOCK and you resend it in their daytime. A held text is charged only when it sends.
Since we make Ready, here's the fair comparison. Twilio and other CPaaS providers sell lookups too, and if your stack already lives there, their lookup will do the job. Where Ready differs is that validation sits next to registration, sub-accounts, scrubbing, quiet hours and opt-out handling in one API. You don't have to stitch those together yourself.
FAQ
What is a phone number validation API?
It's an API that checks a phone number before you contact it and reports whether it's validly formatted, what line type it is (mobile, landline, VoIP) and whether it's still in service. Platforms call it on form submit and on list import so dead and non-textable numbers never reach a campaign.
Can you send a text message to a landline?
Generally, no: most landlines can't receive SMS, so the text fails or is converted by some carriers into something the recipient won't act on. On Ready, known landlines are refused at send and not charged. Validating on import still keeps them out of your counts and your campaign planning.
How do I check if a phone number is disconnected before texting?
Run it through a validation lookup, which reports whether the number is currently in service. Re-check older contacts before each campaign, because a number that was live when you collected it can be disconnected months later.
Does phone number validation replace a DNC scrub?
No. Validation checks the line, while a DNC and litigator scrub checks whether the number is on a Do Not Call or known-litigator list. You need both, plus a documented opt-in, because a valid mobile number can still be one you shouldn't text.
Should I validate numbers in bulk or one at a time?
Do both, at different points. Validate one at a time when a number is captured, so you can ask the person for a better one, and in bulk when a list is imported or migrated. The bulk run catches inherited bad data before anyone builds a campaign on it.
The practical takeaway
Put validation where numbers enter your system, not where messages leave it. Check single numbers at capture, check every import in bulk, re-check old segments before a campaign, and let send-time refusal catch whatever slips through. Keep in mind that a valid number is not a consented contact and not always the same owner.
If you want to try the flow end to end, the docs above have the request shapes. A new Ready account gets its first 20 one-to-one texts free (a card on file is required to send), so validate a sample of your real list and send to the mobiles before you decide anything. You can create an account here.