Tips

Normalizing Phone Input Before Verification Requests

Diagram illustrating normalize phone number input for verification workflows

Many failed verification attempts begin with a bad number, not a bad network. Users paste digits with spaces, drop the country code or add a leading zero. A short normalisation pipeline at the form boundary fixes most of these before they cost you an order.

Step 1: collect the country explicitly

A country picker with a sensible default beats guessing from the first digits. Pre-select using the user's locale or IP as a hint only, and let them change it. Show the calling code beside the field so the user can see what is being assumed.

Step 2: sanitise the raw string

  • Trim whitespace at both ends.
  • Convert full width and Arabic-Indic digits to ASCII digits.
  • Remove spaces, dots, dashes and parentheses.
  • Keep a single leading plus if present, and discard stray plus signs elsewhere.
  • Reject anything that still contains letters, apart from an optional extension marker you choose to refuse.

Step 3: parse with the country as context

Pass the cleaned string and the chosen country to a parsing library. If the user typed a number beginning with a plus, the library will infer the country from the prefix and ignore your default. If they typed a national number, the default region fills the gap.

Step 4: validate in two levels

Possible means the length fits the country's rules. Valid means the digits form a known pattern. Use valid for final acceptance, but when a library data set lags behind a newly allocated range, consider accepting possible numbers with a soft warning instead of blocking.

Step 5: confirm back to the user

Show the formatted result before sending anything: We will send a code to +1 415 555 0123. This single line catches typos, wrong countries and swapped digits at the cheapest possible moment.

Handling edge cases

  • Paste events. Normalise on paste so the field shows the cleaned value.
  • Autofill. Browsers may fill with plus and spaces. Your pipeline should treat that as normal.
  • Shared codes. The US and Canada share calling code 1, so use the area code, not the prefix, to tell them apart when it matters.
  • Test numbers. Fictional ranges such as 555 are invalid in production but handy in tests. Allow them only in non-production settings.
def normalize(raw, country):
    cleaned = re.sub(r'[^0-9+]', '', raw)
    num = phonenumbers.parse(cleaned, country)
    if not phonenumbers.is_possible_number(num):
        raise ValueError('bad_length')
    return phonenumbers.format_number(num, E164)

Finally, log the failure reason rather than the number itself. Counting how often bad_length or wrong_country occurs tells you which part of the form to improve next.

Frequently asked questions

Should I guess the country from the IP address?

Use it only as a default hint. VPNs, travel and mobile networks make IP location unreliable. Always let the user change the country, and show the calling code clearly so a wrong guess is obvious before they submit.

What if validation rejects a real new number range?

Library data can lag behind newly allocated ranges. Offer a soft path: accept numbers that are possible by length, warn gently, and log them for review. Update the library regularly so the gap stays small.

Should I normalise on the client or the server?

Both. Client side normalisation gives instant feedback and a nicer experience. The server must repeat it, because clients can be bypassed and different versions may behave differently. The server result is the one you store.

What should I log when normalisation fails?

Log the failure category, the selected country and the length of the cleaned input, not the number itself. Categories such as too short, too long, wrong prefix and invalid characters let you see which part of the form confuses people, while keeping personal data out of your logs entirely.

Keep going

Check the services list for current availability, then use the API docs to wire the flow into your own product. If you want background on the platform, visit the about page. Answers to everyday questions live in the help center, and the contact page reaches a person. More articles are on the blog. To place an order, log in to the verification dashboard.

Related reading: E.164 Phone Number Format Explained for Developers and OTP Length and Format: UX Design Choices That Matter.

Share

X / Twitter LinkedIn Facebook

← Back to Blog