Why Attio's native CSV import isn't enough
The CSV importer is the first thing most teams reach for when they move into Attio. It is right there in the product, it is free, and a contacts export is one click away in the old CRM. For a single flat list of people with an email column, it works exactly as advertised.
The trouble starts the moment the data has shape. Companies that link to people. Deals that link to both. Select fields with options that have to match. A pile of notes and meetings that carry the actual history. The native importer was built to load records into one object, not to rebuild a CRM. That is a different job, and the gap between the two is where most self-serve migrations quietly go wrong.
This is the honest map of what the CSV importer does, where it stops, and what to use instead.
Does Attio's CSV import work?
Attio's native CSV import works for loading a single object's records and their basic attributes, and it is the wrong tool for everything beyond that. It imports one file into one object at a time, so People, Companies, and Deals each need a separate pass. It matches records on one column you choose, so a missing or inconsistent key creates duplicates instead of updates. It does not move notes, tasks, emails, meetings, or attachments, because CSV carries records and fields only. It does not transform data on the way in, so split names, reformatted phone numbers, and parsed dates have to be fixed in the spreadsheet first. And it cannot reliably rebuild relationships between objects in one run, because a link only resolves if the record it points to already exists. For a flat contact list it is fine. For a real CRM with linked objects and history, it covers maybe a third of the work.
What does the native CSV importer actually do well?
Give it credit for the job it was scoped for. Upload a CSV, map each column to an existing attribute, pick a column to match on, and Attio loads the rows into the object you chose. For a clean list of people or companies, with text, number, and a few select fields, it is fast and it is free. If you are starting a workspace from a single spreadsheet of contacts and nothing links to anything yet, stop reading and use it.
The problems are not in that path. They are in everything a migration adds on top of it.
Where does the native CSV import break?
Six places, in roughly the order teams hit them.
- One object per file. You import People, then Companies, then Deals as separate passes. Nothing about the importer understands that these are parts of one model. The coordination between them is on you.
- Matching is a single column. Attio dedupes on the one field you nominate, like email for People or domain for Companies. If that column is blank, formatted differently, or duplicated in the source, you get new records instead of merges. A second import meant as an update silently doubles the data.
- Relationships do not resolve on their own. To link a Person to their Company, the Company has to exist already and the match value has to align exactly. Import the objects in the wrong order, or let the domains drift even slightly, and the links land empty.
- Select and status options drift. Values in the CSV map to existing options. When the casing or wording is off, you end up with "Closed Won", "closed-won", and "Won" living as three separate options on the same field.
- No transformation on the way in. What sits in the cell is what lands. Full names do not split into first and last. Phone numbers and dates are not normalised. The importer is a loader, not a cleaner.
- History is not invited. Notes, tasks, emails, meetings, and files do not come through CSV at all. The records arrive with none of the context that made the old CRM worth keeping.
None of these are bugs. They are the boundary of what a CSV loader can do. The mistake is expecting it to do the migration.
Why is "one file at a time" the real problem?
The single-object limit sounds like an inconvenience. It is actually the thing that makes self-serve migrations go sideways, because a CRM is its relationships. A Deal with no contacts attached is a number with no story. A Person floating free of their Company breaks every filter, every view, and every report that segments by account.
To rebuild those links through CSV, you have to import in dependency order, keep a clean match key on every file, and hope nothing drifts between passes. Companies first, matched on domain. People next, referencing those domains exactly. Deals last, pointing at both. One inconsistent value anywhere in that chain and the links fail without an error, so you do not find out until a report comes back wrong weeks later. That is the difference between loading records and migrating a system.
When is native CSV import the right call?
Use it, without hesitation, when all of these are true.
- You are populating one object, not a linked model.
- The source is a single clean spreadsheet, not a CRM with history.
- You do not need notes, emails, or meetings to come across.
- The match key on your file is present and consistent on every row.
If that describes the move, the native importer is the fastest path and anything else is overkill. The list is also the test. The moment two of those go false, you have outgrown it.
What should you use instead?
Match the route to the shape of the data, not to whichever button is closest.
Import2, for core CRM objects. Attio's official one-click migration, free when you start it from the Migrate button inside Attio. It moves companies, people, deals, custom objects, notes, and tasks together, with the relationships intact, from HubSpot, Salesforce, Pipedrive, Close, Affinity, Copper, Zoho, and more. It does not move emails, meetings, or attachments. For most standard CRM moves this is the right default, and it skips every trap above.
The Attio API, for scale and complex links. For datasets over a few thousand records, or several related custom objects that have to land together with their links resolved, scripting against the API is the repeatable, controllable route. It transforms on the way in, retries cleanly, and can be run twice without doubling the data.
Assisted migration, when the model changes. The hardest migrations are not technical. They are the ones where the new workspace should not mirror the old one. New objects, fewer fields, relationships drawn differently. That is design work before it is import work, and it is exactly where we spend most of a migration. If you would rather not hand-stitch the dependency order and the match keys yourself, that is the gap we built our migration tooling and our process to close.
Whichever route fits, the sequence is the same one in the Attio migration checklist: decide what the new CRM should look like first, then move the data into it. The native CSV importer is one tool in that plan. It is not the plan.
For the source-specific playbooks, see HubSpot to Attio, Pipedrive to Attio, and Google Sheets to Attio.
Need help with your Attio setup?
We migrate teams, build data models, wire automations, and train Claude agents inside your workspace. Discovery call is free.
Book a free discovery callReady when you are.
Two ways in. Pick the friction that fits.