CRM migration

Migrate from Firmao CRM to Odoo CRM

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

Firmao CRM logo

Firmao CRM

Source

Odoo CRM

Destination

Odoo CRM logo

Compatibility

75%

9 of 12

objects map 1:1 between Firmao CRM and Odoo CRM.

Complexity

BStandard

Timeline

2-4 weeks

Rollback included Accuracy guarantee Field-level validation

Overview

What this migration involves

Moving from Firmao CRM to Odoo CRM is a structural migration across API architectures. Firmao exposes a flat JSON REST API with per-endpoint GET and POST operations and no bulk endpoint, while Odoo uses XML-RPC with distinct model names (res.partner, crm.lead, project.task, product.product) and per-method batch limits of 5,000 records per call. The core migration work involves mapping Firmao's Companies and Contacts to Odoo's res.partner (distinguished by company_type), mapping Deals to crm.lead with stage names reconciled against the Odoo pipeline, resolving Firmao's dot-notation custom fields (customFields.customN) into Odoo custom field definitions before data import, and handling the subClass=warehouse envelope in Products by extracting each warehouse variant as a separate stock.location in Odoo. We do not migrate automations, workflows, or Forms as code; we deliver a written inventory of every active automation for the customer's Odoo admin to rebuild. Historical timestamps and owner assignments (via email-to-user resolution) are preserved throughout.

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

Firmao CRM logo

Firmao CRM

What's pushing teams away

  • Customization requires technical knowledge — configuring the system to fit unique business workflows is cited as a barrier for non-technical administrators.
  • Basic tier feels feature-limited; users report needing to upgrade to Professional or Enterprise to access custom fields, deal tracking, and Gantt/Kanban diagrams.
  • No publicly documented rate limits means migration tooling must handle undocumented throttling conservatively, which can slow large data transfers.
  • The platform's heavy ERP-adjacent feature set creates complexity for teams that only need a straightforward CRM, leading to feature-overload frustration.

Choosing

Odoo CRM logo

Odoo CRM

What's pulling them in

  • Teams choose Odoo CRM for its modular architecture — one base install with one-click app additions means they can adopt CRM alone and add accounting, inventory, or sales later as the business grows.
  • Small businesses pick Odoo because the Community edition is free and open-source, with no per-user or contact limits, allowing full evaluation before committing to a paid Enterprise tier.
  • The drag-and-drop Kanban pipeline and AI lead scoring are highlighted across G2 reviews as concrete features that make lead management faster and more visual than spreadsheet-based workflows.
  • Odoo's native integration with email, live chat, SMS, VoIP, and WhatsApp means inbound leads from multiple channels feed into a single pipeline without third-party middleware.
  • Companies in retail, supply chain, and construction value that Odoo's CRM module shares the same PostgreSQL database and UI as its ERP modules, eliminating data silos between sales and operations.

Object mapping

How Firmao CRM objects map to Odoo CRM

Each row shows how a Firmao CRM object lands in Odoo CRM, including any object-level transformations, lookup resolution, or schema-design dependencies.

Typical mapping — final map is confirmed during the sample migration step.

Firmao CRM

Contact

maps to

Odoo CRM

res.partner

1:1
Fully supported

Firmao Contact records (GET /svc/v1/contact) map to Odoo res.partner with company_type='contact'. We extract name, email, phone, address fields (street, city, postal_code, country) and resolve the parent company via companyName matching against Firmao Company records before inserting into Odoo, populating the parent_id lookup. Custom contact fields (customFields.customN) are mapped after the Odoo custom field definition is created during schema setup. Owner assignment is resolved via email matching against Odoo res.users.

Firmao CRM

Company

maps to

Odoo CRM

res.partner (company_type='company')

1:1
Fully supported

Firmao Company records (GET /svc/v1/company) map to Odoo res.partner with company_type='company'. The company name becomes partner name, and address components (street, city, postal_code, country) are split into Odoo address fields. Company records are imported before Contacts so that parent_id lookups resolve at Contact insert time. Custom company fields follow the same dot-notation extraction and Odoo custom field pre-creation pattern as Contacts.

Firmao CRM

Deal

maps to

Odoo CRM

crm.lead

1:1
Fully supported

Firmao Deals (GET /svc/v1/deal, available on Professional and above) map to Odoo crm.lead. We verify the customer's Firmao tier during scoping before attempting Deal extraction; accounts on Standard tier have no Deals to migrate. Deal name maps to crm.lead name, dealstage maps to stage_id (resolved via crm.stage name matching), and dealValue maps to planned_revenue. Owner is resolved by email. The Firmao subClass/subId envelope for deal-to-task associations is handled via a note on the crm.lead record until the Tasks phase inserts project.task records.

