Salesforce to Attio migration: the step-by-step playbook
Moving a revenue team off Salesforce is mostly a modelling exercise, not a data exercise. This is the playbook we use in production: who should migrate and who genuinely should not, how every Salesforce object maps to Attio, what breaks on the way, and the checklist that keeps your pipeline moving through cutover.
Attio is a deliberate downgrade if you run a large service organisation in Service Cloud, quote through CPQ, or sit on years of Apex that encode how your business actually works. Stay where you are. It is a liberation if you are a revenue team of 5 to 50, a fund running relationship pipelines, or a scale-up paying enterprise prices for a database nobody keeps clean.
The data move is the easy half. The real work is rebuilding automations and reporting on the other side, and deciding what deserves to survive the trip. Plan 3 to 6 weeks, dry run on a copy, and keep Salesforce read-only for a quarter after cutover.
Who should migrate, who should stay
Attio is not a smaller Salesforce. It is a different species of CRM: your market as a typed, relational database with a serious API, instead of a platform you administer. That difference, more than any feature list, decides who wins in the move and who regrets it.
When Attio is a downgrade, and we say so
Large call centres and service organisations living in Service Cloud. Quote-heavy motions where CPQ, price books and approval matrices are load-bearing. Orgs with years of Apex that effectively run the business. Regulated industries that depend on territory management and enterprise sharing rules. For these teams, Salesforce remains the right tool, and pretending otherwise would waste your money and our reputation.
When it is a liberation
Revenue teams of 5 to 50. Funds and investors whose pipeline is relationships, not tickets. B2B scale-ups paying Enterprise prices to use a tenth of the platform. Teams whose reps live in Gmail and Calendar while the CRM quietly rots. If you want automations and AI agents reading and writing through a clean API instead of admin-ware, this is the move. See what we build on Attio day to day.
Coming from HubSpot instead? The trade-offs differ enough that we wrote a separate playbook: HubSpot to Attio migration.
How Salesforce objects map to Attio
Do not replicate your org. Half the value of this migration is shedding structures that only existed because Salesforce made you build them. Here is the mapping we apply in practice, including the rows where Attio has no answer.
| Salesforce | Attio | What changes in practice |
|---|---|---|
| Leads + Contacts | People (one object) | The lead versus contact split disappears. Lead status becomes an attribute or a list membership. The same human stops existing twice with two separate histories. |
| Accounts | Companies | Near one-to-one. Parent and child hierarchies become relationship attributes between company records. |
| Opportunities | Deals | Stages map to deal stages. Multiple pipelines split by record type become separate lists, or separate objects when the underlying data truly differs. |
| Record Types | Custom objects or lists | What record types simulated, Attio models directly: one real object per entity, or one object viewed through different lists. |
| Custom fields | Attributes | Typed attributes: select, currency, date, record reference. Formula fields do not port; rebuild the few that matter in a workflow or downstream service. |
| Activities (Tasks, Emails, Events) | Tasks, notes, native Gmail and Calendar sync | Email logging stops being a discipline problem because the sync is native. Historical activity imports as timeline entries on the record. |
| Campaigns + Campaign Members | Lists with entry attributes | Campaign membership becomes list entries that carry their own attributes, queryable like everything else. |
| Products, Price Books, Quotes | No native equivalent | The honest row. Attio has no CPQ and no native quoting. Quoting moves to PandaDoc or similar, billing connects through Stripe or Pennylane. |
| Reports and Dashboards | Views, plus a thinner native reporting layer | Attio reporting is younger than Salesforce reporting, full stop. Operating views cover the day to day; deep historical analytics belong in a BI layer. |
The Leads versus Contacts merge is the single biggest data-quality win in the whole move: one person, one record, one history. It also forces a deduplication decision before import, not after, which is exactly where most self-run migrations go wrong.
What breaks in a Salesforce to Attio migration
None of this is a surprise mid-project if you audit first. All of it is painful if discovered after cutover. Be clear-eyed about the list before you commit.
Apex triggers and classes
Nothing written in Apex ports. Inventory every trigger and class, and expect most to be dead: orgs accumulate automation the way attics accumulate boxes. The living ones get rebuilt as Attio workflows, n8n flows, or small API services you own. That last option sounds like a regression and is usually an upgrade: revenue logic in version-controlled code instead of logic buried inside a CRM.
Validation rules
Attio enforces types and required attributes but has no validation rule engine. The guardrails move to the write layer: every automation that touches the workspace validates before it writes. In our PE and M&A fund deployment, every data point extracted from a meeting passes a second adversarial check that rejects anything that was not actually said. That is stricter than any validation rule we ever wrote in Salesforce.
Historical reports and snapshots
Report definitions and reporting snapshots do not port. Export the underlying data, archive the snapshots in your warehouse, and rebuild only what people still look at. Run the viewer audit before deciding what to grieve: most orgs find that the large majority of their reports have had no viewers in months.
Territory management and sharing rules
Attio permissions are workspace-level and simple. There is no role hierarchy, no territory model, no record-level sharing engine. If your sharing model is a compliance requirement, treat that as a strong signal to stay on Salesforce. If it was an artifact of org politics, you will not miss it for a single day.
CPQ and approval processes
No native quoting, no approval engine. Quote generation and signature move to PandaDoc, approval steps become explicit workflow gates with a human in the loop. For most teams under 50 seats this ends up as two tools doing cleanly what one module did expensively.
How to migrate Salesforce to Attio, step by step
A Salesforce to Attio migration runs in a fixed order: build the Attio model first, export from Salesforce, import Companies, then People, then Deals, then notes and tasks, then list memberships. Sequence is not a preference. Import People before Companies and Attio cannot auto-link them.
Build the Attio model before you import anything
Teams who import first and design later pay for it twice, because the second pass means deleting records and re-importing. Stand up the objects, attributes and lists against your real motion first. Decide where Salesforce record types become separate objects and where they become lists viewed differently. This is the same model-design week that section 01 calls the highest-leverage part of the move.
Export from Salesforce, object by object
A full Data Export of Accounts, Contacts, Leads, Opportunities, Activities and Campaign Members, plus the Salesforce IDs that hold your relationships together. The section below covers exactly which export to run and why the IDs matter more than the field values.
Import Companies first, deduped on domain
Companies are the anchor everything else links to. Attio matches and deduplicates companies on domain, so a clean domain column is worth more than any other field. Do not import employee counts, founding years or revenue: leave those columns empty so Attio's own enrichment fills them. The traps section explains why importing them silently breaks enrichment forever.
Import People, matched on email, carrying their company domain
This is where the Salesforce Leads-and-Contacts split finally collapses into one People object. Carry each person's company domain on the row so Attio links them to the company you just imported. Deduplicate on identity before this step, not after: at a PE and M&A fund we had to resolve booking stubs from Calendly against enriched LinkedIn profiles where the same human carried different email addresses, and email matching alone would have left duplicates.
Import Deals with name, owner and stage on every row
Attio rejects a deal that is missing a name, an owner or a stage, so map those three first and map them completely. Opportunity stages become deal stages; multiple Salesforce pipelines split by record type become separate lists or separate objects. Aim for an owner populated on every single deal, because ownerless records die quietly in any CRM.
Import notes and tasks, then list memberships, last
Notes, tasks and historical activity import as timeline entries through Import2 or the API. Campaign membership becomes list entries that carry their own attributes. Lists go last because they reference records that must already exist. Emails are the exception: they do not migrate by any method and come back on their own when you connect Gmail or Calendar after cutover.
The order is the same whichever tool you use. Attio's own Import2 covers Accounts, Contacts, Leads and Opportunities but not Cases, which is one more reason Service Cloud orgs should read the verdict in section 01 before committing. For anything Import2 will not carry, including custom objects and the relationships between them, the move runs through the Attio API. That is the part most self-run migrations underestimate, and it is the core of our Attio implementation work.
Getting your data out of Salesforce cleanly
Use Salesforce's native Data Export (Setup, Data, Data Export) for a full, attachment-inclusive backup, and a Reports or Data Loader pull for the working files you will actually shape and import. Export the record IDs alongside the values: they are what let you rebuild relationships on the other side.
| Salesforce export | What it gives you | Watch for |
|---|---|---|
| Data Export (Setup) | Full weekly or one-off backup, all objects, attachments and notes included | This is your rollback copy. Archive it untouched before any change. Large orgs get a multi-file ZIP, not one CSV. |
| Reports / Data Loader | The working CSVs you clean and import, one per object | Always include the Salesforce 18-character ID and the lookup IDs (AccountId, OwnerId). Field labels alone will not reconnect records. |
| Picklist values | The exact option strings behind every picklist | Map them to Attio selects character for character. "$5m-$10m" and "$5m-10m" are different options to a machine and surface later as silent automation failures. |
| Owner and user list | The mapping from Salesforce user IDs to real people | Records without owners die quietly. Build the owner map before import, not after. |
| Activities and Campaign Members | History and membership, exported separately | These import as timeline entries and list entries, not as their own objects. Decide history depth in writing first: full history, or 24 months live plus an archive. |
One trap is specific to Salesforce: a record's identity lives in its IDs, not its names. Two accounts can share a company name, two contacts can share a full name, and the relationships between them are held by IDs you never see in the UI. Export those IDs and the import reconnects everything. Skip them and you are stitching records back together by hand after cutover, which is exactly the afternoon nobody budgeted for.
Four questions that settle it
If you can answer these four honestly, the decision usually makes itself. They are also the first four questions we ask in the diagnostic.
How much living Apex do you have?
Not lines of code: triggers and classes that fired last quarter and that someone on the team can still explain. Under a dozen, the rebuild is days of work. Dozens of load-bearing classes, price the rebuild before you commit to anything.
What do your seats actually do?
Relationship work and pipeline management migrate beautifully. High-volume case handling and call scripting do not. Count seats per motion, not seats in total, and let the majority motion pick the system.
Does quoting live inside your CRM?
If CPQ is your deal desk, Attio alone will not carry it and we will tell you so. If quotes are documents someone assembles anyway, PandaDoc plus Attio is leaner than the module you are paying for.
Where does reporting really happen?
If the honest answer is that people export to spreadsheets anyway, you lose nothing. If executives live inside Salesforce dashboards with years of snapshot history, budget a BI layer as part of the move, not as an afterthought.
The pre-migration checklist
The boring list that saves the project. Run all of it before anyone touches an import tool.
- Export everything first. Full data export including attachments, notes and activity history, archived before any change. Your rollback plan is a copy, not a hope.
- Audit field fill rates. Pull the percentage filled for every custom field. Anything under a few percent is almost always noise. Do not port noise into a clean workspace.
- Audit which reports are actually viewed. Last-viewed dates on every report and dashboard. Rebuild the survivors only.
- Deduplicate before the move, on identity. Leads and Contacts collapse into People, so the same person must become one record. Email matching alone is not enough: at a PE and M&A fund we had to resolve booking stubs from Calendly against enriched LinkedIn profiles where the same human carried different email addresses. Identity matching caught what email matching missed.
- Map every owner. Records without owners die quietly in any CRM. In that same fund build we left with 71 of 71 deals carrying a populated owner. Aim for nothing less.
- Refresh stale enrichment. Decide what enrichment data is too old to trust before you import it. We identified and flagged 953 stale profiles for re-enrichment as part of that engagement rather than carrying expired data into a new system.
- Decide history depth in writing. Every activity since the org was born, or 24 months live plus an archive? Either is fine. Deciding by accident is not.
- Map picklists to selects character for character. To a machine, "$5m-$10m" and "$5m-10m" are different options, and mismatches surface later as silent automation failures, not as errors.
- Inventory every integration hitting the Salesforce API. Marketing automation, enrichment, billing, the Zapier and Make scenarios nobody remembers building. Each one needs a flip plan to Attio's API or a retirement date.
- Plan the freeze window and the comms. A short, announced write freeze for the final delta import. Reps forgive a quiet afternoon. They do not forgive lost updates.
The migration, phase by phase
A clean Salesforce to Attio migration is five phases. The calendar realistically reads 3 to 6 weeks for a 5-to-50-seat org, longer when the Apex rebuild dominates the critical path.
Audit
The free diagnostic covers most of it: objects, fields, automations, integrations, reports people actually open, and the verdict on whether you should move at all. You keep the findings either way, including when the verdict is to stay.
Model design
Design the Attio workspace on your real motion, not as a replica of your Salesforce org. This is where record types become objects or lists, where dead fields stay dead, and where the model comes out simpler than the thing it replaces. It is the highest-leverage week of the whole project.
Dry run
Full import into a test workspace. Reconcile row counts per object, spot-check records per record type, fix the mapping, run it again. Nothing touches production until the dry run reconciles with zero surprises.
Cutover
Freeze writes, final delta import, integrations flipped to Attio, Salesforce switched to read-only. Discipline matters most here. In a lifecycle migration we ran for a B2B SaaS scale-up, 35,788 contacts were excluded from communications, 143 lifecycles corrected and 158 dead deals closed as Lost, with zero accidental wins and every write verified before and after. That is the standard a cutover deserves, whatever the platform.
Rebuild and run
The phase self-run migrations skip, and the reason they stall. Automations come back as workflows and API services, reporting comes back as views and dashboards. At the PE and M&A fund we run 24 Attio workflows in production: post-meeting extraction into structured records with an adversarial verification pass, cross-email deduplication, a rebuilt pipeline board, and native reporting with 9 views plus a 7-chart dashboard built through the API.
If you want the whole arc handled end to end, that is our core service: Attio implementation from 8,000 EUR for the setup, and from 3,500 EUR per month if you want us to run and extend the system after handover.
Three traps that ruin an otherwise clean import
Three failures account for most botched Salesforce to Attio migrations: importing into Attio's enriched fields, leaving email sync on during the import, and importing People before Companies. None of them throw an error. All of them are silent, which is what makes them dangerous. Here is how each one bites.
Importing into Attio's enriched attributes
Attio auto-enriches company and people data, employee count, founding year, revenue, job title, seniority, from domain and email alone. If you import your old Salesforce values into those fields, Attio treats them as manually entered and never overwrites them with fresh data. You inherit your stale data permanently and lose the enrichment you switched for. Leave those columns empty on import. On one fund engagement we deliberately identified and flagged the stale profiles for re-enrichment rather than carry expired data into the new system.
Leaving email sync on during the import
If your team's Gmail or Microsoft accounts are connected to Attio while you import, Attio auto-creates People and Company records from every incoming email, and you finish the migration with duplicates everywhere on top of the records you just imported. Disable email sync before the first import and re-enable it only after the data is validated. The history you are worried about losing comes back the moment you reconnect, because email is the one thing that backfills itself.
Importing People before Companies
Companies are the anchor. Import People first and Attio has nothing to link them to, so you get a workspace full of contacts floating free of their accounts and a manual relinking job at the end. Companies first, deduped on domain, then People carrying their company domain. The sequence in section 04 exists precisely to avoid this, and it is the single most common reason a self-run migration looks finished but reads broken.
Coming from HubSpot rather than Salesforce? The same three traps apply, but the object mapping and what breaks differ enough that we keep them separate: see the HubSpot to Attio migration playbook.
Salesforce to Attio, the questions we get
How long does a Salesforce to Attio migration take?
Can we keep our Salesforce history?
What happens to our Apex automations?
Does Attio replace Salesforce reports and dashboards?
What does a Salesforce to Attio migration cost?
Can we run Salesforce and Attio in parallel?
What tool do you use to migrate Salesforce to Attio?
What is the right order to import Salesforce data into Attio?
Find out which side of the verdict you are on
A free 30-minute diagnostic: we look at your Salesforce org, tell you honestly whether Attio is a fit, and what the move would cost. Text or voice memo, an answer within 24 hours.
Free 30-minute diagnostic