API DOCUMENTATION

Validate phone numbers with one API call

A simple REST API that returns validity, line type, carrier, messaging provider, location and a risk score for any number.

Quick start

  1. Create a free account. You get 100 free lookups, with no card needed.
  2. Copy your API key from API keys in your dashboard.
  3. Send a request to POST /v1/validate, as shown below.
Request
curl -X POST https://api.smartphonevalidator.com/v1/validate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"phone": "+1 212 555 1234"}'

The base address for every call is https://api.smartphonevalidator.com/v1. Requests and responses are JSON, except bulk file upload (a form upload) and bulk download (a CSV file).

Authentication

Send your API key with every request, in either header:

Headers
X-API-Key: YOUR_API_KEY
# or
Authorization: Bearer YOUR_API_KEY
Keep your key secret. Call the API from your server, not from browser code, and rotate the key in your dashboard if it leaks.

Validate a number

POST https://api.smartphonevalidator.com/v1/validate

FieldTypeDescription
phoneRequiredstringThe number to check. Any common format works: +1 212 555 1234, (212) 555-1234, 00442079460018.
defaultCountryOptionalstringTwo-letter country code (for example GB) used when the number has no + country code.
Response · 200 OK
{
  "success": true,
  "data": {
    "isValid": true,
    "e164": "+12125551234",
    "countryCode": "US",
    "countryName": "United States",
    "dialCode": "+1",
    "flag": "🇺🇸",
    "location": "New York, NY",
    "timezone": "America/New_York",
    "lineType": "landline",
    "carrier": "Verizon New York, Inc.",
    "messagingProvider": "Bandwidth.com CLEC, LLC",
    "isDisposable": false,
    "riskScore": 4,
    "riskFlags": [],
    "latencyMs": 142,
    "invalidReason": null
  },
  "meta": {
    "balanceMicros": 24997000,
    "balance": "$24.997",
    "freeLookups": 0,
    "priceMicros": 4000
  }
}

A number that is not valid is still a normal 200 response, charged like any other check. It has isValid: false, and invalidReason tells you why.

Example · an invalid number (shortened)
{
  "success": true,
  "data": {
    "isValid": false,
    "e164": "+12125550100",
    "lineType": null,
    "carrier": null,
    "messagingProvider": null,
    "riskScore": 100,
    "riskFlags": ["fictional_number"],
    "invalidReason": "LAST FOUR DIGITS 0100 ARE RESERVED FOR FICTIONAL USE AND NOT IN SERVICE",
    ...
  }
}

Besides data, every successful response has a meta block with your wallet:

meta fieldMeaning
balanceYour remaining wallet balance as text, for example "$24.997".
balanceMicrosThe same balance as a whole number of millionths of a dollar (24997000 = $24.997). Use it for exact maths.
freeLookupsFree lookups you have left. They are used before the wallet.
priceMicrosPrice of one lookup in millionths of a dollar (4000 = $0.004).
count, lookupsChargedBatch only: numbers you sent, and numbers charged. A number repeated in the same batch is charged once.

Response fields

Fields inside data. A field is null when the information isn't available for that number.

FieldTypeDescription
isValidbooleantrue if the number is real and correctly formed for its country.
e164stringThe number in E.164 format, for example +12125551234. The best format to store.
countryCodestringTwo-letter country code, for example US.
countryNamestringCountry name.
dialCodestringInternational dial code, for example +1.
flagstringCountry flag emoji, handy for UIs.
locationstring | nullCity or area the number was issued in, when available.
timezonestringTimezone for the number, for example America/New_York.
lineTypestring | nullWhat kind of line it is: mobile, landline, voip, tollfree, premiumrate or unknown.
carrierstring | nullThe network that provides voice service for the number, when available.
messagingProviderstring | nullThe company that handles text messages (SMS) for the number. See the section below.
isDisposablebooleantrue if the number looks like a temporary or throwaway number.
riskScorenumber0–100. Lower is safer. See the Risk Score guide.
riskFlagsstring[]Reasons that raised the score (see Risk flags). Empty when nothing was found.
latencyMsnumberHow long the check took, in milliseconds.
invalidReasonstring | nullWhy the number is invalid, in plain English. null for valid numbers.

Line type

lineType is one of these values. Handle values you do not recognise gracefully.

