Guides
Last updated
July 25, 2025

5 Ways to Validate Phone Numbers in Joi

Nicolas Rios
Nicolas Rios
Table of Contents:
ON THIS PAGE
Get your free
phone validation
 API key now
stars rating
4.8 from 1,863 votes
See why the best developers build on Abstract
START FOR FREE
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
No credit card required

Ensuring phone numbers are valid is a frequent task in Joi schemas for data integrity. You can approach this in several ways. We'll look at five methods with code examples, discuss the shortcomings of common libraries, and then show how Abstract API offers a more dependable alternative.

How to Implement Phone Number Validation in Joi

This section covers four distinct methods to validate phone numbers in Joi. Each approach has a different implementation, from simple regular expressions to more advanced, feature-rich library extensions.

Regex-Only Schema

This method uses Joi’s native .pattern() function, which runs fast and has zero runtime dependencies. When you need to accept multiple national formats, you can create several regular expressions or wrap them in Joi.alternatives().

const Joi = require('joi');

const e164 = /^\+?[1-9]\d{1,14}$/;           // accepts +15551234567 etc.
const schema = Joi.string().pattern(e164).required();

schema.validate('+15551234567'); // { value: '+15551234567' }  
schema.validate('555-1234');     // ValidationError

Salesflare joi-phone-number Extension

The joi-phone-number extension is a wrapper around google-libphonenumber. It supports features like defaultCountry, a strict mode, and four canonical output formats: e164, international, national, and rfc3966. It also integrates with Joi’s convert option, which can rewrite the value to the desired format before it reaches your business logic.

const BaseJoi   = require('joi');  
const extension = require('joi-phone-number');  
const Joi       = BaseJoi.extend(extension);

const schema = Joi.string().phoneNumber({ defaultCountry: 'US',
                                          format: 'e164',   // output conversion
                                          strict: true });  // reject impossible numbers

schema.validate('415-555-1212');      // => '+14155551212'  
schema.validate('+99 123');           // ValidationError

@tepez/joi-phone-number-extensions

This extension exposes libphonenumber capabilities directly. These include defaultRegion versus an explicit region, line-type filters, and runtime formatting. It provides a first-class Joi type, Joi.phoneNumber(), which makes the schema’s intent clearer than a standard string validation.

const BaseJoi = require('joi');  
const ext     = require('@tepez/joi-phone-number-extensions');  
const Joi     = BaseJoi.extend(ext);

const schema = Joi.phoneNumber()                   // dedicated type, not string()
                 .defaultRegion('US')              // assume US if no ‘+’
                 .region('US')                     // enforced country
                 .type('MOBILE')                   // only mobile lines
                 .format('E164');                  // normalised output

schema.validate('+1 541-754-3010');  // '+15417543010'

Custom Rule with libphonenumber-js

You can build a custom rule with libphonenumber-js to avoid a third-party Joi plugin. This approach gives you full control over the conversion logic and error messages. You can also select the metadata package size (core, min, or max). The rule can be wrapped in Joi.extend() to create a reusable .phone() function across different schemas.

const Joi = require('joi');  
const { isValidNumber, parsePhoneNumber } = require('libphonenumber-js/max'); // use max metadata

const phoneSchema = Joi.string().custom((value, helpers) => {
  const parsed = parsePhoneNumber(value, 'US'); // default region
  if (!parsed || !parsed.isValid()) {
    return helpers.error('any.invalid');
  }
  return parsed.number; // convert to E.164
}, 'libphonenumber validation');

phoneSchema.validate('(415) 555-1212'); // '+14155551212'

Challenges of Phone Number Validation in Joi

While the previous methods offer structural checks, they share inherent limitations that can compromise data quality. These drawbacks stem from outdated dependencies, flawed logic, and an inability to verify real-world status.

  • The `joi-phone-number` plugin often lags behind `google-libphonenumber` updates. This causes the rejection of valid new dialing codes because the wrapper does not have the latest numbering plan information.
  • The `joi-phone-number` extension has historically bypassed core checks. This oversight allows syntactically correct but non-existent numbers to pass validation, a flaw that can reappear as the plugin evolves.
  • A regex-only schema struggles with diverse global formats. The variety of lengths and prefixes across 200+ national plans makes a single, comprehensive regular expression nearly impossible to create and maintain.
  • Joi's synchronous nature limits validation to format and structure. It cannot perform real-time checks to detect deactivated or disposable numbers, which means it only confirms syntax, not actual reachability.

Validate Phone Numbers with Abstract API
Add phone number validation to your Joi project to collect accurate user data from day one.
Get started for free

How Abstract API Handles Phone Number Validation in Joi

Abstract API addresses the core weaknesses of traditional Joi validation methods through a live verification layer that provides real-time data.

  • It moves beyond simple format checks to confirm if a number is active and currently dialable through real-time telecom data sources.
  • The API returns a precise line type, such as mobile, landline, or VOIP, which avoids the ambiguous classifications common in static libraries.
  • It identifies the current network carrier for a number, a detail that static datasets cannot provide because they only store original allocations.
  • These data points allow developers to enforce specific business rules inside Joi, like "reject VOIP numbers" or "allow only US mobiles."

How to Bring Abstract API to Your Dev Environment

Once you know Abstract’s capabilities, you can add its phone number validation API to your project with ease.

  • First, sign up at Abstract API to get a free API key for the Phone Validation API.
  • Next, install the Abstract API and Joi packages from npm.
npm install @abstractapi/javascript-phone-validation joi
  • Then, import and configure the library in your application's entry point with your API key.
  • Finally, create a Joi schema that uses an async custom validator to call the API and check the response.

Sample Phone Number Validation Implementation with Abstract API

The code below shows a custom Joi validator. It calls the Abstract API for any given phone number. The rule checks if the number is valid, is a mobile line, and originates from the US. If any check fails, Joi rejects the value. This moves validation from simple pattern matches to checks based on live, real-world data.

const Joi = require('joi');
const { AbstractPhoneValidation } = require('@abstractapi/javascript-phone-validation');
AbstractPhoneValidation.configure(process.env.ABSTRACT_PHONE_KEY);

const phoneSchema = Joi.string().custom(async (value, helpers) => {
  const data = await AbstractPhoneValidation.verify(value);
  if (!data.valid || data.line_type !== 'mobile' || data.country_code !== 'US') {
    return helpers.error('any.invalid');
  }
  return value;
}, 'Abstract phone check');

await phoneSchema.validateAsync(req.body.phone);

The API returns a detailed JSON object. The valid field confirms if the number is active. The format object provides local and international versions. The country and location fields allow for geographic rules. The type field specifies if the line is mobile, landline, or VOIP, while carrier identifies the current network owner.

{
  "phone": "14152007986",
  "valid": true,
  "format": {
    "international": "+14152007986",
    "local": "(415) 200-7986"
  },
  "country": { "code": "US", "name": "United States", "prefix": "+1" },
  "location": "California",
  "type": "mobile",
  "carrier": "T-Mobile USA, Inc."
}

Final Thoughts

Traditional validation methods use static data and cannot confirm if a number is active or its true line type. Abstract API overcomes these limits with live data checks for accurate, real-time details on validity, carrier, and location. To reliably validate user phone numbers, consider getting a free API key from Abstract API.

Validate Phone Numbers with Abstract API
Ensure you collect accurate user data by implementing phone number validation in your Joi schemas.
Get started for free

Related Articles

Phone Validation
key now
Get your free
stars rating
4.8 from 1,863 votes
See why the best developers build on Abstract
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
No credit card required