Preserve valid, catch-all, unknown, invalid, disposable, blank, and error outcomes.
Release only the policy-approved safe status. Quarantine risk instead of relabeling it.
Confirm email, name, company, and every variable land in the field the sequence actually uses.
Check the file, other lists, active campaigns, customers, replies, and global blocklists.
Explain every uploaded, skipped, rejected, quarantined, and missing row before launch.
The most dangerous cold email CSV is the one labeled verified.
That filename creates false confidence. Operators assume every row is valid, every duplicate is gone, and every custom variable will map correctly. Then the verifier's full report is imported instead of the valid-only split, a catch-all column is ignored, the email field maps to the wrong header, or the sequencer suppresses hundreds of rows without anyone reconciling the difference.
Ink Persuasion's release rule: the main campaign receives only policy-approved valid emails. Catch-all, unknown, invalid, disposable, blank, and API-error rows stay out unless a separate, explicit workflow changes their status.
Why a verifier export can still be unsafe
Verification tools return classifications. They do not know your campaign policy.
MillionVerifier lets users download Good-only, Risky-only, Bad-only, custom, or full reports. Its full report includes Good, Catch-all, Unknown, Invalid, and Disposable outcomes. ZeroBounce similarly packages separate status files plus an all_results file and the original uploaded file. If an operator selects the full report because it preserves the most data, the unsafe rows are still there by design.
This is not a verifier failure. It is an import-policy failure. The verifier told you what each row was. The campaign import must decide which classes are allowed to send.
Catch-all is not the same as valid
A catch-all domain can accept mail for any local part, including an address that does not belong to a real person. That prevents an ordinary SMTP check from proving that the individual mailbox exists.
MillionVerifier classifies catch-all and unknown as Risky. ZeroBounce separates catch-all from Valid and warns that sending to catch-all addresses can be risky. Its deeper catch-all validation can reclassify some rows, but unresolved rows remain Catch-All. Both products preserve the distinction because it matters.
Community discussions on Reddit show the same operational disagreement repeatedly: some operators exclude catch-all completely, while others isolate it in a lower-volume test. That is anecdotal evidence, not a universal threshold. The practical conclusion is still useful: catch-all needs its own policy and must not silently enter the confirmed-valid cohort.
Field mapping can defeat a clean file
Instantly requires the email column to be mapped to its predefined Email variable. It also auto-suggests mappings for names, company fields, predefined variables, and custom variables. Suggested does not mean verified.
Before importing the full file, use a fixture row with unmistakable values:
email = qa-fixture@example.com first_name = FIRSTNAME_TEST company_name = COMPANY_TEST personalized_line = PERSONALIZATION_TEST source_status = valid source_row_id = QA-0001
Upload that row to a paused test list, export or inspect it, and preview the exact sequence. If FIRSTNAME_TEST appears where the company should be, or a custom variable is blank, the mapping fails before a real prospect receives the mistake.
Duplicate suppression is a business rule
Instantly's import flow has a setting to check for duplicates across campaigns and lists. It recommends enabling the check, but the option can be turned off. MillionVerifier deduplicates repeated addresses inside one uploaded file for billing, but it does not compare a new file with every older file you verified.
The result is a dangerous assumption: "the tool deduped it" can mean only that one vendor removed duplicates in one local context. It does not prove that the lead is absent from another campaign, a previous client list, a customer table, a suppression list, or a replied-contact history.
Use a stable normalized email for person-level suppression and a normalized domain or company ID for account-level routing. Keep the reason. A duplicate skipped because the person is active elsewhere is different from a duplicate skipped because the record already exists in the destination.
The real preflight checks copy as well as data
Ink Persuasion ran a 1,128-row repair-only export that passed required-value checks, duplicate checks, and campaign copy-fit QA. It still failed the Instantly preflight on a line-issue category. The file remained pending review instead of being called upload-ready.
That example matters because import safety has several independent dimensions:
- Structure: UTF-8 CSV, one header row, unique column names, no merged rows, and no malformed line breaks.
- Identity: one normalized email, stable row ID, correct person-company relationship, and no blank recipients.
- Verification: raw status preserved and only the approved class released.
- Suppression: file-level, workspace-level, customer, reply, opt-out, and global blocklist checks.
- Copy fit: every variable used by every sequence step is present and sensible for that row.
- Destination: imported count, skipped count, and stored values read back from the sequencer.
A first-party verification run shows why the classes matter
In one anonymized Ink Persuasion list operation, 8,036 rows survived an earlier security-provider filter. Mailbox verification then produced 4,745 valid rows, 2,744 unverifiable rows, 369 invalid rows, 13 API-error rows, and 165 rows without a usable email.
The cold email CSV import checklist
- Freeze the source. Record the filename, row count, column count, and checksum.
- Preserve every raw status. Never overwrite the verifier response with your final send decision.
- Create a valid-only candidate file. Keep catch-all, unknown, invalid, disposable, blank, and error rows outside it.
- Apply ICP and suppression rules. A deliverable email can still be the wrong person or a blocked contact.
- Normalize and dedupe. Check the current file and the wider workspace.
- Validate every copy variable. Fail rows with missing, malformed, or wrong-context personalization.
- Run the mapping fixture. Inspect the stored lead and preview every sequence step.
- Import to a paused destination. No campaign should begin sending during QA.
- Read the destination back. Export or inspect the imported rows and compare them with the release file.
- Close the equation. Source rows must equal uploaded, excluded, quarantined, skipped, and unresolved rows.
source_rows = imported_rows + excluded_rows + quarantined_rows + destination_skips + unresolved_rows launch_allowed = unresolved_rows == 0 AND mapping_fixture == pass AND destination_readback == release_file
Frequently asked questions
Can I import the full report from MillionVerifier or ZeroBounce?
Not into the main campaign without filtering. Full reports retain multiple result classes. Use the valid or good split as the starting pool, then apply your campaign's ICP, suppression, mapping, and copy checks.
Should catch-all emails go into a cold email campaign?
Keep them out of the confirmed-valid main campaign. If your risk policy allows a test, isolate the cohort, reduce volume, name the stop condition, and monitor it separately. Do not let a catch-all value disappear during field mapping.
Does Instantly remove duplicate leads?
Instantly offers a duplicate check across campaigns and lists during CSV import, but it is a configurable setting. It also cannot infer every business-level suppression rule. Reconcile its skipped count and check customers, replies, opt-outs, and account-level routing separately.
What if the verifier and sequencer counts do not match?
Stop before launch. Classify each difference as a deliberate exclusion, duplicate, blocklist match, invalid format, mapping failure, platform skip, or unresolved row. A count mismatch without a row-level explanation is a failed import.
Is a valid email automatically safe to send?
No. Valid describes a mailbox verification outcome. Send-ready also requires a relevant person, clear suppression state, correct campaign variables, approved copy, and a verified destination record.
Reconcile a small import before releasing the full file
Use a paused destination and a bounded cohort first. The following 25-row example is illustrative, not a reported client campaign:
- 21 rows appear in the intended campaign with the correct stable IDs and field values.
- Two rows are skipped because the same emails already exist under the chosen duplicate rule.
- One row matches an existing suppression rule.
- One row stays quarantined because a required personalization field is unresolved.
The accounting closes: 21 imported + 2 duplicate skips + 1 suppressed + 1 quarantined = 25 source rows. These categories must be mutually exclusive for this reconciliation. The presence of 21 records alone would not prove what happened to the other four.
Read back the stored email, first name, company, custom fields, campaign ID, and lead status for each imported row. Preview every sequence step for the fixture. Keep the source record and destination record paired so a mapping error cannot hide behind a correct total.
Once the pilot passes, use the same checks for the full release. If a run is interrupted, resume from reconciled lead IDs; do not blindly reimport the entire file. The 8,252-to-5,602 list-cleaning case study explains the upstream decisions that happen before this destination gate.
Sources
MillionVerifier: Managing verification results
MillionVerifier: Uploading files, duplicates, and reports
ZeroBounce: Downloading validation results
ZeroBounce: Catch-all email validation
Instantly: How to import leads via CSV
Want this import gate built into your outbound system instead of relying on a filename and a hope?