How to Normalize Phone Numbers to E.164 Before You Dedupe or Send SMS
Strip spaces, dashes, and parentheses, add the country code, and collapse every messy phone number into one E.164 form so dedupe and SMS actually work.
How to Normalize Phone Numbers to E.164 Before You Dedupe or Send SMS
A contact list never arrives clean. It comes from a CSV export, a few support tickets, a copied web page, and somebody's spreadsheet where the phone column was typed by hand. So the same person shows up four times: (555) 123-4567, 555.123.4567, 5551234567, and +1 555 123 4567. To a human those are obviously one number. To your dedupe step, your CRM, and your SMS gateway they are four different strings. That mismatch is where the real damage starts: duplicate contacts, double-sent messages, and a gateway that silently drops the rows it cannot parse.
The fix is to pick one canonical form and rewrite every number into it before you do anything else. That canonical form is E.164, and the Phone Number Normalizer is built to produce it from whatever mess you paste in.
What E.164 actually is
E.164 is the international canonical form for a phone number. The shape is strict and worth memorizing: a leading +, then the country code, then the national subscriber number, with a maximum of 15 digits total and no spaces, dashes, dots, or parentheses anywhere. Nothing else is allowed.
Run the four variants above through that definition and they all reduce to the same thing:
(555) 123-4567-> strip punctuation ->5551234567-> add country code ->+15551234567555.123.4567->+155512345675551234567->+15551234567+1 555 123 4567->+15551234567
Once every row reads +15551234567, a plain string comparison is enough to spot the duplicates. That is the whole point: E.164 turns "are these the same number?" from a fuzzy judgment call into an exact ===.
A practical note on how the tool treats this: it rewrites the mixed dashes, spaces, and parentheses into one consistent E.164-style form in the browser tab, and it keeps a row untouched when there is nothing valid to standardize. A string like 415-555-013 is one digit short, so the tool does not guess a tenth digit and emit a fake rewrite. It leaves the row alone and flags the reason, which keeps the normalized column trustworthy instead of full of invented numbers. Whether a bare ten-digit number gets a +1 prefix or stays as-is depends on the country context the tool can infer from your input, so check the output against a number you already know before you trust a whole batch.
Why you must normalize before deduping
Deduplication is just grouping identical keys. If your keys are raw, unnormalized strings, "identical" means byte-for-byte identical, and almost nothing matches. Here is what a messy list looks like going in and coming out.
Input (pasted from a support export):
(555) 123-4567
555.123.4567
+1 555 123 4567
5551234567
(555) 987-6543
555-987-6543
415-555-013
After normalizing to E.164, keeping unique rows, and sorting:
+15551234567
+15559876543
415-555-013 (invalid: too short)
Seven rows in, two clean canonical numbers out, plus one row preserved for review. The four spellings of the first number collapsed to a single +15551234567; the two spellings of the second collapsed to +15559876543; and the broken row did not vanish, it stayed visible with its reason so you can fix it at the source. If you had deduped the raw input instead, you would have kept all seven rows because no two strings matched exactly.
Why it matters for SMS
SMS gateways are unforgiving about format. Most APIs expect E.164 and will reject, mangle, or silently route incorrectly anything else. Send (555) 123-4567 and you might get a hard error; send 5551234567 with no country code and the gateway has to guess where the number lives, which it often gets wrong. Normalize first and every row is already in the exact shape the API wants, so the only failures left are genuinely bad numbers, not formatting noise.
This is also where deduping pays off twice. If the same person sits in your list under three spellings and you skip normalization, you will send them the same message three times. Collapse to E.164 first and they get one message, which is the difference between a campaign and a complaint.
A workflow I actually use
When I get handed a column of numbers to clean, I do not trust my eyes for it anymore. I paste the whole thing into the normalizer, turn on dedupe and sort, and read the output top to bottom. The first time I did this I expected maybe a handful of duplicates; the list had 340 rows and came out at 290, which meant 50 messages I would otherwise have double-sent. What sold me was the invalid rows. Instead of quietly dropping the eight short or malformed numbers, the tool left them in with a reason next to each one, so I could go back to the original export and chase down the typos rather than discover them when the SMS batch half-failed. Everything runs in the browser tab, so the customer phone column never leaves my machine, which matters when the data is real.
Getting the output into your next system
Normalizing is only half the job; the clean list has to land somewhere. The tool lets you switch the output between plain lines, CSV, JSON, Markdown, a SQL IN clause, and a TypeScript union, then download exactly that artifact. So you can hand a SQL IN (...) straight to an analyst, drop a JSON array into a test fixture, or export CSV for a CRM import without hand-adding quotes and commas. Pick the format your destination expects and the normalized, deduped, sorted list is ready to paste.
A couple of habits keep this clean. Copied web text often carries hidden whitespace, so always normalize before you dedupe or import, never after. And when you need an audit trail, download the CSV or Markdown with line numbers instead of copying only the final list, so you can trace any number back to its source row.
If your raw text still has the numbers buried in prose or HTML, pull them out first with the phone number extractor, then send that clean column here to normalize. The two steps together turn a pasted page into an import-ready E.164 list with nothing sent to a server.
The short version
E.164 is the one canonical phone format that makes everything downstream behave: a +, a country code, the national number, 15 digits max, no punctuation. Collapse (555) 123-4567, 555.123.4567, and 5551234567 to +15551234567 first, and only then dedupe and send. Normalize once at the top of the pipeline and you stop paying for it as duplicates, double-sends, and gateway errors at the bottom.
Made by Toolora · Updated 2026-06-13