Guides
Last updated
July 20, 2025

5 Ways to Validate Phone Numbers in Zod

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

Validating phone numbers in Zod is key for data integrity. We will explore five common methods, complete with code snippets, to handle this task. We will also examine the limitations of these traditional approaches and show how Abstract API overcomes these specific challenges.

How to Implement Phone Number Validation in Zod

Here are four common methods to validate phone numbers with Zod. Each approach uses a different technique, from simple regular expressions to more comprehensive validation libraries for robust checks.

Direct Regex Match

The most straightforward approach is to use a regular expression. The "z.string().regex()" method allows you to define a specific pattern that the phone number string must match. This acts as a basic syntactic check.

This method requires no external libraries and executes quickly. The code defines a Zod schema for a string and applies a regex pattern to it, with a custom "invalid" message for numbers that do not match the pattern. Some developers recommend this for simple cases.

const phone = z.string().regex(/^([+]?[\s0-9]+)?(\d{3}|[(]?[0-9]+[)])?([-]?[\s]?[0-9])+$/, 'invalid');

Refinement with validator.js

For more robust validation, you can use the "refine" method with a third-party library like "validator.js". This approach keeps your Zod schema clean while it outsources the complex validation logic to a specialized tool.

The library contains a maintained catalog of country-specific phone number formats. The code first imports the "validator" library. Then, it defines a Zod string schema and uses "refine" to pass the input to the "validator.isMobilePhone" function, which checks its validity against known mobile patterns.

import validator from 'validator';
const phone = z.string().refine(v => validator.isMobilePhone(v, 'any'), { message: 'invalid' });

Transformation with libphonenumber-js

A more powerful method involves the "libphonenumber-js" library, which can parse, validate, and normalize phone numbers into a standard format. This is often implemented with Zod's "transform" or "superRefine" methods.

The process starts with the import of the "parsePhoneNumberFromString" function. The Zod schema then uses "transform" to process the input string. Inside the transform, the function attempts to parse the number. If the number is invalid, it adds a custom issue, a pattern discussed in a relevant GitHub issue. If valid, it returns the number in the standard E.164 format, a technique also found on Stack Overflow.

import { parsePhoneNumberFromString } from 'libphonenumber-js';
const phone = z
  .string()
  .transform((v, ctx) => {
    const p = parsePhoneNumberFromString(v, { defaultCountry: 'US', extract: false });
    if (!p?.isValid()) {
      ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'invalid' });
      return z.NEVER;
    }
    return p.number;     // always returns E.164
  });

Native E.164 Validation in Zod 4

With the release of Zod 4, a dedicated helper for the E.164 format is available. The "z.e164()" method provides a simple, built-in way to validate numbers that conform to this international standard.

This helper uses a specific regex that requires the number to start with a "+" symbol, followed by one to fifteen digits. It offers the same API surface as "z.string()" without the need for extra code or external dependencies, as noted in community discussions.

const phone = z.e164();

Challenges of Phone Number Validation in Zod

These traditional methods present several drawbacks. They often struggle with the dynamic nature of global phone number formats and cannot confirm if a number is actually in use or reachable.

  • Zod lacks a native phone schema. This forces developers to use complex regex patterns that quickly become outdated as global numbering rules change. This approach creates brittle code that requires constant maintenance.
  • The libphonenumber-js library can accept non-dialable numbers. When used with Zod's refine method, these invalid numbers pass validation, which requires extra logic to catch edge cases the library misses.
  • The metadata for libphonenumber-js often lags behind official numbering plan updates. A Zod validator that relies on this library may incorrectly reject new, valid phone numbers or approve old, deprecated ones.
  • Zod validation operates only at a syntactic level. Methods like z.e164() confirm format compliance but cannot verify if a number is active, assigned, or poses a fraud risk.

Validate Phone Numbers with Abstract API
Validate phone numbers effectively in Zod to maintain clean user data and improve application reliability.
Get started for free

How Abstract API Handles Phone Number Validation in Zod