Firmao CRM

Task

maps to

Odoo CRM

project.task

1:1
Fully supported

Firmao Tasks (GET /svc/v1/task) map to Odoo project.task. The subClass/subId envelope carries the associated dealId or contactId reference. We use dealName matching against the migrated crm.lead to resolve project_id on the task, and contactId to resolve the user_id or partner_id. Status (pending, inProgress, completed) maps to Odoo stage_id within a dedicated project.project created for the migration. Due dates and assignee are preserved directly.

Firmao CRM

Product

maps to

Odoo CRM

product.product

1:1
Fully supported

Firmao Products (GET /svc/v1/product) map to Odoo product.product with name, default_code (product code), list_price, and standard_price preserved. The product's base fields migrate as-is. We create a corresponding product.template record alongside product.product per Odoo's internal architecture. Custom product fields (customFields.customN) follow the standard dot-notation extraction pattern.

Firmao CRM

Warehouse (subClass of Product)

maps to

Odoo CRM

stock.location + stock.quant

1:many
Fully supported

Firmao warehouse stock is not a standalone object — it returns as subClass=warehouse subId entries within the product GET response, carrying netPriceInStore and currentStoreState per warehouse. We extract each subId variant as a separate Odoo stock.location record with location_type='internal' and a corresponding stock.quant record for each product-location combination, setting the quantity from currentStoreState. This flattens the nested envelope structure into Odoo's flat stock management model.

Firmao CRM

User

maps to

Odoo CRM

res.users

1:1
Fully supported

Firmao Users (GET /svc/v1/user) export as name, email, and role. We map the role string to an Odoo access rights group (for example, 'admin' maps to 'CRM Manager' group, 'user' maps to 'Sales' group). Owner assignments on Deals and Tasks are resolved by email match against the migrated res.users records. Users without a matching Odoo account enter a reconciliation queue for the customer's admin to provision before the record import resumes.

Firmao CRM

Custom Fields

maps to

Odoo CRM

ir.model.fields (custom)

lossy
Mapping required

Firmao custom fields are defined in Professional and above under Settings and referenced in the API using dot-notation keys (customFields.custom5, customFields.custom12). There are no human-readable labels in the API response. We retrieve a sample record via GET first to enumerate which custom field keys are populated, then cross-reference against the customer's import documentation. Each active custom field key gets an Odoo ir.model.fields definition created before any data import begins, with the field type set to 'char' for string values. Empty custom fields in the sample export are flagged and excluded.

Firmao CRM

Tag / Label

maps to

Odoo CRM

res.partner.category

1:1
Fully supported

Tags appear as a comma-separated property on Firmao Contact and Company records with no dedicated /tags endpoint. We extract the tag values as a list during export and create corresponding res.partner.category records in Odoo (or match to existing categories by name). Each Contact or Company receives res.partner.category assignments via res.partner.respartner_rel_m2m during import.

Firmao CRM

Pipeline Stages

maps to

Odoo CRM

crm.stage

lossy
Mapping required

Pipeline stages are not a standalone API object in Firmao — they are a property value on each Deal record. We export the distinct stage names from the Deal dataset and create corresponding crm.stage records in Odoo before Deal import begins. Stage sequence order and probability percentages are set on each stage. If the customer has custom stage names (not the Firmao defaults), we use those verbatim in Odoo.

Firmao CRM

Invoice Header

maps to

Odoo CRM

account.move

1:1
Fully supported

Firmao Invoices (VAT invoices, bills, receipts, accounting notes) are accessible via the API with line items, tax codes, and payment status. We map invoice headers to Odoo account.move records with move_type='out_invoice' or 'in_invoice' depending on direction, and line items to account.move.line. Note that the full invoice financial workflow (payments, reconciliation, aged receivable reports) requires an Odoo Accounting configuration that is out of scope for the data migration itself.

Firmao CRM

Project (Professional+)

maps to

Odoo CRM

project.project

1:1
Fully supported

Firmao Projects (available on Professional and above, with Gantt and Kanban views) migrate as project.project with name, description, and date_start. The project task associations map to the project.task records already migrated. The Gantt bar positions and Kanban column configuration are visual layout data that do not have a structural equivalent in Odoo's project.project model and are not migrated.

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.

Firmao CRM logo

Firmao CRM gotchas

High

Tier-gated objects cause silent import failures

Medium

Custom field keys are dynamic and not self-documenting

Medium

Parent-child object import order is mandatory

Low