ValueMeaning
mobileA mobile phone. Can receive texts.
landlineA fixed line. Most landlines cannot receive texts, unless the owner has set up text service (see messagingProvider).
voipAn internet-based number. Often used for texts, and often used for throwaway accounts.
tollfreeA toll-free business number, such as 800 or 888.
premiumrateA premium-rate number that charges the caller.
unknownThe line type could not be determined.

Messaging provider

messagingProvider names the company that handles text messages (SMS) for a number. It answers a question that carrier cannot. carrier is the company that provides voice service for the number, and for a landline or VoIP number that is often not the company that receives its texts.

  • Where it is returned. US and Canadian numbers (+1), when the number is a landline or VoIP number that has text service set up. Example: a business landline whose texts are handled by a cloud messaging company.
  • Where it is null. Mobile numbers (texts go through the mobile carrier shown in carrier), numbers outside the US and Canada, and numbers with no text service.
  • Why it matters. A landline that returns a messagingProvider can usually receive texts. A landline without one usually cannot, so you can skip it in an SMS campaign, or call it instead.
  • Bulk files. The same value is in the messaging_provider column of the results CSV.
A messagingProvider shows that text service is set up for the number. It is not a guarantee that a particular text will be delivered.

Risk flags

Values you may see in riskFlags. Treat the list as open-ended: new flags can be added, so handle unknown values gracefully. For how they affect the score, see the Risk Score guide.

voipInternet-based (VoIP) number
voip_carrierCarrier is a known VoIP provider
disposable_numberTemporary or throwaway number
toll_freeToll-free business number
premium_ratePremium-rate number that charges the caller
caribbean_premium_trapCaribbean number often used for call-back fraud
repeated_digitsDigits like 1111111111
sequential_digitsDigits like 1234567890
pattern_digitsOther made-up looking patterns
short_numberUnusually short for its country
unknown_carrierNo carrier could be found
high_risk_countryCountry with high fraud rates
fictional_numberReserved for films and examples, such as 555-01xx
service_numberDirectory or service line, not a customer phone
unassigned_prefixThe area code or prefix has not been assigned
unassigned_numberThe prefix exists but this number is not assigned
reserved_prefixPrefix reserved for special use
fake_numberThe network reports that the number does not exist
invalid_formatThe number could not be read as a phone number

Batch: up to 100 numbers

POST https://api.smartphonevalidator.com/v1/validate/batch. Send a phones array of up to 100 numbers. Results come back in the same order, with the same fields as a single lookup. A number that appears twice in the same request is charged once.

Request
curl -X POST https://api.smartphonevalidator.com/v1/validate/batch \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"phones": ["+14155552671", "+447911123456"]}'
Response · 200 OK
{
  "success": true,
  "data": [ { "isValid": true, "e164": "+14155552671", ... },
            { "isValid": true, "e164": "+447911123456", ... } ],
  "meta": {
    "count": 2,
    "lookupsCharged": 2,
    "balance": "$24.989",
    "freeLookups": 0
  }
}

Bulk CSV or Excel

For large lists, upload a file and collect the results when it is done. A file runs in the background, so you can upload it and come back later. We also email you when the job finishes.

The file

  • Format. CSV, or Excel (.xlsx, read from the first sheet). Old .xls files are not supported: save them as .xlsx or CSV. A very large Excel file can be refused with a message to save it as CSV, which has no size limit.
  • Phone column. If the column is named phone, number, mobile or tel, it is found automatically. Otherwise, or when the file has several phone columns, send the column name in the form field phoneColumn, for example Cell Phone. A file without a header row can use Column 1, Column 2 and so on. Only that column is validated and charged.
  • Blank cells and repeats. Rows with no number are skipped and counted in meta.rowsWithoutPhone. A number that appears more than once is charged once, and every row still gets a result.
  • Several files. You can have up to 5 files waiting or running at the same time.

1. Upload

Request
curl -X POST https://api.smartphonevalidator.com/v1/bulk/upload \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "[email protected]" \
  -F "phoneColumn=Cell Phone"
Response · 202 Accepted
{
  "success": true,
  "data": {
    "jobId": "bj_1a2b3c4d",
    "pollUrl": "/v1/bulk/bj_1a2b3c4d"
  },
  "meta": { "lookupsCharged": 4980, "rowsWithoutPhone": 20, ... }
}

