Most CRM migrations go wrong for the same reason: the team treats it as a file export and import. Someone downloads a CSV on Friday, uploads it to the new system on Monday, and by Wednesday the sales team finds three copies of the same customer, deals in stages that no longer exist, and a “Notes” column with ten years of shorthand nobody can read.
A good migration is mostly preparation. This checklist walks through that preparation for a small team moving from spreadsheets, a shared inbox or an older CRM. It’s tool-neutral: the steps apply whatever system you’re moving to.
A quick note on inChat: it’s a conversation-first CRM in development, and its import tooling hasn’t been announced. Nothing in this guide depends on a specific importer. Clean, mapped data in a CSV is useful for any system you choose.
Before you start: decide what “done” means
Write down, in one or two sentences, what the migration is for. For example:
By the end of next month, every active lead and customer is in the new CRM with an owner, a current stage and a phone number we can message. The old spreadsheet is read-only.
That sentence keeps the project small. It tells you that active records matter more than historical ones, that owner and stage are required fields, and that the spreadsheet will stop being edited on a specific date.
Also decide who owns the migration. On a team of 3–25 people, that’s usually one person (often an ops lead or the owner) plus one sales rep who knows how the data is actually used.
Step 1: Inventory every data source
Customer data rarely lives in one place. List every source, including the informal ones.
| Source | Owner | Records (rough) | Format | Last updated | Migrate? |
|---|---|---|---|---|---|
| Leads spreadsheet | Office manager | Google Sheet | |||
| Old CRM | Sales lead | CSV export | |||
| Personal phone contacts | Each rep | Phone contacts | |||
| WhatsApp or SMS chats | Each rep | Chat history | |||
| Email inbox | Owner | ||||
| Booking or invoicing tool | Office manager | CSV export | |||
| Paper or whiteboard | Team | Paper |
Questions to answer for each source:
- Is this the “source of truth” for anything (for example, the invoicing tool for billing addresses)?
- How current is it? A spreadsheet last edited eight months ago is a reference, not a source.
- Who can export it, and in what format?
- Does it contain sensitive data that shouldn’t be copied, such as payment details or health information?
Pay special attention to conversations on personal phones. They often hold the most current information about active deals, and they’re the hardest to move. Our guide to moving client chats off personal phones covers that part separately.
Step 2: Export and freeze a snapshot
Export everything you listed into files, and store the originals somewhere safe and unchanged. Work on copies only.
- Export to CSV where possible, with a header row.
- Name files with the source and date, such as
old-crm-contacts-2026-10-29.csv. - Note the record count of each file so you can check nothing was lost later.
- Keep the original exports until well after go-live.
Step 3: Map your fields
Field mapping is where you decide how each column in the old data becomes a field in the new system. Do it in a spreadsheet before touching any import tool.
Mapping table template
Copy this table and fill in one row per source column:
| Source | Source column | Example value | New object | New field | Field type | Transform rule | Required? | Notes |
|---|---|---|---|---|---|---|---|---|
| Leads sheet | Name | “maria g” | Contact | First name / Last name | Text | Split on first space; title case | Yes | |
| Leads sheet | Phone | “(555) 010-0142” | Contact | Mobile phone | Phone | Convert to +1XXXXXXXXXX | Yes | Primary key for dedupe |
| Leads sheet | Source | “FB ad” | Contact | Lead source | Picklist | Map “FB ad”, “facebook” to “Facebook” | No | |
| Leads sheet | Status | “Hot” | Deal | Stage | Picklist | See stage map | Yes | |
| Leads sheet | $ | “4.5k” | Deal | Amount | Currency | Convert to 4500 | No | |
| Old CRM | Owner | “jsmith” | Contact, Deal | Owner | User | Map usernames to new users | Yes | |
| Old CRM | Notes | Long text | Contact | Note (timeline) | Note | Import as one dated note | No | Review for sensitive data |
| Old CRM | Fax | Don’t migrate | Unused |
Rules for good mapping
- Normalize phone numbers. For a messaging CRM, the phone number is often the key that links a conversation to a contact. Convert every number to one format, with country code, such as
+15550100142. - Turn free text into picklists where it matters. “FB”, “Facebook”, “facebook ad” and “Meta” should become one lead source value.
- Split combined fields. Full name into first and last; “City, State” into separate fields.
- Create custom fields only for data you’ll actually use. If nobody has filtered by “Fax” in five years, don’t recreate it.
- Decide the object. Some columns belong on the contact, some on the company, some on the deal. A budget belongs on the deal; a birthday belongs on the contact.
- Map owners explicitly. Every active record should have an owner in the new system. Departed reps’ records need to be reassigned before import, not after.
Step 4: Set dedupe rules
Duplicates are the most common complaint after any migration. Decide your contact deduplication rules before you import, not after.
Choose your matching keys
In order of reliability for most small teams:
- Mobile phone number (normalized)
- Email address (lowercased, trimmed)
- Name plus company or name plus postal code (weak; flag for review, don’t auto-merge)
Decide which record wins
When two records match, decide which values survive:
| Situation | Rule |
|---|---|
| Both have a value, and they differ | Keep the most recently updated value; keep the other in a note |
| One is blank | Keep the filled value |
| Different owners | Keep the owner of the most recent active deal; flag for the team lead |
| Different stages | Keep the more advanced active stage; review manually |
| Both have notes | Keep both, combined into one dated note |
Dedupe checklist
- Phone numbers normalized before matching
- Emails lowercased and trimmed
- Exact matches merged using the rules above
- Fuzzy matches (similar names) exported to a review list, not auto-merged
- Shared numbers (a business main line, a family phone) flagged so they don’t merge different people
- Final record count compared with the original count, with the difference explained
Step 5: Map your pipeline stages
Old systems often have too many stages, or stages that mean different things to different people. Use the migration to clean them up. For a starting point, see sales pipeline stages for a service business.
Build a stage map:
| Old stage or status | New deal stage | Notes |
|---|---|---|
| New, Inquiry, Lead | New inquiry | |
| Contacted, Called, Texted | Contacted | |
| Hot, Warm, Interested | Qualified | Only if qualification questions were answered; otherwise Contacted |
| Quote sent, Proposal | Quote sent | |
| Verbal yes, Pending | Verbal commit | |
| Won, Closed, Paid | Won | |
| Dead, No response, Lost | Lost | Add a lost reason if known |
| Cold (no activity in 6+ months) | Don’t migrate as an open deal | Keep the contact; close the deal as Lost |
Two rules make this easier:
- Every old stage maps to exactly one new stage. If you can’t decide, the new stage definitions need work.
- Stale open deals get closed, not migrated. An open deal with no activity in six months distorts your pipeline. Close it with a reason and keep the contact.
Step 6: Decide what not to migrate
Leaving data behind is part of a good migration. Common candidates:
- Records with no way to reach the person: no phone and no email
- Unused fields: columns that are blank on most rows or that nobody uses
- Very old closed deals: keep a summary on the contact, or keep the archive file instead
- Test records and junk: “test test”, “asdf”, internal staff entries
- Sensitive data that doesn’t belong in a CRM: payment card numbers, government ID numbers, health details. Keep these out entirely.
- Contacts who opted out of messaging: you may want to keep the record so you don’t contact them again, but mark the opt-out clearly and don’t put them in any outreach list.
- Automation and workflow rules: rebuild these in the new system rather than trying to copy them
Keep the full original exports archived, read-only, so nothing is truly lost.
Step 7: Clean and test with a sample
Before importing everything:
- Apply your transforms to the full file in a spreadsheet: phone format, picklist values, splits.
- Run your dedupe rules.
- Import a sample of 20–50 records that includes edge cases: a duplicate, a missing email, a long note, a departed rep’s record, a shared phone number.
- Check each sample record in the new system by hand. Are fields in the right place? Did the stage map correctly? Is the owner right?
- Fix the mapping, then delete the sample and repeat until it’s clean.
Step 8: Plan the cut-over
The cut-over is the moment the old system stops being used and the new one becomes the source of truth. The goal is to keep the double-entry period as short as possible.
A simple cut-over plan
| When | What happens | Owner |
|---|---|---|
| One week before | Announce the cut-over date and the “freeze” rule to the team | Migration lead |
| Two days before | Final mapping and dedupe test passed on a sample | Migration lead |
| Cut-over day, morning | Old system set to read-only; final export taken | Migration lead |
| Cut-over day, midday | Full import run; record counts checked | Migration lead |
| Cut-over day, afternoon | Each rep checks their own active deals and fixes anything off | Each rep |
| Day 2–5 | Daily 10-minute check-in on missing or wrong records | Team lead |
| Day 30 | Old system archived; access removed | Owner |
Rules for the cut-over window
- One source of truth at a time. After the freeze, nobody edits the old system.
- Pick a quiet day. Avoid end of month or a busy season.
- Expect a few fixes. Ask reps to report problems in one place, such as a shared list, instead of fixing them silently.
Step 9: Verify after go-live
Check the result against your “done” sentence from the beginning:
- Record counts match the cleaned source counts, with the difference explained
- Every active contact and deal has an owner
- Every open deal has a current stage
- Every contact you message has a phone number in the correct format
- Opt-out flags carried over
- A spot check of 20 random records matches the source
- Old system set to read-only and archive stored
Common migration mistakes
- Importing first, cleaning later. Cleaning inside the new system is slower and spreads errors.
- Keeping every field “just in case.” The new CRM inherits the clutter that made the old one hard to use.
- Auto-merging on names. Two different “Maria Garcia” contacts become one.
- No owner on records. Records without owners don’t get followed up.
- A long parallel period. Running both systems for weeks means neither is accurate.
- Forgetting the conversations. If the real deal history lives in chat threads on personal phones, migrating the spreadsheet only moves half the picture.
After the migration
Clean data at launch decays without habits to maintain it. Set a few rules:
- New contacts are created with a normalized phone number and an owner.
- Each conversation is linked to the right contact and deal.
- Stages are updated when the deal moves, not at the end of the week.
- Someone reviews possible duplicates on a regular schedule.
These habits are easier when the conversation and the record are in the same place, which is the idea behind a messaging CRM. Our lead management guide covers the day-to-day process, and the 30-day messaging CRM rollout plan covers how to bring the team along. For how inChat is designed to handle contacts and history, see contact management. If you run a small team, see how inChat is meant to work for small business teams. The product is in development, and you can join early access to follow its progress.