Abstract API addresses the core weaknesses of traditional methods by off-loading validation logic to a cloud system that stays current for over 195 countries.

  • It confirms if a number is actually assigned and reachable, not just its syntax.
  • It removes the maintenance burden of local patterns, as numbering plans update automatically in the cloud.
  • It returns metadata like carrier, line-type, and location without large offline libraries that increase a client build's size.

How to Add Abstract API to Your Development Environment

Once you know Abstract's capabilities, to add its phone number validation to your project is simple.

  • Sign up at Abstract and copy the phone-validation API key from the dashboard.
  • Install dependencies with the command npm i zod node-fetch dotenv –-save.
  • Add ABSTRACT_API_KEY=your_key to your .env file and load it with dotenv/config.
  • Create a Zod schema that calls Abstract inside an async .refine predicate.
  • Use schema.parseAsync(data) in your route or controller.

Sample Phone Number Validation Implementation with Abstract API

The code below defines a Zod schema for a phone number. It uses an asynchronous refine method to send the number to Abstract API for validation. The schema only passes if the API response confirms the number is valid with the field "valid" set to "true". Otherwise, it returns a custom error message.

The API returns a detailed JSON object. For Zod's pass or fail logic, you only need the "valid":true field. Additional data includes format objects to normalize numbers, country and location details for geo-based rules, carrier information, and the line type to distinguish between mobile and landline numbers.

Final Thoughts

Traditional validation with static regular expressions or large libraries only checks syntax. This approach fails to confirm if a number is active and creates a maintenance burden. Abstract API solves these problems with a cloud-based system that provides real-time data for over 195 countries.

To reliably validate user phone numbers, create a free account on Abstract API and get your API key.

Frequently Asked Questions

What is phone number validation in Zod?

Phone number validation in Zod means using Zod schema methods to check that a string conforms to a valid phone number format before it is processed in your application. Common approaches include z.string().regex() for simple pattern matching, the refine method with a third-party library like validator.js or libphonenumber-js, or the built-in z.e164() helper introduced in Zod 4. Each approach trades off simplicity against how thoroughly it verifies the number.

How does Zod 4's built-in z.e164() work for phone number validation?

Zod 4 ships a native z.e164() helper that validates a string against the E.164 international telephone numbering standard. It requires the number to start with a + sign followed by one to fifteen digits. This covers the format used by most telephony APIs and messaging services, but like all offline methods it only checks the structure of the number; it cannot confirm the number is actually assigned or in service.

When should I use regex versus libphonenumber-js with Zod?

Use a regex with z.string().regex() when you need a quick, zero-dependency syntactic check and your application only handles a single known region. Use libphonenumber-js with Zod's transform or superRefine when you need to parse and normalize international numbers into E.164 format. Be aware that libphonenumber-js's offline dataset can lag behind official numbering plan updates, so it may accept non-dialable numbers or reject newly issued ones.

Why is offline phone number validation in Zod not always sufficient?

Offline validation (whether via regex or a bundled library) only checks syntax and cannot confirm that a number is currently active, assigned to a carrier, or reachable. Numbering plans across 195+ countries evolve continuously, so static patterns become outdated and produce false rejections or approvals. It is also unable to detect fraud risk or distinguish between mobile, landline, and VoIP lines.

How do I use Abstract for real-time phone validation inside a Zod schema?

You can pass an async function to Zod's refine method that calls Abstract's Phone Validation endpoint and checks the returned valid field. Because refine supports promises, the schema can await the HTTP request before deciding whether to pass or fail. This approach also returns carrier name, line type, and geographic location metadata without requiring a large offline library bundled into your application.

Does using async refine for phone validation affect Zod's parse method?

Yes. When a Zod schema contains an async refine, you must use schema.parseAsync() instead of schema.parse(), otherwise Zod will throw an error. parseAsync returns a promise that resolves to the validated value, so your calling code must be async as well. This is a common source of errors when developers first add API-based validation to an existing Zod schema.

Validate Phone Numbers with Abstract API
Validate phone numbers in your Zod schemas to collect accurate information from your users.
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