Home /how-it-works/csv-import

How does InsertLead import leads from a CSV?

Drop a CSV from Podio, PropStream, BatchLeads, or hand-built lists, and InsertLead auto-detects columns, normalizes phone numbers to E.164, normalizes addresses, dedupes against your existing leads by name + address, and gives you a preview before you commit. The whole flow is designed for the wholesaler who wants to import a 2,000-row pull and start a campaign in five minutes without touching Excel.

On this page
  1. Supported file formats
  2. Auto-detected columns
  3. Phone + address normalization
  4. Name + address dedup
  5. Preview + commit flow
  6. Audience-type tagging

Supported file formats

Standard CSV (comma-separated) is the primary format. We also accept TSV and Excel exports if they're saved as CSV first. UTF-8 is preferred; Windows-1252 (the default Excel encoding) is auto-detected and converted.

Specific exports we test against on every release:

  • Podio — the most common wholesaling CRM export. Comes with mixed casing in column headers and embedded commas in address fields.
  • PropStream — data-rich exports with 30+ columns. We pull only what we need.
  • BatchLeads — clean structure, easy parse.
  • Manual lists — anything you build in Google Sheets and export. As long as you have at minimum a name column, an address column, and a phone column, we can work with it.

Auto-detected columns

We don't ask you to map columns by hand. Instead, we look at the headers (and the first few rows of data) to guess which column is which. The map we build:

  • Name — first name + last name, or full name. We'll split on space if only one name column is present.
  • Phone — any column whose values look like phone numbers (10-digit US format, or already E.164).
  • Address — street address. Often labeled "Property Address," "Mailing Address," or just "Address."
  • City, State, ZIP — pulled separately if the columns exist.
  • Custom fields — everything else gets stored as a JSON blob on the lead so the autoresponder can reference it. (E.g., "Equity %" or "Last sale year" if your data source includes them.)

If the auto-detect makes a mistake, you can override on the preview screen before commit. Future improvement: import-template profiles you can save and reuse.

Phone + address normalization

Phone normalization

Every phone goes through the phonenumbers library to land in E.164 format (+1XXXXXXXXXX for US). Garbage in:

  • (555) 867-5309
  • 555.867.5309
  • 5558675309
  • 15558675309

All of those become +15558675309 at insert time. Anything that fails to parse (random text, fewer than 10 digits, foreign formats) is rejected with a row-level error so you see exactly which rows didn't import.

Address normalization

Addresses get USPS-style cleanup: trailing whitespace stripped, double-spaces collapsed, "Street" / "St" / "St." normalized to "St", "Apartment" / "Apt" / "Apt." to "Apt", and so on. We do NOT geocode (no Google Maps API call), so we won't catch a typo in the street name — just formatting noise.

Name + address dedup

The most-asked-about feature. The rule is: two leads are the same person if their normalized name + normalized address match. Phone alone is not the dedup key — same household members might share a phone, and the same person might have multiple phones across imports.

When you upload a CSV that contains rows already in your database, we don't re-insert them. Instead, the existing lead gets updated (latest custom-field values, latest phone if it changed) and a new "import_batch" pointer is added to its history. The audit trail shows every batch a lead was part of, which is useful for "did I re-text this person already?" debugging.

Dedup is scoped to your account, not platform-wide. Another InsertLead user with the same lead in their list isn't affected. (The one cross-tenant exception is the global DNC — covered on the DNC compliance page.)

Preview + commit flow

Every import shows you a preview screen before commit:

  • How many rows are new vs. duplicate.
  • How many rows have invalid phone numbers (with row numbers so you can fix them).
  • Sample of the first 20 rows with the auto-detected column mapping.
  • Estimated cost if you immediately send a campaign on this audience (varies by tier and campaign type).

Hit "Commit Import" and the leads land in your database with an import_batch_id tag so you can target them in a campaign by batch. Hit "Cancel" and nothing was written.

Audience-type tagging

When you create the import batch, you tag it with an audience type: vacant land, pre-foreclosure, probate, absentee owner, expired listing, or "general." This tag flows through to the campaign engine, which uses it to pick the most appropriate template intro AND tells the AI autoresponder what kind of lead it's talking to (so probate replies sound different from absentee-owner replies, for example).

You can mix audience types within one batch if your data source doesn't separate them, but the AI autoresponder works best when the audience type is accurate.


Ready to try it? Request beta access