Phonelint
Integrations

How to clean a phone list before importing it to Klaviyo

Published 2026-09-10 · Updated 2026-09-12 · Phonelint

Klaviyo's phone-number import is strict in one way and permissive in another, and the combination catches people out. It is strict about format — anything not in E.164 is rejected outright. It is permissive about whether the number can actually receive a text, a landline imports perfectly happily, then silently consumes SMS credits forever.

The same is broadly true of Attentive, Postscript, Braze and most ESPs with an SMS channel. The specifics below are Klaviyo's, but the shape of the problem is universal.

What Klaviyo requires

Phone numbers must be in E.164: a plus sign, then digits, no spaces or punctuation. Rows that fail are skipped, and the import summary tells you how many were skipped without telling you which ones or why. On a large file that is a genuinely painful debugging experience, which is the main argument for cleaning before you upload rather than after.

What happens to a number after it imports

The import is the visible step, so it gets the attention. What the number does afterwards is where the cost accumulates.

A phone number in Klaviyo attaches to a profile, and a profile is the unit that carries consent, subscription status and message history. Three consequences follow, and none of them are reversible by re-importing a better file later:

This is the argument for cleaning before rather than after. Cleaning before is a file operation. Cleaning after is a data-migration exercise inside a system that is actively sending.

Prepare the file in this order

1. Fix the format

Strip punctuation, convert leading 00 to +, resolve each row's country, and drop the trunk prefix where that country uses one. The UK +44 (0) 20… pattern deserves specific attention — naive punctuation stripping turns it into a number with an extra zero that is the right length for nothing.

2. Deduplicate after normalising, not before

Klaviyo will happily create separate profiles for (415) 555-2671 and +14155552671 if your source treats them as different strings, and then message the same person twice. Normalise first so they collapse.

3. Drop unallocated numbers before upload

These import cleanly. They are well-formed, so nothing rejects them, and then sit in your account as permanently unreachable profiles, dragging your deliverability metrics down and, on plans billed by active profile, costing you money for contacts that cannot be contacted.

4. Remove landlines

This is the one with an ongoing cost. Landline profiles receive every SMS you send to that segment, forever, and every one is billed. A few thousand landlines in a list you message weekly is a recurring charge for messages that were discarded on arrival.

5. Check your consent data separately

Klaviyo requires that SMS subscribers have consented, and this is a legal requirement, not just a platform rule. Cleaning a list makes it deliverable. it does not make it compliant. Consent has to come from your own records, and if you cannot show where a number consented, it should not be in the SMS segment regardless of how clean it is.

Reading the import summary

Klaviyo tells you how many rows were skipped. It is much less forthcoming about which rows, and why. On a file of any size that is the difference between a five-minute fix and an afternoon.

The reliable way round it is to make the file unable to fail rather than to debug the failure afterwards. Before uploading, verify locally that:

If those four hold, a skipped row is a Klaviyo-side rule rather than a formatting problem, and you have narrowed the search enormously.

Worth knowing that a row can also be accepted and then be wrong. An import that reports zero skipped rows is not evidence that the numbers are real. It is evidence that they were syntactically acceptable, which is a much weaker claim.

The CSV itself

The Excel trap, concretely. Open a clean E.164 CSV in Excel and save it, and +14155552671 can come back as 14155552671 or 1.41556E+10. If you must touch the file in a spreadsheet, set the column type to Text before opening, or use Google Sheets with a leading apostrophe, or do not open it at all.

The same problem in other platforms

The specifics above are Klaviyo's. The shape is common to every platform with an SMS channel, and the differences that matter are in how strict the import is and how the billing works.

BehaviourWhy it changes what you do
Strict E.164 on importFailures are loud and happen up front, which is the easier case to handle
Permissive import with normalisation at send timeFailures are quiet and happen later, per message, which is harder to attribute
Billed per active profileAn unreachable number is a recurring charge even if you never message it
Billed per message sentAn unreachable number costs only when that segment is sent to, but does so every time

In every combination the preparation is the same, which is the practical reason to do the work in the file rather than in the platform. A cleaned E.164 file imports correctly into all of them. A file prepared for one platform's quirks does not travel.

