Tools Solutions Pricing Blog
Log in Start for free
← All articles

How to Clean a Prospect List Before Cold Outreach (Apollo, ZoomInfo, LinkedIn Exports)

Prospect lists from Apollo, ZoomInfo, and LinkedIn exports need different cleanup than a CRM import: merging sources, suppressing existing contacts, and verifying emails before outreach.

On this page

You’ve got three tabs open: an Apollo export of 800 contacts matching your ICP filters, a ZoomInfo pull your manager sent over, and a CSV a VA scraped from LinkedIn Sales Navigator last week. Somewhere across those three files, some of these people are already customers, some are already mid-sequence with another rep, and some don’t have a real inbox behind the address at all. You’re about to merge all of it into one list and load it into Outreach anyway, because manually reconciling three spreadsheets by hand isn’t how anyone wants to spend a Tuesday.

This is a different cleaning problem than a CRM import. A CRM export is one file, one schema, one set of picklist values to fix. A prospect list is several files from several sources, none of which agree on how to format a company name, and the risk of getting it wrong isn’t a rejected row, it’s emailing a customer a cold pitch or burning your sending domain’s reputation on a list full of dead addresses.

Why prospect lists break differently than CRM exports

Most CSV cleaning advice, including the complete CSV cleaning checklist, assumes one file: fix the delimiter, normalise the picklist values, convert the dates, import. That’s still true here, but it’s not the hard part.

The hard part with a prospect list is everything upstream of “normalise the columns”:

  • The list didn’t come from one place. It came from three or four tools that each format the same data differently.
  • The goal isn’t just “does this row import cleanly”, it’s “does this row belong on this list at all.” A perfectly clean, perfectly formatted row for someone who’s already a customer is still a mistake.
  • The email addresses weren’t typed by a human who might make a typo. They were scraped, appended, or guessed by a third-party data provider, and a meaningful percentage of them don’t work.

Cleaning an event attendees list has some of the same shape (free-text job titles, inconsistent company sizes), because that data is also user-generated and messy. But an event list is one file from one platform. A prospect list is a merge-and-reconcile problem before it’s a normalisation problem.

1. Merge your sources before you clean anything

Every prospecting tool formats the same fields differently. Before you can deduplicate or normalise anything, you need one schema all three sources map into.

FieldApolloZoomInfoLinkedIn export (manual)
CompanyAcme Inc.Acme CorporationAcme
TitleVP of SalesVice President, SalesVP Sales @ Acme
IndustryComputer SoftwareSoftware(blank)
Company size51-200100(blank)

If you skip this step and try to deduplicate straight away, Acme Inc. and Acme Corporation look like two different companies to any exact-match dedupe logic, and you’ll email the same account twice from two different contacts without realising it.

Pick one canonical schema (your CRM’s field names are the obvious choice, since the list is headed there eventually) and map every source’s columns to it before anything else. The mapping mechanics are the same as standardising picklist values before a CRM import: define the canonical list, map every variant to it, apply in one pass.

2. Deduplicate across all the merged sources, not within one file

Merging three lists into one multiplies your odds of the same person appearing twice, sometimes with a different email address in each source. Deduplicate in two passes:

Contact-level. Exact match on email first. Then a secondary pass on first name + last name + company, to catch the same person with a work email in one source and a personal or outdated email in another.

Company-level, for account-based routing. Extract the domain from each contact’s email ([email protected]acme.com) and group by domain rather than the free-text company name field. This catches cases the company-name field would miss, Acme Inc. from Apollo and Acme Corp from ZoomInfo both resolve to acme.com, and lets you decide per-account how many contacts you actually want on one list, rather than accidentally targeting eight people at the same company from three different sources.

When you find a duplicate, keep the row with the most complete data (title, direct dial, LinkedIn URL), not necessarily the one from whichever source you happened to merge last.

3. Suppress against everyone you already have

This is the step that has no equivalent in a CRM import post, and it’s the one that causes the most damage when skipped.

Before a new prospect list goes anywhere, check it against:

  • Existing CRM contacts, at any lifecycle stage. Cold-emailing a current customer, or a lead already being worked by another rep, is an easy way to look uncoordinated in front of a prospect.
  • Active sequence members in Outreach, Salesloft, or whatever engagement tool you use. Someone already three steps into a sequence doesn’t need to start a second one.
  • Your do-not-contact / unsubscribed list. Emailing someone who opted out isn’t just bad practice, in some jurisdictions it’s a compliance problem.
  • Previously bounced addresses. If an address hard-bounced on a past campaign, sending to it again does nothing but hurt your sender reputation a second time.

In practice, this means keeping a running suppression file, every email and domain that’s ever been a customer, an active sequence contact, an unsubscribe, or a hard bounce, and checking every new prospect list against it before upload. A simple approach: export the suppression list as email + domain, then match your new list against it (exact match on email, domain match for account-level suppression) and remove or flag anything that hits. Refresh the suppression file before every new prospecting push, since yesterday’s opt-out is today’s exclusion.

4. Verify email deliverability before you load a sequence tool

Bought and scraped lists have a meaningfully higher invalid-address rate than contacts your own team entered by hand, and a bad batch doesn’t just fail quietly, it damages the sending reputation of the domain you use for every other campaign too.

What to check for:

  • Catch-all domains. A domain configured to accept mail at any address, valid or not, will return a “deliverable” result from basic syntax checks even when the specific mailbox doesn’t exist. These need a dedicated verification pass, not just a regex.
  • Role-based addresses. info@, sales@, support@ rarely reach a real person, and some spam filters treat high volumes of role-based sends as a signal on their own.
  • Syntax and scraping errors. Concatenation bugs (johnsmithacme.com, missing the @) and truncated values are common in scraped lists, less common in lists people typed by hand.