Warehouse stock state is subClass-embedded, not top-level

Low

API login is auto-generated and tied to company ID

Odoo CRM logo

Odoo CRM gotchas

High

Odoo.sh version gating blocks assisted migrations from trial

High

Enterprise modules fail to install on Community after database restore

Medium

Custom module view inheritance breaks between Odoo major versions

Medium

Custom fields risk losing their application context on Community

Low

API access for Community is gated behind the Custom Plan

Pair-specific challenges

  • Deal import fails silently on Standard-tier accounts

    Deals, custom fields, Gantt, Kanban, and the sales plan are gated behind Firmao Professional (€29/user/month) and Enterprise (€49/user/month). If we import Deals via the API for an account still on Standard, the records may appear to POST successfully but the pipeline UI will not display them because the tier activation flag is not set server-side. We confirm the customer's active plan tier during scoping, flag which objects are gated, and do not begin migration until the customer upgrades or confirms the Standard-tier object scope.

  • Custom field keys have no human-readable labels in the API

    Firmao custom fields follow the customFields.custom5 pattern with no self-documenting label in the GET response. The data import help file defines labels but requires login to access. We retrieve a sample record via GET to enumerate which custom fields are populated, cross-reference with customer-provided documentation, and exclude fields with no values in the sample export. Fields that are defined but never populated in any record cannot be distinguished from deleted definitions and are excluded to avoid creating empty Odoo custom fields.

  • Firmao has no bulk API and undocumented rate limits

    Firmao exposes only single-record GET and POST operations per endpoint. Large migrations require repeated single-record requests, extending transfer timelines. Rate limits are not publicly documented, so we probe with a conservative backoff strategy before scaling up request frequency. If we encounter 429 responses, we throttle immediately and resume after the backoff interval. This slow-and-steady approach protects the migration from undocumented throttling that could interrupt large data transfers.

  • Odoo XML-RPC has per-method batch size limits

    Odoo's XML-RPC API enforces batch size limits per method: create operations allow 5,000 records per call and search operations allow 80,000 results per call. Firmao's export must therefore be chunked to Odoo's limits, and the migration tooling must handle XML-RPC response parsing and error propagation correctly. We use the Odoo ORM's execute_kw method with batching logic that respects these limits per object type, falling back to paginated search-and-create loops for objects with larger datasets.

  • Parent-child object import order is mandatory

    Companies must be imported before Contacts, and Deals before Tasks in Firmao's API, otherwise the parent reference (companyId, dealId) resolves to null. Firmao's internal IDs are not exposed in the GET response, so we use companyName matching for Contacts and dealName or dealValue matching for Tasks as a fallback resolution strategy. We provide a sequencing manifest before migration begins so the customer can verify the relationship map and flag any duplicates or conflicts before data moves.

Migration approach

Six steps for a successful Firmao CRM to Odoo CRM data migration

  1. Discovery and tier verification

    We audit the source Firmao account across tier (Standard/Professional/Enterprise/Supreme), active API objects, custom field definitions (via sample record GET and customer documentation), pipeline stage names, owner list, and engagement volume. We also review the destination Odoo instance: edition (Community or Enterprise), installed modules (CRM, Sales, Project, Stock, Accounting), existing crm.stage records, and custom field definitions already present. The discovery output is a written migration scope confirming which objects are in scope, which are tier-gated and require upgrade confirmation, and which Odoo modules need activation before migration.

  2. Schema design and Odoo custom field pre-creation

    We design the Odoo destination schema before any data import. This includes creating ir.model.fields definitions for every Firmao custom field key found in the sample export, setting the field type to 'char' for string values, and assigning the fields to the correct model (res.partner, crm.lead, product.product). We also create crm.stage records matching the customer's Firmao pipeline stage names in the correct sequence order. Schema is deployed into the Odoo Sandbox or test environment first for validation.

  3. Sandbox migration and reconciliation

    We run a full migration into the Odoo Sandbox environment using a representative data sample. The customer reconciles record counts (Contacts in, Companies in, Deals in, Tasks in, Products in, stock.quant in), spot-checks 25-50 random records against the Firmao source, and signs off the schema and mapping before production migration begins. Any mapping corrections, custom field type adjustments, or stage name corrections happen in Sandbox, not in production.

  4. Owner reconciliation and User provisioning

    We extract every distinct owner referenced on Firmao Contact, Company, Deal, and Task records and match by email against the Odoo destination's res.users table. Owners without a matching Odoo User enter a reconciliation queue. The customer's Odoo admin provisions any missing Users before record import resumes, because OwnerId (user_id, user_ids) references on crm.lead, project.task, and res.partner must be valid at import time.

  5. Production migration in dependency order

    We run production migration in record-dependency order: res.users (provisioned, not migrated), res.partner for Companies (company_type='company'), res.partner for Contacts (company_type='contact' with parent_id resolved via companyName), crm.stage (stage definitions), crm.lead for Deals, product.template and product.product for Products, stock.location for each warehouse subId, stock.quant for each product-location quantity, project.project for Projects, project.task for Tasks, res.partner.category for Tags, account.move for Invoices. Each phase emits a row-count reconciliation report before the next phase begins.

  6. Cutover, validation, and automation rebuild handoff

    We freeze Firmao writes during cutover, run a final delta migration of any records modified during the migration window, then enable Odoo as the system of record. We deliver a written inventory of every active Firmao automation and process for the customer's Odoo admin to rebuild via Odoo Studio or a certified Odoo partner. We support a one-week hypercare window where we resolve any reconciliation issues. We do not rebuild Firmao automations as Odoo server actions or workflow rules inside the migration scope; that is a separate engagement or internal admin task.

