CRM migration
Field-level mapping, validation, and rollback between Opal CRM and Twenty CRM. We move data and schema; workflows are rebuilt natively in Twenty CRM.
Opal CRM
Source
Twenty CRM
Destination
Compatibility
6 of 10
objects map 1:1 between Opal CRM and Twenty CRM.
Complexity
BStandard
Timeline
3-5 weeks
Overview
Opal CRM organizes its data around field-sales workflows—leads tracked from capture through quotation with role-based permissions for Sales Reps, Managers, and Admins. Twenty CRM is an open-source, developer-friendly platform built with a modern GraphQL API, custom objects available from the free tier, and a transparent AGPL-3.0 codebase on GitHub with over 40,000 stars. The structural difference that defines this migration is Opal's lack of a documented public REST API or bulk export endpoint: data extraction relies on manual coordination with Opal support or direct database access, which we scope and validate before any data moves. We preserve the relationship between Sales Representatives and their assigned Leads, decompress Tour Plan expense line items into structured records, and map Opal's quotation workflow state to a custom field in Twenty. We do not migrate Workflows, Sequences, automations, or Reports as code; these require rebuild in Twenty by the customer's admin team.
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 Opal CRM 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.
Opal CRM
Lead
Twenty CRM
Person (standard object)
1:1Opal CRM Leads are the primary record for field-sales prospects captured from forms, campaigns, and manual entry. They map directly to Twenty's Person object, preserving contact fields (name, phone, email, address) and any source attribution. If Opal Lead records include point-based performance data (a feature in the Basic plan), we carry it to a custom number field in Twenty rather than discarding it.
Opal CRM
Sales Representative
Twenty CRM
WorkspaceMember (user provisioning)
1:1Opal CRM team members with roles (Sales Rep, Manager, Admin) migrate as Twenty Workspace Members. Role permissions in Opal (role-based access tiers) do not export as structured data, so we capture the role assignment per user and document the mapping so the customer's Twenty admin can configure equivalent access levels in Twenty's workspace settings during setup.
Opal CRM
Tour Plan
Twenty CRM
Custom Object (TourPlan) + related Task records
1:manyOpal CRM Tour Plans store itinerary data (dates, locations, assigned rep) plus expense line items. If Opal exports Tour Plans as a flat record, we decompress the expense entries from any available structured export and reconstruct them as individual TourPlanExpense records linked to the parent TourPlan. Twenty does not have a native Tour or Visit object, so we pre-create a custom object schema in Twenty via the Settings UI and the metadata API before migration.
Opal CRM
Quotation
Twenty CRM
Opportunity (with line items)
1:1Opal CRM Quotations are financial sales-closure records with line items and workflow approval state. They map to Twenty Opportunities, with Quotation header fields (total amount, status, dates) as Opportunity fields and line items as related OpportunityLineItem-equivalent records in Twenty's custom object structure. The approval workflow state from Opal is a platform-specific field with no direct Twenty equivalent; we preserve it as a custom picklist field workflow_state__c and document it in the handover notes.
Opal CRM
Pipeline Stage
Twenty CRM
Custom field on Person or Opportunity (stage name + order)
lossyOpal CRM tracks lead progress through pipeline stages tied to its lead engagement workflow. Stage names and order are preserved as a custom picklist field (pipeline_stage__c) on the migrated Person record, and the customer configures matching stage values in Twenty's pipeline view settings post-migration. We do not assume a fixed number of stages; we extract the actual stage set from the source data during discovery.
Opal CRM
Activity (Calls, Emails, Meetings)
Twenty CRM
Task records with activity type flag
1:1Opal CRM interaction logs (calls, emails, meetings) attached to Leads migrate as Twenty Task records with a custom activity_type__c field (call, email, meeting) and ActivityDate set to the original Opal timestamp. If the interaction has notes or a disposition, these land in the Task body and the customer configures Twenty's timeline view to surface the relevant fields per activity type.
Opal CRM
Custom Properties on Lead
Twenty CRM
Custom fields on Person
lossyOpal CRM supports custom fields on Leads, but the custom field schema is not publicly documented. We identify custom fields during discovery by inspecting the Opal export file, infer field types (text, number, date, picklist, checkbox), and pre-create matching custom fields in Twenty via the settings UI before migration. Any custom field that cannot be typed from the export lands as a text field with a flag for the admin to re-type post-migration.
Opal CRM
Lead Source Attribution
Twenty CRM
Custom field on Person (lead_source)
1:1Opal CRM captures leads from website forms, offline events, marketing campaigns, and manual entry. We preserve the source attribution as a custom lead_source__c field on the Person record so the customer's sales team can report on pipeline origin in Twenty without rebuilding the source-tracking logic.
Opal CRM
Performance Points / Rewards
Twenty CRM
Custom number fields on Person or WorkspaceMember
1:1Opal CRM's Basic plan includes sales performance tracking using a point/rewards system. This does not have a standard CRM equivalent in Twenty. We migrate any visible point totals or reward flags as custom number fields on the Person (for lead-level scores) or WorkspaceMember (for rep-level performance) and document the field in handover notes so the admin can configure reporting or remove it if the tracking model changes.
Opal CRM
Role Permissions (per-user)
Twenty CRM
WorkspaceMember access configuration
lossyOpal CRM role assignments (Admin, Manager, Sales Rep) are attached to team member records but do not export as structured permission data. We list every user's assigned role during discovery and produce a role-mapping table that the Twenty admin uses to configure workspace-level access in Twenty's member settings post-migration. We do not set permissions programmatically because Twenty's permission model operates at the workspace and object level rather than role-based groups.
| Opal CRM | Twenty CRM | Compatibility | |
|---|---|---|---|
| Lead | Person (standard object)1:1 | Fully supported | |
| Sales Representative | WorkspaceMember (user provisioning)1:1 | Fully supported | |
| Tour Plan | Custom Object (TourPlan) + related Task records1:many | Fully supported | |
| Quotation | Opportunity (with line items)1:1 | Fully supported | |
| Pipeline Stage | Custom field on Person or Opportunity (stage name + order)lossy | Fully supported | |
| Activity (Calls, Emails, Meetings) | Task records with activity type flag1:1 | Fully supported | |
| Custom Properties on Lead | Custom fields on Personlossy | Fully supported | |
| Lead Source Attribution | Custom field on Person (lead_source)1:1 | Fully supported | |
| Performance Points / Rewards | Custom number fields on Person or WorkspaceMember1:1 | Fully supported | |
| Role Permissions (per-user) | WorkspaceMember access configurationlossy | 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.
Opal CRM gotchas
No publicly documented API for bulk data export
Tour Plan expense data may flatten during export
Quotation workflow state is not a standard CRM field
Free tier limits and trial expiry not visible in export
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
Discovery and export feasibility assessment
We audit the source Opal CRM account across all tiers, identifying Lead records, Sales Representatives, Tour Plans, Quotations, and any custom field schemas visible in the export. Because Opal CRM has no public API, we coordinate a manual export file with the customer—typically CSV or a platform-generated backup—and validate record counts against the Opal UI before committing to the migration scope. This step also includes a Twenty environment review to confirm the target workspace is set up and the customer's admin has verified access.
Schema design in Twenty CRM
We design the destination schema in Twenty before any data loads. This includes creating the custom TourPlan and TourPlanExpense objects via Twenty's Settings UI and metadata API, adding custom fields (workflow_state__c on Opportunity, lead_source__c on Person, activity_type__c on Task, and performance/reward number fields), and configuring workspace member access based on the role-mapping table from discovery. Twenty's flexible data model means we build the schema to fit Opal's field-sales structure rather than forcing Opal data into a fixed Twenty template.
Export coordination and data extraction
We work with the customer to extract a full data export from Opal CRM. The export format depends on what Opal exposes at the time of engagement—typically CSV with one row per object type. We inspect the export for structural issues: flattened Tour Plan expense entries, quotation line items in a separate sheet, and custom field values that require type inference. Any issues are flagged and resolved with the customer before transformation begins.
Transformation and sandbox validation
We transform the Opal export into Twenty's API-compatible format: Person records from Leads with all fields mapped, Opportunities from Quotations with line items, custom TourPlan records with related expense child records, Tasks for activity history, and WorkspaceMember records for each Sales Representative. We run the full migration into Twenty's test environment first and reconcile record counts (Person count, Opportunity count, TourPlan count, Task count) against the source export before any production load.
Production migration in dependency order
We run production migration in record-dependency order: Workspace Members first (so owner resolution works), then Person records, then Opportunities with workflow_state__c preserved, then TourPlan custom records with expense children, then Tasks for activity history. Each phase emits a row-count reconciliation report. Any Opal export row that cannot be loaded (missing required field, malformed date) is logged to an exceptions sheet for the customer's admin to review and resolve before cutover.
Cutover, validation, and workflow handoff
We freeze Opal CRM writes during cutover, run a final delta migration of any records modified during the migration window, then designate Twenty as the system of record. We deliver a written inventory of Opal quotation workflow states, Tour Plan structures, and role assignments that the customer's admin uses to configure Twenty Automations and workspace permissions. We support a one-week hypercare window for reconciliation issues. We do not rebuild automations, approval workflows, or reporting as part of the migration scope; these are documented separately for the admin to configure in Twenty's no-code automation builder.
Platform deep dives
Opal CRM
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 Opal CRM 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
Opal CRM: Not publicly documented..
Data volume sensitivity
Opal CRM 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 Opal CRM to Twenty CRM migration scoping. Not seeing yours? Book a call.
Walk through your Opal CRM 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 Opal CRM
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.