Bulk phone number validation for outbound sales teams
Send your call list to one endpoint, get back clean E.164 numbers segmented by line type — and a straight answer about what validation can't confirm.
Contents
You have a list. Maybe it came from a web form, a scraped directory, a purchased file, or three years of CRM sediment. Some of those numbers are typos, some are toll-free lines that will never reply to a text, and a few are landlines you are about to feed into an SMS tool. Bulk phone number validation is the step that sorts the file before your dialer — and your SMS bill — sorts it for you. One job, the whole list, one clean file back.
Here is how to run it, what you get back, and the part most vendors gloss over: what the result does not tell you.
What one job actually does
Send Boundstone a CSV of numbers and each row comes back with three useful things: whether the number is even possible for its region, the same number normalized to E.164 (+16504472983, the format every dialer and SMS API expects), and its line type from the numbering plan — mobile, fixed line, toll-free, VoIP, premium rate, and so on.
That lets you do two concrete things before you spend a dial or a message:
- Drop the impossible. Wrong digit counts, dead area codes, fat-fingered entries — gone. These cannot connect, so there is no reason to pay to find that out on the phone.
- Segment by line type. Route mobiles to your SMS platform, keep landlines on the human dialer, and pull toll-free numbers you should not be cold-texting anyway.
This is metadata-grade validation. It removes what cannot be valid and labels what remains. It does not promise the phone is ringing on someone's nightstand — more on that below.
Send the whole list: POST /v1/bulk/phone
Post your file as raw CSV. You get an HTTP 202 and a job_id immediately; the work runs in the background.
curl -X POST https://api.boundstone.io/v1/bulk/phone \
-H "Authorization: Bearer bs_live_YOUR_KEY" \
-H "Content-Type: text/csv" \
--data-binary @call-list.csv
When the job finishes, pull the results as a CSV:
curl https://api.boundstone.io/v1/bulk/JOB_ID/results.csv \
-H "Authorization: Bearer bs_live_YOUR_KEY"
Free accounts run up to 250 rows per job; paid accounts run up to 10,000. One credit is reserved per row, and any row that errors is refunded — you pay for answers, not for failures. The free tier is 250 credits a month, no card, and the credits never expire, which is enough to clean a small list end to end before you commit to anything.
Read the results
Each row echoes the verify fields: valid, e164, country, line_type, and national_format.
phone,valid,e164,country,line_type,national_format
+16504472983,true,+16504472983,US,fixed_line_or_mobile,(650) 447-2983
+447700900123,true,+447700900123,GB,mobile,07700 900123
+18005550199,false,+18005550199,US,unknown,(800) 555-0199
not-a-number,false,,,,
Look at row three. 800-555-0199 is perfectly well-formed and sits in a real toll-free area code — a format-only checker waves it straight through. It comes back false because it falls in the reserved 555-01XX range, which cannot be assigned to anyone. Those are the rows that quietly survive a cheap validation pass and then get dialled.
Now row one. In North America the numbering plan often cannot separate mobile from landline, so the honest answer is fixed_line_or_mobile — not a coin flip dressed up as certainty. Treat those as "could be either," not "mobile." Want to eyeball a single number first? The phone validator runs the same check in your browser, no key.
Route by line type
Once every row carries a line type, your segmentation writes itself:
mobile→ SMS platform or power dialer.fixed_line→ human dialer; do not text it.fixed_line_or_mobile→ your call, but know it is a guess if you SMS it.toll_free/premium_rate→ pull out of a cold outbound list.
That is the whole hygiene loop: normalize, drop the impossible, sort the rest. For the longer playbook on doing this before a campaign, see how to clean a phone list before calling, and for the full outbound wiring, the outbound sales use case.
No code? Upload the CSV in the dashboard
You do not need a script. The dashboard has a CSV upload and a paste box — drop in a file or paste numbers one per line, pick phone, and download the same results CSV. Same 250-row free cap, same per-row refund on errored rows.
What "valid" does not mean
Here is the boundary, stated plainly, because it changes how you should use the output.
A valid result means the number is well-formed and possible for its region and carries a line-type label. It does not mean the number is currently in service, reachable, answered, or still on the carrier it was born on. Confirming that needs a live carrier or HLR lookup, and Boundstone does not do it today. Every response says so, in fields you can read:
"checks": {
"performed": ["format", "region", "line_type_metadata"],
"not_performed": ["carrier_lookup", "ported_status", "hlr_liveness"]
}
Two more honest edges. Line type is the number's designated type in its numbering plan, not a live network probe — a VoIP line that was ported into a mobile range still looks like a mobile to metadata. And validation is not compliance: Boundstone is a data-hygiene tool, not a DNC scrubber and not legal advice. For Do-Not-Call and TCPA obligations you need the official registries and your own counsel. Validation drops the junk; it does not clear you to dial.
The short version
- Bulk phone number validation in one call:
POST /v1/bulk/phonewith a CSV, or upload it in the dashboard. - Get back
valid,e164,country,line_type,national_formatper row. - Clean before you dial. Drop impossible numbers, normalize to E.164, route mobiles to SMS, and skip toll-free.
- Bulk sizing. 250 rows per job free, 10,000 paid; one credit per row, refunded on error.
- It confirms the number is possible, not live. It labels the line too. Liveness is a live carrier lookup (
carrier_lookup,hlr_liveness), available as a paid opt-in withhlr:trueat 5 credits.