The upload is accepted, charged and queued. Keep the jobId.

2. Check the status

Request
curl https://api.smartphonevalidator.com/v1/bulk/JOB_ID \
  -H "X-API-Key: YOUR_API_KEY"
Response · 200 OK
{
  "success": true,
  "data": {
    "jobId": "bj_1a2b3c4d",
    "status": "done",
    "fileName": "contacts.csv",
    "totalRows": 5000,
    "processed": 5000,
    "progressPct": 100,
    "validCount": 4410,
    "riskyCount": 312,
    "invalidCount": 278
  }
}
statusMeaning
queuedWaiting its turn. Your file starts as soon as a worker is free.
processingBeing validated. Watch processed and progressPct.
doneFinished. Download the results.
failedCould not finish. errorMsg says why. Numbers not validated are not charged; you can restart the job from the dashboard.
unverifiedYou cancelled the job. Numbers already checked are kept; you can resume it from the dashboard.

3. Download the results

When status is done, download the results CSV. It works with your API key. You can also download it from Bulk history in the dashboard.

Request
curl https://api.smartphonevalidator.com/v1/bulk/JOB_ID/download \
  -H "X-API-Key: YOUR_API_KEY" \
  -o results.csv

The results CSV has one row per row of your file, in the same order, with these columns. Your other columns (name, email and so on) are not copied into it: match results to your own data by the input number.

ColumnMeaning
inputThe number exactly as it was written in your file.
e164The number in E.164 format.
is_validyes or no.
is_riskyyes or no. Valid numbers can still be risky.
countryCountry of the number.
locationCity or area, when available.
carrierVoice carrier, when available.
line_typemobile, landline, voip, tollfree, premiumrate or unknown.
risk_score0–100. Lower is safer.
risk_flagsReasons behind the score, separated by commas.
invalid_reasonWhy a number is invalid, in plain English.
messaging_providerThe text-message (SMS) provider, when one exists. Same as messagingProvider above.

Results are kept for 15 days, so download them within that time.

Other bulk calls

  • GET https://api.smartphonevalidator.com/v1/bulk lists your jobs, newest first. Use page and limit (up to 50).
  • POST https://api.smartphonevalidator.com/v1/bulk/JOB_ID/cancel stops a queued or running job.
  • POST https://api.smartphonevalidator.com/v1/bulk/JOB_ID/reverify restarts a cancelled or failed job. Numbers already checked are not charged again.

Billing

  • Each number checked costs $0.004 from your prepaid wallet, whatever the result: single, batch or bulk. Your free lookups are used first.
  • Successful responses include your balance in meta.balance and your remaining free lookups in meta.freeLookups.
  • A batch or bulk job needs enough funds for every number before it starts. If not, you get a 402 and nothing is charged.
  • Checking the same number again within 7 days is free for live lookups. In bulk and batch, a number repeated in the same request is charged once.
  • If we cannot complete a check (a 503, or a bulk job that fails), you are not charged for the numbers that were not checked.
  • Your balance never expires. See Pricing and add funds from your dashboard, or turn on automatic refill.

Errors

Errors return success: false and an error object with a message you can show or log, and usually a code you can handle in your program.

Example · 402
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Your wallet is empty. Add funds to continue."
  }
}
HTTPMeaning
400The request is missing a field or is malformed, for example no phone, no file, or more than 100 numbers in a batch.
401Missing or invalid API key.
402Not enough funds. Add funds to your wallet from the dashboard. Nothing was charged.
403The account is not activated yet (check your email for the activation link) or has been deactivated.
404No such bulk job on your account.
413The uploaded file is too large. Excel files can be refused when very large: save them as CSV, which has no size limit.
422The uploaded file could not be read, is empty, or has no numbers in the phone column.
429You already have 5 bulk files waiting or running. Wait for one to finish, then upload again.
500Something went wrong on our side. Retry, and contact support if it continues.
503We could not complete the check right now (for example, a data provider is unavailable). You are not charged. Retry in a moment.

Retry 500 and 503 responses after a short wait. Do not retry 400, 401, 402, 403 or 422 without changing something first.

Stuck? Contact support and include the request you sent, but never your API key.