A general-purpose CSV cleaner can catch obvious syntax problems, but confirming a mailbox is genuinely deliverable requires a dedicated email verification service, that’s a different tool than anything that just cleans a spreadsheet, and it’s worth running before every cold send, not just the first one.

5. Normalise company names against your existing accounts

Once contacts are deduplicated and suppressed, the remaining company-name inconsistency still matters for one more reason: matching new prospects to accounts you already have in your CRM, for territory assignment or to avoid working an account two reps already own.

This is the same picklist-style mapping problem as step 1, applied against your CRM’s existing account list instead of just reconciling the three source files against each other. If your CRM already has Acme Corporation as an account name, map every variant your prospecting sources produced (Acme Inc., Acme, ACME Corp.) to that exact string, not a close approximation, since account matching is usually exact-match under the hood.

6. Format for your outreach tool, not your CRM

The list’s final destination usually isn’t your CRM directly, it’s Outreach, Salesloft, Instantly, or an Apollo sequence, and those tools have their own formatting expectations:

  • Personalisation fields. {{first_name}}, {{company}}, and any custom merge fields need to be populated for every row. A blank first_name doesn’t just leave a gap, it sends “Hi ,” or the literal {{first_name}} string to a real prospect, which is a worse first impression than no personalisation at all.
  • Custom field setup. Several sequence tools require a custom field to exist in the tool before a CSV column will map into it. Check this before upload, not after a failed import.
  • Column and row limits. Some tools cap the number of custom fields per contact or the rows per CSV upload, which matters if you’re merging several thousand-row exports into one file.

Catching blank personalisation fields before upload, rather than after the first email sends, is worth a manual scan of the merged file specifically for empty cells in whatever columns your templates reference.

If you prospect on a recurring cadence

If your team pulls a new Apollo or ZoomInfo list every sprint, this isn’t a one-off cleanup, it’s a workflow worth saving: the same source-to-schema mapping, the same suppression check, the same output format, run against a new file each time instead of rebuilt from memory. See repeatable CSV import workflows for RevOps teams for how to turn a recurring cleanup into a saved, minutes-not-hours process.

Quick reference checklist

  • All source files (Apollo, ZoomInfo, LinkedIn export, purchased list) mapped into one canonical schema
  • Company names, titles, and industry values normalised before deduplicating
  • Duplicates removed within the merged list: exact email match, then name + company
  • Contacts grouped by email domain to catch account-level duplicates across sources
  • Merged list checked against existing CRM contacts, active sequence members, and your do-not-contact list
  • Previously bounced addresses excluded
  • Emails checked for catch-all domains, role-based addresses, and scraping/syntax errors
  • Company names matched against your CRM’s existing account names, not just reconciled across sources
  • Personalisation fields (first name, company, custom fields) confirmed non-blank
  • File formatted to match your outreach tool’s column and merge-field requirements

Asphorem’s CSV Normalizer handles the merge-and-normalise steps once you’ve combined your source files into one CSV: mapping each source’s company, title, and industry values to your canonical list, removing exact duplicate rows, and saving the mapping so next sprint’s Apollo or ZoomInfo pull applies it in one click. It doesn’t replace a dedicated email verification service or a live suppression check against your CRM, those are separate steps worth running every time regardless of which tool cleans the spreadsheet itself.

Prospect List Cleaning: Frequently Asked Questions

How do I merge prospect lists from Apollo, ZoomInfo, and LinkedIn Sales Navigator?

Map each source’s columns to one canonical schema before doing anything else, since the three tools format company names, job titles, and industry values differently. Skipping this step means later deduplication will miss matches, Acme Inc. from one source and Acme Corporation from another will look like different companies even though they’re the same account.

How do I suppress contacts already in my CRM before a cold outreach campaign?

Keep a running suppression file of every email and domain that’s already a customer, an active sequence member, an unsubscribe, or a past hard bounce. Match your new prospect list against it by exact email (for individual suppression) and domain (for account-level suppression) before uploading anything to your outreach tool, and refresh the suppression file before each new prospecting push.

Why do bought or scraped prospect lists hurt email deliverability?

Bought and scraped lists have a higher rate of invalid, catch-all, and role-based addresses than contacts entered by your own team. Sending to a batch with a high bounce rate damages your sending domain’s reputation for every subsequent campaign, not just the one that caused it, which is why verifying deliverability before the first send matters more than for a typical CRM import.

How do I detect catch-all and role-based email addresses in a prospect list?

Catch-all domains accept mail at any address regardless of whether the specific mailbox exists, so a basic syntax check will report them as valid even when they aren’t. Role-based addresses (info@, sales@, support@) can be flagged by pattern matching on the local part of the email. Confirming true deliverability for catch-all domains requires a dedicated email verification service rather than a spreadsheet-level check.

What’s different about formatting a CSV for Outreach or Salesloft versus a CRM import?

Sequence tools rely on personalisation merge fields ({{first_name}}, {{company}}) that need to be populated for every row, since a blank field sends the literal placeholder text to a real prospect. Several tools also require custom fields to exist inside the tool before a CSV column will map into them, and enforce their own column or row limits, all of which differ from a standard CRM import wizard.

How often should I dedupe and suppress a prospecting list?

Every time, not just the first time you set up the process. A suppression list is only accurate as of the last time it was refreshed, and a contact who unsubscribed or became a customer last week won’t be caught by a suppression file that’s a month old. Treat merge, dedupe, suppress, verify, and format as a repeatable workflow run fresh against every new pull, not a one-time cleanup.

Stop fixing the same CSV problems every week

Asphorem maps your columns, standardises picklist values, and normalises dates so your next import works first time. Free plan included.

Start for free →