CRM migration
Field-level mapping, validation, and rollback between Function 365 and Twenty CRM. We move data and schema; workflows are rebuilt natively in Twenty CRM.
Function 365
Source
Twenty CRM
Destination
Compatibility
12 of 14
objects map 1:1 between Function 365 and Twenty CRM.
Complexity
BStandard
Timeline
48–72 hours of clock time
Overview
Function 365 runs on a Dynamics 365 data model: Account, Contact, Lead, Opportunity, and Task objects with standard Dynamics field names and custom fields managed through the Xrm toolbox or Power Apps maker portal. Twenty CRM uses a simpler object graph — People (unifying contacts and leads), Companies (accounts), Opportunities (deals), Notes, and Tasks — with field types that include Text, Select, Multi-Select, Relation, Currency, Date, and Number. The migration carries everything Function 365 stores natively into Twenty's schema. The structural difference is Dynamics 365's separate Lead and Contact objects collapsing into Twenty's single People object, Dynamics owner-resolution by GUID becoming Twenty's user lookup by email, and Dynamics 365 business rules and Power Automate flows having no Twenty equivalent and requiring manual rebuild using Twenty's workflow builder. We sequence the migration: export Function 365 data via the Dynamics Web API or KingswaySoft CSV export, transform field names and pick-list values, create Twenty custom fields for Dynamics custom attributes, then import in dependency order (Companies first, then People, then Opportunities, then Notes and Tasks). A delta-pickup window captures in-flight changes during cutover.
Every standard and custom field arrives verified.
AI proposes the map; you confirm before any record moves.
Parent–child, lookups, and ownership stay linked.
Calls, emails, meetings — with original timestamps.
Documents, uploads, and inline notes move with the record.
Why teams make this switch
Leaving
What's pushing teams away
Choosing
What's pulling them in
Object mapping
Each row shows how a Function 365 object lands in Twenty CRM, including any object-level transformations, lookup resolution, or schema-design dependencies.
Typical mapping — final map is confirmed during the sample migration step.
Function 365
Account
Twenty CRM
Company
1:1Function 365 Account maps directly to Twenty CRM Company. The Account.Name becomes Company.name (text). Account.website maps to Company.domainUrl. Account.industry maps to a Twenty Select-type Industry field if configured. Parent account hierarchies (Account.ParentAccountId) map to a self-referential Company relation in Twenty. Multi-address accounts (Address fields) are consolidated into Twenty's primary address fields.
Function 365
Contact
Twenty CRM
People
1:1Function 365 Contact maps to Twenty CRM People as a primary mapping. Contact.firstname → People.firstName, Contact.lastname → People.lastName, Contact.emailaddress1 → People.email, Contact.mobilephone → People.phone (or a custom phone field if multiple phone types exist). The Contact's parent CustomerId (Account lookup) maps to the People.company relation by email-domain matching or explicit Account.Name lookup.
Function 365
Lead
Twenty CRM
People
many:1Function 365 Lead and Contact both map into Twenty CRM People. The distinction is preserved via a People.type field (set to 'Lead' or 'Contact' during import) and a status flag. If your Function 365 has closed/won leads that represent existing customers, those records receive a 'Converted Lead' tag in Twenty so your sales team can filter them separately without losing history.
Function 365
Opportunity
Twenty CRM
Opportunity
1:1Function 365 Opportunity maps to Twenty CRM Opportunity with minimal transformation. Opportunity.name → Opportunity.name, Opportunity.estimatedvalue → Opportunity.amount (Currency type), Opportunity.closeprobability → Opportunity.probability (Number 0–100), Opportunity.estimatedclosedate → Opportunity.closeDate. The Dynamics StageCode (option set) maps to a Twenty Select-type Stage field value-by-value.
Function 365
Lead (lead_to_opportunity_process)
Twenty CRM
Opportunity
1:manyFunction 365 Lead records that have been converted into Opportunities retain both the original LeadId and the new OpportunityId. We map the converted Opportunity to Twenty Opportunity directly. The original Lead fields (lead quality score, source campaign) are preserved as custom fields on the Twenty Opportunity record so closed-loop reporting remains intact.
Function 365
Task
Twenty CRM
Task
1:1Function 365 Task (activity) maps to Twenty CRM Task. Task.subject → Task.title, Task.scheduledend → Task.dueDate, Task.statuscode → Task.status, Task.ownerid → Task.assignee (resolved by email to a Twenty Workspace Member). Task regarding fields (RegardingObjectId pointing to Account, Contact, or Opportunity) map to the Task's relation field in Twenty.
Function 365
Email (EmailSendPointer / EmailHash)
Twenty CRM
Task
1:1Function 365 email activities are stored as EmailSendPointer records with body text in EmailRouterMailboxTrackingPolicy-linked tables. We extract the subject, body text, sender, recipients, and sent-on timestamp and represent each email as a Twenty Task with Type='Email', subject from the email subject line, and the original timestamp preserved. Email threading is not maintained as a native feature in Twenty but can be reconstructed from a related-email custom field.
Function 365
PhoneCall
Twenty CRM
Task
1:1Function 365 PhoneCall activity maps to Twenty Task with Type='Call'. Subject is built from the CallDirection (Incoming/Outgoing) and the regarding record name. Duration (PhoneCall.duration) is stored as a custom Number field (CallDurationMinutes__c) since Twenty's native Task does not include duration.
Function 365
Appointment
Twenty CRM
Task
1:1Function 365 Appointment maps to Twenty Task with Type='Meeting'. Subject, scheduledstart, scheduledend, and location are mapped to the corresponding Twenty Task fields. The Appointment's requiredattendees (PartyList of Contact/Lead records) are stored as a custom Multi-Select relation field on the Twenty Task since Twenty does not have native attendee tracking.
Function 365
Annotation (Note / Attachment)
Twenty CRM
Note
1:1Function 365 Annotation (notes and file attachments) maps to Twenty CRM Notes attached to People, Companies, or Opportunities by the RegardingObjectId reference. The note text maps to Note.body; the createdon timestamp and notetext (if a string field) maps to a custom datetime field. File attachments are downloaded from Dynamics SharePoint/Note locations and re-uploaded to Twenty's file storage.
Function 365
Custom Entity (Dynamics custom table)
Twenty CRM
Custom Object
1:1Function 365 custom entities (tables created via Power Apps maker or Xrm tooling) map to Twenty CRM Custom Objects. We create the matching Twenty custom object in Settings → Data Model before import, then map each custom entity attribute to the corresponding Twenty field. Custom entity relationships (many-to-many via intersect tables) map to Twenty relation fields.
Function 365
Connection (AccountCustomerContacts / ContactCustomerAccounts)
Twenty CRM
People → Company relation
1:1Function 365's N:N contact-to-account relationship via Connection or the inverse CustomerAddress role is flattened into Twenty's People.company relation (a single relation per person). The most recently modified or primary company per contact is designated as the Twenty relation; any additional companies are stored in a custom Multi-Relation field.
Function 365
SalesOrder / Invoice
Twenty CRM
Custom Object
1:1Function 365 SalesOrder and Invoice entities have no direct Twenty CRM equivalent. We preserve them as a custom object (e.g., Orders) with fields for order number, amount, status, date, and related Opportunity. Order line items are stored as a custom relation sub-object. This gives you a reference record even though Twenty does not natively support order management.
Function 365
SystemUser
Twenty CRM
WorkspaceMember
1:1Function 365 SystemUser records map to Twenty Workspace Members. Resolution is by email address: each SystemUser.internalemailaddress is matched to a Twenty user account. Unmatched SystemUser records are flagged before migration so your team can either invite them to Twenty first or assign their records to a fallback user. User business unit hierarchies do not translate to Twenty's flat permission model.
| Function 365 | Twenty CRM | Compatibility | |
|---|---|---|---|
| Account | Company1:1 | Fully supported | |
| Contact | People1:1 | Fully supported | |
| Lead | Peoplemany:1 | Fully supported | |
| Opportunity | Opportunity1:1 | Fully supported | |
| Lead (lead_to_opportunity_process) | Opportunity1:many | Fully supported | |
| Task | Task1:1 | Fully supported | |
| Email (EmailSendPointer / EmailHash) | Task1:1 | Fully supported | |
| PhoneCall | Task1:1 | Fully supported | |
| Appointment | Task1:1 | Fully supported | |
| Annotation (Note / Attachment) | Note1:1 | Fully supported | |
| Custom Entity (Dynamics custom table) | Custom Object1:1 | Fully supported | |
| Connection (AccountCustomerContacts / ContactCustomerAccounts) | People → Company relation1:1 | Fully supported | |
| SalesOrder / Invoice | Custom Object1:1 | Fully supported | |
| SystemUser | WorkspaceMember1:1 | Fully supported |
Gotchas + challenges
Platform-specific issues from each side, plus the pair-specific challenges that don't show up on either platform's page on its own.
Function 365 gotchas
AI-assisted notes are proprietary — verify clinical-record export coverage
NHS Number format must be preserved exactly
Implementation specialist time is paid extra at £55/session
GDPR consent timestamps are regulatory artefacts
Twenty CRM gotchas
Import order is enforced and critical
Export limited to 20,000 records and visible columns only
Soft-deleted records count toward uniqueness and trigger restores
API rate limits cap at 200 req/min on Organization tier
No native email sequences — follow-up cadences require external tools
Pair-specific challenges
Migration approach
Audit and export Function 365 data via Dynamics Web API or KingswaySoft CSV export
FlitStack connects to your Function 365 instance via the Dynamics 365 Web API (OAuth 2.0 with an app registration) or uses KingswaySoft SSIS to extract Account, Contact, Lead, Opportunity, Task, Annotation, and custom entity records. We run a pre-export data quality scan identifying duplicate records, missing required fields (e.g., Contact with no email or lastname), and inactive users whose records should be filtered. The output is a structured CSV file per entity with GUIDs preserved as source_system_id for traceability.
Build Twenty CRM Data Model — create custom fields and objects before import
We generate a Data Model setup plan listing every custom field from Function 365 that has no direct Twenty equivalent, the field type to create (Select, Multi-Select, Number, Date, Relation), and option values for pick-list fields. Your Twenty admin (or FlitStack on your behalf) creates these fields in Settings → Data Model before data is imported. Custom objects for Function 365 entities with no standard Twenty equivalent (e.g., Orders, Contracts) are created at this stage. Workspace Members matching your Dynamics SystemUsers are invited and confirmed active before step 3.
Transform and sequence the CSV files for dependency-order import
FlitStack transforms every exported CSV: Dynamics field names mapped to Twenty field names, Dynamics option set integer values mapped to Twenty Select labels, Dynamics OwnerId GUIDs resolved to Twenty Workspace Member IDs by email match, and Dynamics date formats (UTC ISO 8601) accepted natively by Twenty. The files are sequenced: Companies first (dependency anchor), then People (referencing Companies by name or domain), then Opportunities (referencing Companies and People), then Notes and Tasks (referencing all parent objects). Any record with an unresolvable owner or missing required field is flagged in a separate exceptions file for your team to clean before the full run.
Run a sample migration with field-level diff against a representative slice
A representative slice (typically 200–500 records spanning all entity types, including a few with custom fields) is imported into Twenty first. FlitStack generates a field-level diff report comparing source Dynamics values against the imported Twenty values for every mapped field. You verify that pick-list mappings, owner resolution, company-people associations, and amount/currency fields all landed correctly. Any mapping errors are corrected in the transformation logic before the full run is scheduled. This sample is your last chance to adjust field mapping without touching production data.
Execute full migration with delta-pickup window for in-flight records
The full CSV import runs against your Twenty instance with FlitStack monitoring for duplicate-key errors, validation failures, and import rate throttling. Once the initial load completes, a delta-pickup window (typically 24–48 hours) captures any records created or modified in Function 365 during the cutover window. FlitStack produces an audit log of every operation (insert, update, skip) and a reconciliation summary comparing record counts by entity between the source and destination. One-click rollback is available if reconciliation identifies missing records or incorrect associations.
Deliver workflow inventory export and post-migration support checklist
FlitStack exports your Function 365 workflow definitions (Power Automate flow JSON, classic Workflow XAML) and business rule configurations as a structured reference document for your Twenty admin. The deliverable includes a rebuild priority list (critical workflows first, then nice-to-have), a screen-by-screen mapping of Dynamics entities to Twenty objects, and a post-migration validation checklist covering record counts, custom field completeness, owner resolution rate, and note attachment verification. We schedule a 30-day follow-up call to address any data issues discovered after users begin working in Twenty.
Platform deep dives
Function 365
Source
Strengths
Weaknesses
Twenty CRM
Destination
Strengths
Weaknesses
Complexity grading
Standard CRM migration. 1 of 8 objects need a mapping; the rest are 1:1.
Overall complexity
Standard migration
Derived from compatibility, mapping clarity, API constraints, and data volume across Function 365 and Twenty CRM.
Object compatibility
1 of 8 objects need a mapping; the rest are 1:1.
Field mapping clarity
Field mapping is derived from defaults — final spec confirmed during the sample migration.
Timeline complexity
8-object category — typical timelines run 2–7 days end-to-end.
API constraints
Function 365: Not publicly documented.
Data volume sensitivity
Function 365 doesn't expose a bulk API — REST + parallelization used for high-volume runs.
Estimator
Rule-based pricing — no per-record fees, no manual quotes. Migrations over 2M records are scoped individually.
Step 1
Pick a category, then your source and destination platforms.
Category
FAQ
Answers to the questions buyers ask most during Function 365 to Twenty CRM migration scoping. Not seeing yours? Book a call.
Walk through your Function 365 to Twenty CRM migration with a real engineer — 30 minutes, free, written quote within 24 hours.
Book a free 30 minute consultationAdjacent paths
Other ways to leave Function 365
Other ways to arrive at Twenty CRM
Ready when you are
Tell us record counts and timeline. We'll come back with a written quote inside 1 business day — no commitment, no sales pitch.