Skip to Content
GuidesValidate Phone

Validate Phone

VerifNow checks a phone number against its country’s numbering plan: the right length, and a prefix that is actually allocated. Valid numbers come back normalized to E.164, with the country and the kind of line they belong to.

Valid means the number exists in the plan, not that the line is live. Nothing short of calling or texting the number can tell you that. Use a one-time code if you need proof of ownership.


Basic phone validation

Send the number with its country code, written with + or the 00 international prefix. Spaces, dashes and parentheses are fine.

POST https://api.verifnow.io/api/v1/validate/phone X-API-KEY: your_api_key_here Content-Type: application/json { "value": "+33 6 12 34 56 78" }

Example response

{ "valid": true, "message": "Valid phone number", "normalizedValue": "+33612345678", "originalValue": "+33 6 12 34 56 78", "validationLevel": "STANDARD", "phoneDetails": { "country_code": "FR", "calling_code": 33, "line_type": "MOBILE", "international_format": "+33 6 12 34 56 78", "national_format": "06 12 34 56 78" } }

Store normalizedValue. E.164 is the form SMS providers and telephony APIs expect, and it makes two spellings of the same number compare equal.


Why the country code is required

The request carries a single value. Without a country code, 06 12 34 56 78 is a French mobile, and a malformed number almost everywhere else. Guessing a default country would validate the wrong thing without telling you.

If your form collects the country separately, prepend its calling code before sending — or, better, use a phone input that produces E.164 directly.

{ "valid": false, "message": "Phone number must include its country code, e.g. +33 6 12 34 56 78", "originalValue": "06 12 34 56 78", "validationLevel": "STANDARD" }

phoneDetails

FieldDescription
country_codeISO 3166-1 alpha-2 country, e.g. FR. Absent when a calling code is shared and the number does not identify a single country.
calling_codeInternational calling code without the +, e.g. 33.
line_typeKind of line — see below. Absent when the number is invalid.
international_format+33 6 12 34 56 78. Absent when the number is invalid.
national_format06 12 34 56 78, as dialled inside the country. Absent when the number is invalid.

phoneDetails is also returned for an invalid number, as long as it could be read as international. Knowing the input was read as French but is one digit short lets you write a better error message than “invalid phone”:

{ "valid": false, "message": "Phone number is too short for its country", "originalValue": "+33 6 12 34 56 7", "validationLevel": "STANDARD", "phoneDetails": { "country_code": "FR", "calling_code": 33 } }

line_type

ValueMeaning
MOBILEMobile line.
FIXED_LINELandline.
FIXED_LINE_OR_MOBILEThe plan does not distinguish the two — the case for the US and Canada.
VOIPInternet telephony, e.g. French 09 numbers. Common for businesses.
TOLL_FREEFree to call, e.g. 0800.
PREMIUM_RATECharged at a premium to the caller, e.g. French 0899.
SHARED_COST, PERSONAL_NUMBER, PAGER, UAN, VOICEMAILLess common categories from the numbering plan.
UNKNOWNThe plan does not say.

A PREMIUM_RATE or VOIP number is still valid: true — it exists. line_type is how you decide to exclude one, rather than the API deciding for you.


Acceptance strategy

import { VerifNow } from '@verifnow/sdk'; const client = new VerifNow({ apiKey: process.env.VERIFNOW_API_KEY }); const result = await client.validatePhone(input); if (!result.valid) { return reject(result.message); // the message is written to be shown to a user } const { lineType, countryCode } = result.phoneDetails; if (lineType === 'PREMIUM_RATE') { return reject('Please enter a number we can call at a normal rate.'); } if (requiresSms && lineType !== 'MOBILE' && lineType !== 'FIXED_LINE_OR_MOBILE') { return reject('Please enter a mobile number so we can text you a code.'); } return accept({ phone: result.normalizedValue, country: countryCode });

phoneDetails needs @verifnow/sdk 1.2.0 or later. The SDK maps line_type to lineType, and so on.

Phone checks are the same on every plan. Validation depth by plan only changes email signals.


Common errors

InputResponse
06 12 34 56 78 (no country code)valid: false, message asks for the country code
0033 6 12 34 56 78valid: true — 00 is read as +
+33 6 12 34 56 7 (one digit short)valid: false, phoneDetails.country_code: "FR"
+999 123 456 789valid: false, "Unknown country calling code"
+33 8 99 12 34 56valid: true, line_type: "PREMIUM_RATE"

See Error Handling for transport-level failures and status codes.


Next steps

Last updated on