A worked sequence on a real export

Concretely, on a 50,000-row export merged from a checkout system and two signup forms. The counts below are one list's, not a benchmark, and the reason to show them is the order rather than the proportions.

  1. 50,000 rows in. Three sources, three different formatting conventions, one of which stored numbers with the country name in a separate column and one of which did not store country at all.
  2. Normalise first. The rows with no country are the decision point. Where the number already carried a prefix it converts cleanly; where it did not, it is set aside rather than assumed into the majority country.
  3. Deduplicate second. Only now does the same number from checkout and from a form collapse into one row. Running this step first would have left both.
  4. Drop unallocated blocks third. These are the rows that pass every format check and cannot ring. They would have imported silently and become permanent profiles.
  5. Split landlines fourth, into a separate file for the voice team rather than into the bin.
  6. Import what is left, with the consent columns attached, and keep the removals as a suppression file for next month's export.

The step that most often gets skipped is the last clause of the last point. The same sources will produce the same dead numbers again in thirty days, and a suppression file is what stops you paying for them twice.

Consent is a separate file, and a separate problem

Worth restating, because technical cleanliness reads like compliance and is not.

Every number in an SMS segment needs consent you can evidence: when it was given, through what mechanism, and for what. That record lives in your own systems and has to survive a change of platform, which is why it belongs in the import file rather than being reconstructed later from whatever the platform happened to retain.

A perfectly formatted, deliverable, mobile number with no consent record behind it is a liability rather than an asset, and it is the one defect that cleaning cannot detect. Numbering-plan data can tell you that a number is real and that it is a mobile. It cannot tell you that someone agreed to hear from you.

Doing it once versus doing it monthly

For a one-off import of a few thousand rows, careful manual work in a spreadsheet gets you there.

For a list you re-export monthly, or one in the hundreds of thousands of rows, manual stops being viable, not because it is hard, but because it has to be repeated identically every time and it will not be. That is where a tool that does the whole sequence in one pass pays for itself: same rules, same output, every time, with the invalid rows accumulating into a suppression file so you are not re-cleaning the same junk each month.

Common questions

How do I format a phone number in international format?

Start with a plus sign, then the country code, then the national number with the trunk prefix removed and all spaces, brackets and dashes stripped. A UK mobile written 07700 900123 becomes +447700900123. The trunk zero is dropped, which is the step most often missed, and keeping it produces a number that is the right length for nothing.

How do I import contacts into Klaviyo?

Upload a CSV with one phone number per row, already in E.164, with the column formatted as text so the leading plus survives. Include your consent columns in the same file rather than backfilling them afterwards. Prepare the file completely before uploading, because the import summary reports how many rows were skipped without telling you which ones.

Why does Klaviyo reject my phone numbers?

Almost always formatting rather than the number itself. The common causes are a missing plus, a trunk prefix that was not removed, a value that a spreadsheet converted to scientific notation, and invisible characters such as non-breaking spaces picked up through copy and paste. All four produce a row that looks correct on screen.

Do landline numbers cost money in an SMS platform?

Yes, in both billing models. On a platform billed per message they consume a send every time the segment is messaged, and the message is discarded on arrival with nothing reported back. On a platform billed per active profile they are a standing charge for a contact that cannot be contacted. Neither shows up as an error.

Does cleaning a list make it compliant?

No. Cleaning makes a list deliverable. Compliance is about consent and about the registries you are required to check, and those use different data entirely. It is worth treating them as two separate passes with two separate records, because passing one says nothing about the other.

What are Klaviyo's weaknesses when it comes to phone data?

Scoped to phone numbers rather than the product generally: the import is strict about format but permissive about reachability, so a landline or an unallocated number imports as cleanly as a good mobile. The skipped-row summary reports a count without identifying the rows. And because a number becomes a profile, a bad import is a durable record rather than a rejected line. None of that is unusual among SMS platforms, and all of it is avoidable by preparing the file first.

Try it on a number right now

The free checker on the homepage runs the same engine the desktop app uses: validity, country, line type and carrier, one number at a time.

Check a number free