Zalo data cleaning is the unglamorous step that decides whether a Vietnam outreach campaign converts or quietly stalls. Most teams blame the message template, the sending schedule, or the age of their account when results drop. In practice the problem is usually upstream: a contact list exported from three different sources, never normalized, and never re-checked since the day it was collected.
This guide walks through a seven-step Zalo data cleaning workflow you can run on any list, whether you exported it from a group, pulled it out of a CRM, inherited it from a partner, or received it from a vendor. Every step is written as an operation you can actually execute, with a pass criterion so you know when the step is finished.
Why Cleaning Comes Before Sending
Zalo is a phone-number-native platform. An account exists because a SIM card exists, and SIM cards get replaced, recycled and switched off far more often than email addresses do. A list that was 90% reachable six months ago can easily be 60% reachable today without anything visibly breaking — the messages simply stop landing.
Dirty data costs you in three separate ways.
Wasted sends. Every message to a dead number is a unit of your sending budget spent for nothing. If you pay per message or operate under a daily cap, this is money leaving the account in real time.
Quality signals. Repeated sends to non-existent accounts inflate your failure rate. Platforms read a high failure rate as a spam indicator, and the penalty lands on the sending account, not on the bad number.
Broken reporting. When a third of your list is unreachable, your delivery, read and reply rates are all understated. You end up rewriting copy, changing send times and testing new templates to fix a problem that was never in the copy.
The fix is not complicated, but it has to be systematic. Running one filter pass and calling the job done is the single most common mistake.
What "Clean" Actually Means for a Zalo List
Before touching the data, define what a clean record looks like. For Zalo, a record is clean when all five conditions hold:
- Format is normalized — the number is stored in one consistent international format.
- The account exists — the number is actually registered on Zalo.
- It is reachable — the account is live, not deleted, not permanently disabled.
- It is unique — the same person appears exactly once in the list.
- It is labeled — you know which source it came from and which segment it belongs to.
Skip the fifth condition and you will be cleaning the same list again next quarter, with no way to tell which source produced the junk in the first place.
Step 1: Normalize Every Number to One Format
Vietnamese phone numbers are the classic source of mess. The same number can legitimately appear as 0912345678, +84912345678, 84912345678, "+84 912 345 678", or "(+84) 912-345-678". Load all five variants into a sending tool and you get five separate records for one person — and your deduplication step later will miss every single one of them.
Do this:
- Strip every non-digit character except a leading plus sign.
- Convert legacy 01x prefix families to their modern equivalents if your data predates the Vietnamese prefix migration.
- Rewrite all domestic numbers into E.164 form: drop the leading zero, prepend +84.
- Store the normalized value in a dedicated column, and keep the raw value in a second column for audit.
Pass criterion: every row matches the pattern "+84 followed by exactly nine digits" (or the equivalent pattern for your target market). Anything that does not match goes into a quarantine sheet, not the trash — landline numbers and mistyped entries hide there, and a manual look often recovers a meaningful share of them.
Step 2: Verify Which Numbers Are Real Zalo Accounts
A working SIM is not the same thing as a Zalo account. Plenty of numbers in a purchased or scraped list belong to people who never installed the app, or who registered with a different number entirely.
This is where a number screening service earns its keep: it checks each normalized number against the platform and returns an existence flag, so you can cleanly separate "registered on Zalo" from "just a phone number".
Do this:
- Run the full normalized list through a screening pass.
- Split the output into three buckets: registered, not registered, and unknown or errored.
- Re-run the unknown bucket once after a short interval. Transient lookup failures are normal at scale, and a single retry usually recovers most of them.
- Keep the not-registered bucket out of the sending list entirely.
Pass criterion: every remaining row carries an explicit registered flag, and the unknown bucket is under 2% of the total.
Step 3: Remove Dead, Recycled and Risky Numbers
Existence is not reachability. A number can be registered and still be worthless to you, because the SIM was recycled, the account was abandoned years ago, or the owner has not opened the app since the day they registered.
Layer these checks on top of the existence pass:
- Activity recency. Flag accounts with no recent activity; these are the strongest candidates for dead weight.
- Profile completeness. An account with no avatar, no display name and no interaction history is a low-confidence record.
- Failure history. Any number that failed delivery in a previous campaign should be removed, not retried. Retrying a known failure is the fastest way to damage an account's reputation.
- Known complaint sources. Numbers that previously blocked or reported your account should never be re-imported.
If you run outreach on more than one platform, keep the same discipline everywhere. The WhatsApp screening workflow and the Telegram account checks follow identical logic, so one cleaning pipeline can serve all of them once the normalization step is made market-specific.
Pass criterion: the remaining list contains no number that failed in either of your last two campaigns.
Step 4: Deduplicate Across Every Source
Now that formats are consistent, deduplication actually works. Most teams dedupe on the phone number alone and stop there, which is acceptable for a single-source list but risky for a merged one.
Do this:
- Dedupe on the normalized E.164 value as the primary key.
- Where two records share a number but conflict on other fields, keep the most recently updated record and log the conflict.
- Watch for cross-source duplicates: the same person may appear with a personal number in one export and a business number in another. Decide explicitly whether that counts as one contact or two, and write the rule down.
Pass criterion: zero duplicate normalized numbers, plus a documented rule for business-versus-personal collisions.
Step 5: Segment and Tag Before You Send
Cleaning without tagging throws away most of the value. Once the list is trustworthy, attach the attributes you will actually send against:
- Source — group export, CRM, form fill, partner list, vendor file.
- Market and language — domestic Vietnamese, or overseas Vietnamese communities if you target them.
- Intent stage — cold, previously engaged, previously replied, existing customer.
- Consent status — whether you have any legitimate basis to contact this person at all.
Consent is not a legal footnote; it is the single biggest driver of block and report rates. A smaller list of people who opted in will outperform a large scraped list on every metric that matters, including the ones the platform uses to judge your account. You can see which platforms support this kind of segmentation on the platforms page.
Step 6: Put Cleaning on a Schedule
A one-off clean decays. SIM cards churn, users deactivate, and every new import reintroduces the original mess. Set a cadence instead of running a project:
- Per import: run steps 1 through 4 automatically on every new batch before it touches a sending account.
- Weekly: re-verify any record that has not been contacted in 30 days.
- Monthly: re-score activity across the whole database and archive anything inactive for two consecutive checks.
- Per campaign: strip every hard failure from the previous send before the next one goes out.
Automating this is straightforward once the steps are defined — screening is an API call, and everything else is spreadsheet or database logic you can script in an afternoon.
Step 7: Lock the Output and Hand It to the Sending Tool
The last step is governance. Produce one canonical, read-only "sendable" table, and make every campaign read from it rather than from whichever export somebody downloaded last week.
- Freeze the cleaned list with a date stamp and a row count.
- Record the screening run identifier next to each record.
- Route all sending through the canonical table, and write failures back to it automatically.
Pass criterion: there is exactly one table your team treats as the source of truth, and it displays a visible "last cleaned" date.
What Changes After a Proper Clean: An Example
Consider a typical example. A team exports 50,000 rows from a mix of group members, an old CRM, and a vendor file. Normalization collapses roughly 8% of the rows as duplicates created purely by formatting differences. The existence screen then removes a large share of numbers that were never on the platform at all. Activity filtering takes another slice. The exact percentages vary enormously by source — that is precisely why you measure them per source rather than assuming an industry average — but the sendable list that comes out the other end is frequently less than half the original file.
The important part is not the shrinkage. It is that the remaining rows are measurable: you now know your true delivery rate, your true reply rate, and which acquisition channel produces contacts that actually stay reachable.
A Weekly Routine That Keeps It Clean
Once the pipeline exists, maintenance costs about 20 minutes a week. Pull the failure report from the previous week's sends, remove those numbers from the canonical table, re-verify 100 to 200 of the oldest untouched records, and spot-check that new imports actually ran through the pipeline. Teams that do this consistently see far more stable delivery than teams that schedule one big cleanup a year.
Five Mistakes to Avoid
- Cleaning after sending instead of before. Verification is always cheapest before a number ever touches your sending account.
- Deleting instead of quarantining. Keep the rejects; they tell you which acquisition source is producing junk.
- Trusting a vendor's "verified" claim. Verify on import, every time, regardless of who supplied the file.
- Ignoring consent. Reachability is not permission.
- Treating cleaning as a one-time project. The list decays; the process should not.
Where to Start
If you have never cleaned a Zalo list before, start with steps 1 and 2 — normalization and existence screening. Those two alone usually remove the bulk of the waste, and they give you a baseline you can measure everything else against. Screening is priced per lookup, so check the pricing page before you run a large batch.