CRM migration

Migrate from Odoo Field Service to Twenty CRM

Field-level mapping, validation, and rollback between Odoo Field Service and Twenty CRM. We move data and schema; workflows are rebuilt natively in Twenty CRM.

Odoo Field Service logo

Odoo Field Service

Source

Twenty CRM

Destination

Twenty CRM logo

Compatibility

92%

11 of 12

objects map 1:1 between Odoo Field Service and Twenty CRM.

Complexity

BStandard

Timeline

48–72 hours

Rollback included Accuracy guarantee Field-level validation

Overview

What this migration involves

Odoo Field Service runs on Odoo's unified res.partner model — contacts and companies live in the same table — and its field service module (fsm.order, fsm.location, fsm.worker, fsm.tag) is an OCA-maintained add-on layered on top of the CRM, Project, and Inventory apps. Twenty CRM uses a conventional CRM object model: People for contacts, Companies for accounts, and Opportunities for pipeline deals, with a native Tasks object for work items. The migration must split Odoo's res.partner into separate People and Company records in Twenty, map fsm.order records to a Twenty custom object (field_service_order) or Tasks depending on your operational model, and convert crm.lead stages into Twenty Opportunities stage values via a value-by-value pick-list map. FlitStack AI sequences the migration as: Companies first (because Twenty's People requires a companyId relation), then People (with their partner_id → companyId link resolved), then Opportunities (with crm.lead → Opportunity mapping and stage value mapping), then field service orders, then attachments and notes. Owner resolution happens by email match against Twenty workspace members. We do not migrate Odoo workflows, Odoo automation rules, or Odoo Studio custom views — those require a manual rebuild using Twenty's workflow builder or the REST/GraphQL API. The API ingestion path for large record sets uses Twenty's REST endpoints with pagination; bulk CSV import is used for validation batches.

Field-level fidelity

Every standard and custom field arrives verified.

Schema-aware mapping

AI proposes the map; you confirm before any record moves.

Relationships preserved

Parent–child, lookups, and ownership stay linked.

Full activity history

Calls, emails, meetings — with original timestamps.

Attachments & notes

Documents, uploads, and inline notes move with the record.

Why teams make this switch

Two sides of the same decision

Leaving

Odoo Field Service logo

Odoo Field Service

What's pushing teams away

  • High implementation cost: users report that per-user pricing plus partner consulting fees make Odoo FSM expensive relative to standalone FSM alternatives for teams under 20 users.
  • Steep learning curve: multiple reviews cite the broad feature set as overwhelming for new users, with onboarding requiring significant time investment before teams feel productive.
  • Bank reconciliation pain: uploading bank statements does not automatically match transactions to invoices, forcing manual review that frustrates accounting-focused users.
  • Mobile limitations in the field: users report difficulties accessing information on the mobile app in rural areas or with limited connectivity, directly undermining the field service use case.
  • Feature-rich but customization-heavy: power users note that achieving specific business workflows requires developer customization, which becomes technical debt during upgrades.

Choosing

Twenty CRM logo

Twenty CRM

What's pulling them in

  • Top open-source CRM on GitHub with 40.6K stars, giving teams full source code access and infrastructure ownership without per-feature licensing surprises.
  • Free self-hosting under AGPL-3.0 means unlimited users and custom objects for the cost of cloud infrastructure alone, typically $20–100/month.
  • Pricing page explicitly mocks competitors for charging add-on fees for API access, webhooks, and workflows — transparency that resonates with RevOps teams burned by Salesforce.
  • Unlimited custom objects and fields with no price impact, letting teams shape the data model to their business rather than forcing business into rigid schemas.
  • Modern TypeScript/React/PostgreSQL stack means developer-led teams can extend, self-host, or integrate without fighting legacy architecture.

Object mapping

How Odoo Field Service objects map to Twenty CRM

Each row shows how a Odoo Field Service 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.

Odoo Field Service

res.partner (type=contact)

maps to

Twenty CRM

People

1:1
Fully supported

Odoo's res.partner with partner_type='contact' maps directly to Twenty People. The email, phone, address, and job_title fields migrate as standard Twenty People fields. The res.partner.id is preserved as source_system_id__c for delta-run deduplication. This mapping requires the Company records (res.partner type=company) to exist in Twenty first so the companyId relation can resolve.

Odoo Field Service

res.partner (type=company)

maps to

Twenty CRM

Companies

1:1
Fully supported

Odoo's res.partner with partner_type='company' maps to Twenty Companies. Company name, website, street/city/state/country fields migrate directly. The Odoo parent_id hierarchy (parent/child company relationships) is preserved by mapping parent_id to Twenty's companyId self-relation field. Multi-company Odoo setups map to separate Twenty workspace Companies records.

Odoo Field Service

crm.lead (stage: new / qualified / proposition)

maps to

Twenty CRM

Opportunities

1:1
Fully supported

Odoo's crm.lead for active pipeline stages (new, qualified, proposition) maps to Twenty Opportunities. The expected_revenue field migrates to amount (currency field). Odoo's crm.stage names (new, qualified, etc.) are mapped via a value map to Twenty's opportunity stageName options. The lead's partner_id is resolved to the People record already migrated.

Odoo Field Service

crm.lead (stage: won / lost)

maps to

Twenty CRM

Opportunities (closed)

1:1
Fully supported

Won and lost crm.lead records migrate to Twenty Opportunities with stageName set to the corresponding closed stage. Odoo's won/lost stage probability values are mapped value-by-value. Lost reasons stored in Odoo's lost_reason_id field migrate as a custom text field (lost_reason__c) for audit continuity.

Odoo Field Service

fsm.order

maps to

Twenty CRM

field_service_order (custom object)

1:1
Fully supported

Odoo fsm.order has no native equivalent in Twenty. We create a custom object called 'field_service_order' in Twenty's data model with custom fields for: stage (fsm.stage.name), location_address (fsm.location.partner_id display name + street), scheduled_date (scheduled_date_start), assigned_worker (assigned_to user email match), and tags. The fsm.order.id is stored as source_system_id__c.

Odoo Field Service

fsm.location

maps to

Twenty CRM

Companies

many:1
Fully supported

Odoo fsm.location records (service site addresses) are merged into the Twenty Companies object. The location name + address fields populate the Company name and address fields. If the location has a related partner_id (customer), we link it to that Company record. Locations without a customer link create standalone Company records in Twenty.

Odoo Field Service

project.task (from Project app linked to fsm)

maps to

Twenty CRM

Tasks

1:1
Fully supported

Odoo Project tasks linked to fsm.order migrate as Twenty Tasks. The task name, description, planned_date_begin/end, user_id (owner), and stage_id (stage name) map directly. Tasks linked to a fsm.order carry the source fsm.order ID in a custom field (source_fsm_order_id__c) for traceability back to the field service order.

Odoo Field Service

ir.attachment

maps to

Twenty CRM

Notes / file import

1:1
Fully supported

Odoo file attachments (ir.attachment records linked to res.partner, crm.lead, or fsm.order) are downloaded and re-imported to Twenty. Files attached to People or Companies become Twenty Notes with the attachment content. Large binary files (e.g., signed PDFs from fsm.order worksheets) are stored with a URL reference to the destination storage.

Odoo Field Service

res.users (salesperson / field worker)

maps to

Twenty CRM

WorkspaceMember (Twenty users)

1:1
Fully supported

Odoo res.users records with active CRM or Field Service access are matched to Twenty workspace members by email address. Unmatched Odoo users (e.g., inactive technicians no longer in the system) are flagged and assigned to a fallback owner. The match is used to resolve owner_id on crm.lead and user_id on fsm.order during migration.

Odoo Field Service

res.partner.bank

maps to

Twenty CRM

Custom field on Companies

1:1
Fully supported

Odoo bank details on res.partner (res.partner.bank records) have no native equivalent in Twenty's Company object. They are migrated as a custom multi-text field (bank_details__c) containing the account number, bank name, and IBAN as a formatted string. This is a reference-only preservation — payment processing is handled outside Twenty CRM.

Odoo Field Service

crm.lead / res.partner custom fields (x_*, ir.model.fields)

maps to

Twenty CRM

Custom fields on People / Opportunities

1:1
Fully supported

Any Odoo custom fields added via Odoo Studio or ir.model.fields on crm.lead or res.partner are migrated as Twenty custom fields on People or Opportunities. The field type is inferred from Odoo's field ttype (char→text, integer→number, many2one→relation, selection→select). Fields with no equivalent in Twenty become custom text fields for reference.

Odoo Field Service

fsm.tag

maps to

Twenty CRM

Custom multi-select field on field_service_order

1:1
Fully supported

Odoo fsm.tag records (name, color) migrate as a multi-select custom field (service_tags__c) on the field_service_order custom object. Tag names are preserved as options; tag colors are not migratable since Twenty multi-select fields use plain text values. Tags are de-duplicated (same name = one option).

Gotchas + challenges

What specifically takes care here

Platform-specific issues from each side, plus the pair-specific challenges that don't show up on either platform's page on its own.

Odoo Field Service logo

Odoo Field Service gotchas

High

Database version upgrade is not a direct restore

Medium

Custom fields use x_ column naming that can collide

Medium

ir.attachment binaries can exceed API upload limits

Low

Chatter messages use HTML that requires sanitization

Twenty CRM logo

Twenty CRM gotchas

High

Import order is enforced and critical

High

Export limited to 20,000 records and visible columns only

Medium

Soft-deleted records count toward uniqueness and trigger restores

Medium

API rate limits cap at 200 req/min on Organization tier

Low

No native email sequences — follow-up cadences require external tools

Pair-specific challenges

  • Field service orders have no native destination object — custom object creation is mandatory

    Odoo fsm.order records track field service work items with their own stage model, assigned workers, locations, and scheduled times. Twenty CRM has no native field service module — fsm.order data must be stored in a custom object (field_service_order) that your Twenty admin creates before data lands. If the custom object is not pre-created in Twenty's data model, the migration pipeline will error on the fsm.order records. FlitStack AI includes a custom-object setup guide in the migration plan so your Twenty workspace is schema-ready before the data loads. This is a pre-flight requirement, not a post-migration cleanup item.

  • Odoo's res.partner model splits into two Twenty objects — N:N associations collapse

    Odoo stores contacts and companies in a single res.partner table with a type field distinguishing them. A single res.partner record can simultaneously serve as a company (with child contact records) and carry contact-level fields. Twenty separates People and Companies into distinct objects. FlitStack AI splits Odoo's res.partner into two migration paths: company-type records go to Twenty Companies, contact-type records go to Twenty People with their parent_id mapped to companyId. The Odoo N:N partner-category tags migrate as Twenty tags on People. Any Odoo contact that is also a company (type=company AND has address_ids) requires manual disambiguation — your migration plan flags these records for review before the migration commits.

  • Owner resolution by email match fails for inactive Odoo users

    Twenty CRM workspace members must exist before FlitStack AI can assign an owner to migrated records. Odoo user accounts for inactive employees, departed technicians, and portal-only users do not have Twenty workspace accounts and cannot be auto-matched. Unmatched owner IDs on crm.lead and fsm.order records are flagged in the pre-migration audit report. If left unresolved, those records land in Twenty without an owner and appear in the 'Unassigned' view. Your team must either create placeholder Twenty users for these individuals or assign records to a fallback owner — the migration plan surfaces this decision before cutover.

  • Odoo workflows, automation rules, and server actions do not migrate to Twenty

    Odoo Field Service frequently uses automated actions (ir.filters, mail.activity.type rules, base.action.rule records) to generate fsm.order from sale orders or to stage crm.lead based on email responses. Twenty CRM's automation model uses a workflow builder with triggers on record creation or field changes. There is no import path for Odoo automation XML — the logic must be manually rebuilt in Twenty's workflow builder or via the REST API. FlitStack AI exports a structured JSON representation of your Odoo automation rules as a rebuild reference document for your Twenty admin. This is disclosed upfront in every Odoo-to-Twenty migration scope.

  • Twenty free and Pro tiers have per-minute API rate limits that affect large bulk migrations

    Twenty Cloud Pro caps API calls at 200 per minute. Odoo instances with large data volumes (50,000+ res.partner records, 20,000+ fsm.order) exceed this rate if pushed via direct REST calls without throttling. FlitStack AI implements batched API writes with exponential back-off on 429 responses, and falls back to Twenty's CSV import endpoint for records that exceed the API throughput ceiling. The migration plan specifies whether your data volume requires API-mode or CSV-import-mode migration before the first test run.

Migration approach

Six steps for a successful Odoo Field Service to Twenty CRM data migration

  1. Discover Odoo data model and plan Twenty schema

    FlitStack AI connects to your Odoo instance via XML-RPC or the Odoo REST API (external API module) and inventories all res.partner records, crm.lead records, fsm.order records, and any custom fields registered in ir.model.fields. We simultaneously review your Twenty workspace and create a custom object (field_service_order) with all required custom fields identified in the Odoo audit. The plan names every custom field to be added, every stage value to be configured, and every user email to be matched. No data moves until the schema is confirmed ready.

  2. Export and deduplicate Odoo data

    We export all Odoo records in the dependency order required by Twenty's relation model: Companies first (res.partner type=company), then People (res.partner type=contact with companyId links resolved), then Opportunities (crm.lead with personId links resolved), then field service orders (fsm.order with customer and worker links resolved), then attachments. During export we run deduplication on res.partner using email as the primary key — duplicate email addresses are surfaced with their Odoo IDs for your team to decide which record to keep before migration commits.

  3. Resolve owners and users by email

    Every Odoo user_id and fsm.worker_user_id is matched against Twenty workspace member email addresses. The match produces a cross-reference table (odoo_user_id → twenty_user_id) that drives owner assignment during the write phase. Records with unmatched owners are listed in the audit report with the option to create placeholder Twenty users or assign to a fallback. No record lands in Twenty without a resolved owner unless your team explicitly approves the unassigned record count.

  4. Run test migration with field-level diff

    A representative slice of 100–500 records spanning People, Companies, Opportunities, and fsm.order migrates first. We generate a field-level diff comparing the Odoo source values against the Twenty destination values for every mapped field. You review the diff to confirm stage value mapping, owner assignment, companyId linkage, and custom field content. Approval of the test diff is required before the full migration run. Any mapping adjustments are applied before the full run.

  5. Execute full migration with delta pickup and audit log

    The full record set migrates against your Twenty workspace using the validated field mappings. A delta-pickup window (typically 24–48 hours) runs in parallel, capturing any Odoo records modified or created during the cutover window so Twenty reflects Odoo's final state at go-live. Every migration operation is logged to an audit table in FlitStack AI's system. If reconciliation reveals a discrepancy (record count mismatch, missing relation), one-click rollback reverts the Twenty workspace to its pre-migration state. Post-migration, we deliver a data integrity report showing record counts, error counts, and owner resolution rates per object.

Platform deep dives

Context on both ends of the pair

Odoo Field Service logo

Odoo Field Service

Source

Strengths

  • All-in-one ERP integration: FSM tasks automatically link to Sales orders, Invoices, and Inventory without manual re-entry.
  • Multiple planning views: Kanban, Gantt, Calendar, and Map give dispatchers flexibility to plan by workflow, timeline, time slot, or geography.
  • Mobile app for field technicians: covers end-to-end task completion including worksheet filling, parts recording, and signature capture.
  • Free tier available: Odoo Online One App Free plan lets small teams evaluate FSM before committing to a paid subscription.
  • Open-source community: OCA maintains field-service-maintenance and other FSM extensions that extend functionality beyond the core module.

Weaknesses

  • Per-user pricing scales directly: every technician, dispatcher, and admin adds to the monthly bill, making it expensive for large field teams.
  • Bank reconciliation is manual: the accounting module does not auto-match bank statements to invoices, requiring accounting staff to review mismatches manually.
  • iOS navigation bug: clicking Navigate to on task locations fails on iOS devices, breaking route planning in the field for Apple users.
  • Upgrade path requires OpenUpgrade: Odoo database upgrades between versions are not simple restores; community users must use OCA/OpenUpgrade scripts or migrate one version at a time.
  • Limited standalone FSM branding: the module is positioned as one app within the Odoo suite rather than a dedicated FSM product, making it harder to evaluate in isolation.
Twenty CRM logo

Twenty CRM

Destination

Strengths

  • AGPL-3.0 open-source license with full source code on GitHub — no vendor lock-in, no sunset risk.
  • Unlimited users and unlimited custom objects on self-hosted, with no feature gating based on headcount.
  • REST and GraphQL APIs available on all paid tiers, not locked behind an enterprise add-on fee.
  • MCP server and webhooks shipped as standard features, not premium upgrades.
  • Modern PostgreSQL-backed data model that developer teams can query, extend, and self-host.

Weaknesses

  • Recent v1.0 release means limited production hardening compared to CRMs with multi-year operational track records.
  • No native email sequencing or sales engagement tools — follow-up cadences require a separate platform.
  • No native two-way email sync or inbox integration, requiring third-party connectors for full activity logging.
  • Self-hosting 'free' pricing hides real infrastructure and DevOps costs that stack up over time.
  • Workflow automation is functional but lacks the complexity needed for sophisticated multi-step sales motions.

Complexity grading

How hard is this migration?

Standard CRM migration. 1 of 8 objects need a mapping; the rest are 1:1.

B

Overall complexity

Standard migration

Derived from compatibility, mapping clarity, API constraints, and data volume across Odoo Field Service and Twenty CRM.

  • Object compatibility

    B

    1 of 8 objects need a mapping; the rest are 1:1.

  • Field mapping clarity

    C

    Field mapping is derived from defaults — final spec confirmed during the sample migration.

  • Timeline complexity

    B

    8-object category — typical timelines run 2–7 days end-to-end.

  • API constraints

    B

    Odoo Field Service: Not publicly documented; Odoo documentation notes timeout thresholds for large exports and imports that effectively cap batch size.

  • Data volume sensitivity

    B

    Odoo Field Service doesn't expose a bulk API — REST + parallelization used for high-volume runs.

Estimator

Estimate your Odoo Field Service to Twenty CRM migration cost

Rule-based pricing — no per-record fees, no manual quotes. Migrations over 2M records are scoped individually.

Step 1

What are you migrating?

Pick a category, then your source and destination platforms.

Category

FAQ

Frequently asked questions about Odoo Field Service to Twenty CRM data migrations

Answers to the questions buyers ask most during Odoo Field Service to Twenty CRM migration scoping. Not seeing yours? Book a call.

Can't find your answer?

Walk through your Odoo Field Service to Twenty CRM migration with a real engineer — 30 minutes, free, written quote within 24 hours.

Book a free 30 minute consultation

Most Odoo Field Service to Twenty CRM migrations complete in 48–72 hours of clock time for datasets under 25,000 records. The longest phase is planning the fsm.order to custom object mapping and setting up the custom object schema in Twenty — that typically takes 2–3 days before any data moves. For datasets over 100,000 records or Odoo instances with heavy custom field usage on both crm.lead and res.partner, allow 7–12 days including the test migration, deduplication review, and owner-resolution sign-off.

Adjacent paths

Related migrations to explore

Ready when you are

Move from Odoo Field Service.
Land in Twenty CRM, intact.

Tell us record counts and timeline. We'll come back with a written quote inside 1 business day — no commitment, no sales pitch.

Accuracy guarantee Rollback included Quote in 1 business day