Platform deep dives

Context on both ends of the pair

Firmao CRM logo

Firmao CRM

Source

Strengths

  • Generous free trial (14 days) with full feature access lets teams validate fit before committing to a paid tier.
  • Per-seat pricing with no per-contact billing means unlimited contacts on any plan — ideal for high-contact-volume SMBs.
  • Cloud storage included in every tier (2–10GB) reduces the need for a separate document management tool.
  • Multi-language and multi-currency support makes it viable for teams operating across European markets.
  • Android and iOS mobile apps provide field access for sales teams working outside the office.

Weaknesses

  • Rate limits are not publicly documented, which forces migration tooling to probe-and-backoff cautiously and slows large data transfers.
  • ERP-adjacent complexity (production, courier integrations, warehouse stock) is overkill for teams seeking a pure CRM tool.
  • Custom fields require a Professional or higher tier, gating basic users from one of the most common CRM customization needs.
  • No bulk API endpoint means large migrations must be executed via repeated single-record POST requests, extending transfer timelines.
Odoo CRM logo

Odoo CRM

Destination

Strengths

  • Modular open-source architecture lets teams start with CRM and add ERP apps as needs grow, all sharing one PostgreSQL database.
  • Free Community edition with no contact limits and full source code access means zero licensing cost for evaluation and small deployments.
  • Drag-and-drop Kanban pipeline with AI lead scoring gives a visual, prioritized view of the sales funnel without requiring custom configuration.
  • Native integrations with email, live chat, SMS, VoIP, WhatsApp, and social media feed all inbound leads into a single unified inbox.
  • Active Odoo Community Association (OCA) maintains dozens of community-maintained modules on GitHub for extended functionality.

Weaknesses

  • Gmail and email integration reliability is a recurring complaint — threads drop and conversations scatter across inboxes, disrupting sales team workflows.
  • Enterprise edition pricing stacks quickly: multiple apps at per-user rates ($25–$50/user/month) plus Odoo.sh hosting costs more than many SMBs anticipate.
  • Setup and configuration complexity increases significantly once custom fields, automation rules, and multiple installed modules are in play.
  • Odoo.sh trial databases run on a version (e.g., 18.3) that is not directly migratable to Odoo.sh, blocking the assisted migration path Odoo advertises.
  • Version upgrades between major Odoo releases (e.g., 17→18) frequently break custom module view definitions and XPath expressions, requiring manual remediation.

Complexity grading

How hard is this migration?

Standard CRM migration. 2 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 Firmao CRM and Odoo CRM.

  • Object compatibility

    B

    2 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

    Firmao CRM: Not publicly documented.

  • Data volume sensitivity

    B

    Firmao CRM doesn't expose a bulk API — REST + parallelization used for high-volume runs.

Estimator

Estimate your Firmao CRM to Odoo 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 Firmao CRM to Odoo CRM data migrations

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

Can't find your answer?

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

Book a free 30 minute consultation

Basic migrations under 10,000 total records (Contacts, Companies, Deals, Tasks) land between two and four weeks and complete in two to three weeks. Migrations with 25,000+ records, Products with multi-warehouse stock, more than ten custom field definitions, or project/task hierarchies move to six to ten weeks because of chunked API handling, warehouse stock flattening, and Odoo custom field pre-creation. The Odoo Sandbox validation step adds one to two weeks at the start if the environment is not already provisioned.

Adjacent paths

Related migrations to explore

Ready when you are

Move from Firmao CRM.
Land in Odoo 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