KarmaFlow supports bulk import of contacts and lists from CSV files, Excel spreadsheets (.xlsx / .xls), and directly from connected cloud storage (Google Drive and OneDrive).
.xlsx and .xls workbooks. The first sheet is imported automatically.An import is three steps: choose the file, decide where each column goes, then run it. Nothing is written until you confirm the mapping.
The import runs while you wait. When it finishes, KarmaFlow shows a summary of what happened.
The mapping step lists every column in your file with its first few values and a target: a Contact field, a Company field, a Consent column, one of your Custom fields, or Skip. Each column is pre-filled, and a note says where the suggestion came from:
| Note | Meaning |
|---|---|
| Recognised | The column name is one KarmaFlow knows (Email, Mobile Phone, # Employees…). An Apollo export is recognised in full. |
| From your saved profile | You have imported a file with these columns before and saved the mapping. |
| Your custom field | The column name matches one of your custom fields. |
| Vendor bookkeeping | A data vendor's own id or status column (Apollo Record Id, HubSpot Contact Id…) — suggested as Skip. |
| Looks like it | Nothing matched the name, but the values look like email addresses or phone numbers. |
| AI suggestion | For columns nothing else matched, a small model proposes a target from the same list you see. It is a suggestion only — nothing is applied until you import. |
| No match | Nothing to say; the column starts as Skip. |
Use the Needs a look filter to review only the columns a person should check. Skip does not lose anything: every contact keeps its full original row under Imported data. Two columns on one target are allowed — the first filled value wins, and for Email the rest become alternate emails.
Custom fields. Pick + Create custom field… in a column's target list to create a field without leaving the page; the column is mapped to it. Values are stored by the field's type (a number column becomes a number, a Yes/No column a checkbox).
Import profiles. Tick Save as an import profile and the next file with the same columns opens already mapped — no guessing and no model call. The profile is saved once the import succeeds. Profiles remember the mapping and the options below; they never remember the mobile confirmation, which is a decision about one file. Your saved profiles are listed under Remember this layout on the mapping step, where you can apply one to the current file, rename it, or delete it; not this one beside an applied profile puts every column back to the automatic suggestions.
A row that matches a contact already in your CRM (by email, or by phone when there is no email) is merged by the policy you choose:
| Policy | What happens |
|---|---|
| Fill empty fields only (the default) | The contact keeps every value it has; the file only fills the blanks. |
| Overwrite with this file | Values in the file replace what is stored, including the owner. Empty cells still change nothing, and the email the contact was matched on is never replaced. |
Under either policy an import can only tighten consent — an opt-out on record is never undone by a file.
A file that carries opt-in or opt-out columns can map them to SMS consent, Email consent, Call consent / Do Not Call, or Do not contact (all channels). A "No", "opted out" or "unsubscribed" value records that opt-out on the contact's consent card, with the column name and value it came from. A "Yes" changes nothing: contacts are opted in by default, and a spreadsheet cannot grant consent. Do Not Call columns are recognised automatically as the voice opt-out.
Consent and mobile confirmation are two different facts. Consent says whether a person may be contacted at all; confirmation says whether a mobile number is really theirs. Autonomous campaigns text a mobile only once it is confirmed — the contact texted from it, or someone vouched for it — because a purchased or scraped list is not the person's word. Imported mobiles therefore wait by default, shown as from import, unconfirmed on the contact.
When the file is your own customer or sign-up export, tick These mobile numbers belong to the people listed and may be texted by campaigns on the mapping step. The numbers are then imported as confirmed, and the attestation is recorded under your name in the audit log. It applies to this upload only and never changes consent: anyone who opted out stays opted out.
You can also confirm later — one contact with Confirm beside its mobile, or a whole list with Confirm all on the list's Unconfirmed mobiles tile.
Importing requires the crm:import permission; confirming mobiles requires crm:contacts:edit.
By default, imported records land in the Contacts module. Tick Import as leads to have new records land in CRM > Leads instead, at lifecycle stage Lead — the right choice for a file of cold prospects that still need qualifying. The option only affects records the file creates: a record that already exists in your CRM keeps its current lifecycle stage, so re-importing a customer's email can never demote them back to a lead. The same option is available when importing into a list.
To import contacts directly into a list:
Matching contacts are created or updated and then added to the list. The mapping step is the same one contact imports use.
Companies import from their own page:
Columns like name, domain, website, industry, size, phone, city and country are mapped automatically. An existing company is matched by domain first, then by an exact name match, and only its empty fields are filled from your file — an import never overwrites company data you have curated.
Column names are matched automatically, whatever the file calls them (Email, email_address and Primary Email all land in the same place), and the mapping step lets you correct or extend any of it. Beyond the basics — name, email, phone, company, title, LinkedIn — a contact file can carry:
| Column (Apollo names shown) | Where it lands |
|---|---|
Work Direct Phone, Mobile Phone |
The direct line becomes the contact's phone (typed direct) and the mobile keeps its own mobile slot. With only one of the two, that one is the phone. A mobile that came from a file is shown as from import, unconfirmed: an agent or a person can text it, but an autonomous campaign only texts a mobile the contact gave you or texted you from — it opens up the moment they text from it, when you click Confirm on the contact or Confirm all on a list, or when you vouched for the file's mobiles on the mapping step. |
Corporate Phone, Company Phone |
The company's phone. A switchboard is never stored as a person's number. |
Seniority, Departments, Sub Departments |
Seniority and Departments on the contact — the persona axes for filters and saved views |
City, State, Country, Postal Code |
The contact's location (the single-line Address column is kept as well) |
Email Status, Email Confidence, Catch-all Status, Last Verified At |
Email verification as the source asserted it — shown on the contact, filterable, and separate from bounces your own sends record |
Do Not Call, SMS Opt-in, Unsubscribed, Do Not Contact |
Consent: a stated opt-out sets that channel's opt-out (or the master do-not-contact switch). An import can only tighten consent, never loosen it. |
Secondary Email, Tertiary Email |
Other emails on the contact; the first filled email column is the one you write to |
Stage, Lists, Last Contacted, Account Owner, Email Sent, Replied, Demoed |
Shown on the contact as the source's own history. Never mapped onto your lifecycle stages, owners or bounce state. |
Company Name for Emails, Website, Industry, # Employees, Keywords, Technologies, Annual Revenue, Company City / State / Country, SIC Codes, NAICS Codes, funding columns, intent columns |
The contact's company — created or matched as the file loads (next section) |
An Apollo export is recognised from its own columns and reported as such on the result panel. Columns the CRM has no field for are not lost: every contact keeps its full original row under Imported data on the contact page, and the result panel lists the unmapped column names.
A contact file names a company on every row, and a contact with no company record cannot be segmented by industry, headcount or country. The Companies option on the contact and list import forms decides what happens to them:
| Option | What happens |
|---|---|
| Create or link companies (the default) | Each row's company is matched by its website domain, then by the contact's email domain, then by exact name — and created when none matches. The contact is linked to it and inherits its industry, headcount and country for the contact filters. An existing company only has its empty fields filled. |
| Link to existing companies only | The older behaviour: each row's email domain is matched against the companies already in your CRM (by the company's domain, or by any domain listed on it for helpdesk routing). No company is created. |
| Leave companies alone | The people are imported and the company name stays as text on the contact. |
Importing companies. On the company import form, tick Associate matching contacts by email domain. Every company in your file then adopts the contacts already in your CRM whose email ends in its domain. This is the one to use when the people arrived before their company did.
All three paths are deliberately conservative:
| Situation | What happens |
|---|---|
| Contact already has a company | Left exactly as it is — an import never re-files someone |
Personal address (gmail.com, outlook.com, yahoo.com…) |
Never used as a company domain — one shared provider would otherwise sweep unrelated people into a single company. With Create or link, such a row falls back to the company's website or exact name. |
A subdomain such as eu.acme.com |
Not treated as acme.com; it may be a separate organization |
| Contact has a company name typed in but no company record | The link is made, and your typed text is kept |
| A company already in the CRM | Its blanks are filled from the file; nothing you curated is overwritten |
The result panel reports what happened: how many rows were new or matched an existing contact, which of the richer columns landed (mobiles, direct lines, email verification, seniority, location, custom fields), how many companies were created or matched and how many contacts were linked, which opt-outs were recorded by channel, how many mobiles were confirmed and by whom, and which columns your mapping skipped.
Headcount. A company stores the exact headcount a file gives it (# Employees: 250) and derives its Size range (201-500) from it, so the Size filter keeps working. Pick a Size by hand only for a company whose exact headcount is unknown.
Two other tools pick up where the import option stops. The Suggestions button on CRM > Companies works from the company names typed on your contacts rather than from email domains: it lists names that have no company record yet, and Create & Link makes the company and attaches those contacts. And for hand-picking — someone on a personal address, or a company whose people span several domains — open a company and click Contacts to review suggested people and link them yourself.
Files imported before this option existed. Contacts keep their original rows, so an administrator can re-run the mapping over them from the platform console (Imported Contacts: Re-map Dropped Columns, dry run first) without anyone re-uploading a file.
Every import form carries an Assign owner picker. Choose a user and every record the file creates is assigned to them; records that already exist keep their current owner, and only unowned ones are filled — an import never reassigns anyone's book unless you chose Overwrite with this file on the mapping step, which assigns matched records too. Contact, list, and company imports leave records unassigned when the picker is left on Unassigned; deal imports default to the person running the import.
Deals have their own importer at CRM > Deals > Import, with company and contact association built in — see Deals for the full column set and matching rules.
Different regions use different delimiters in CSV files:
| Region | Common Delimiter |
|---|---|
| North America, UK | Comma (,) |
| Germany, France, Italy, Spain | Semicolon (;) |
| Tab-delimited exports | Tab |
| Legacy systems | Pipe (|) |
The mapping step detects the separator from your header row and shows it above the column list. If the columns look wrong (one long column, or values split mid-word), change the Separator there and the preview re-reads the file.
If you have connected Google Workspace or Microsoft 365 in your account settings, the import page will show those sources automatically. You can:
To connect a cloud storage provider, visit Settings > Google Workspace or Settings > Microsoft 365.
YYYY-MM-DD) for dates where possibleDuring import, KarmaFlow matches each row to an existing contact by email address, or by phone when the row has no email. If a match is found:
When an import into a list finishes, the Import Complete screen offers the natural next steps: View this list, Send a campaign to this list (opens the campaign wizard with the list already selected — see Sending a Campaign), and Import More. Contacts imported with a phone number are matched to SMS conversations by that number, so replies to a campaign land on their timeline.
You can review past imports from the import page. Each import shows: