CRM migration

Migrate from Odoo CRM to HubSpot

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

Odoo CRM logo

Odoo CRM

Source

HubSpot

Destination

HubSpot logo

Compatibility

93%

14 of 15

objects map 1:1 between Odoo CRM and HubSpot.

Complexity

BStandard

Timeline

48–72 hours

Rollback included Accuracy guarantee Field-level validation

Try the reverse

HubSpot
Odoo CRM

Overview

What this migration involves

Odoo CRM stores contacts and companies in a single res.partner model with a type flag distinguishing individuals from organizations. Deals live in crm.lead with a kanban-stage field that maps directly to HubSpot deal pipelines and stages. HubSpot separates contacts and companies into distinct objects, requires a primary company association per contact, and models deals with a mandatory pipeline + stage pair and a closedate field. We extract Odoo data via the XML-RPC / JSON-RPC external API (available on Odoo Enterprise; Odoo Community uses direct PostgreSQL reads), then map res.partner records into HubSpot contacts and companies, crm.lead records into HubSpot deals, and crm.activity records into HubSpot engagement logs (calls, emails, meetings, tasks, notes). Custom fields on crm.lead and res.partner migrate as HubSpot custom properties. Odoo workflow rules, automation actions, and server actions do not migrate — those must be rebuilt in HubSpot's workflow builder. Our migration runs a sample pass against a HubSpot sandbox before committing the full load, and a 24–48 hour delta-pickup window captures any records modified in Odoo during the cutover.

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 CRM logo

Odoo CRM

What's pushing teams away

  • Mail and Gmail integration is repeatedly cited on Reddit and G2 reviews as unreliable — email threads drop, conversations scatter across inboxes, and the sync between Odoo and Gmail breaks under common configurations.
  • Setup complexity grows with business size: reviews note that advanced features require additional configuration and customization, and costs rise steeply once multiple paid apps and users are stacked together.
  • Support response times frustrate Enterprise customers who encounter bugs during version upgrades, with some noting that critical issues go unresolved for weeks.
  • Some teams migrate away from Odoo toward modern CRMs like Attio because they want a slicker, more opinionated UX rather than Odoo's broad-but-configurable interface.
  • Companies leave Odoo.sh specifically when they want more control over their infrastructure — alternatives like udoocloud.pro target users who want direct shell access and no platform vendor lock-in.

Choosing

HubSpot logo

HubSpot

What's pulling them in

  • Lowest barrier to entry of any major CRM — the free tier with unlimited contacts lets teams validate fit before committing to a paid plan, according to G2 and Capterra reviewers.
  • Native integration between the CRM and sales engagement tools (sequences, email tracking, dialer) means no separate sync configuration, a theme across G2 Sales Hub reviews.
  • Pipeline visualization, deal tracking, and automated workflows are consistently praised as intuitive and easy to set up without developer involvement.
  • Strong onboarding for new team members — reviewers on Capterra and G2 highlight how quickly new reps become productive without formal training.
  • The HubSpot platform ecosystem (Marketing, Sales, Service, CMS hubs) allows growing companies to consolidate tools without building new integrations.

Object mapping

How Odoo CRM objects map to HubSpot

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

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

Odoo CRM

res.partner (is_company = True)

maps to

HubSpot

Company

1:1
Fully supported

Odoo companies stored in res.partner with is_company=True map directly to HubSpot Company records. Odoo's street, city, country, phone, website fields on the partner record map to HubSpot's address properties and Website field. Parent-company hierarchies in Odoo (parent_id on res.partner) map to HubSpot's parent company association.

Odoo CRM

res.partner (is_company = False)

maps to

HubSpot

Contact

1:1
Fully supported

Odoo individual contacts (is_company=False) map to HubSpot Contact records. The contact's email, phone, mobile, job title (function field in Odoo), and address properties migrate as HubSpot contact properties. Odoo's parent_id on a contact record determines the HubSpot primary CompanyId association.

Odoo CRM

crm.lead (type = 'lead' or 'opportunity')

maps to

HubSpot

Deal

many:1
Fully supported

Odoo's crm.lead serves both lead and opportunity records. We map all crm.lead records to HubSpot Deal objects regardless of Odoo's type flag. Odoo's type distinction is preserved as a HubSpot custom property (lead_type__c) since HubSpot does not have a native equivalent split between lead and deal.

Odoo CRM

crm.stage

maps to

HubSpot

Deal Pipeline Stage

1:1
Fully supported

Odoo stage names (New, Qualified, Proposal, Won, Lost, etc.) map value-by-value to HubSpot Deal stage names within a designated pipeline. We create the HubSpot pipeline before migration and apply stage name mappings per stage_id in Odoo's crm.stage table. Stage sequence order is preserved.

Odoo CRM

crm.team

maps to

HubSpot

Team / User Assignment

1:1
Fully supported

Odoo's crm.team records map to HubSpot user team assignments. Team members are resolved by email match against HubSpot users, ensuring that owner assignments translate correctly across platforms. Unmatched team assignments are flagged in the pre-migration audit report so the team can pre-create HubSpot users or assign a fallback owner before the migration run begins.

Odoo CRM

crm.activity (category = 'call')

maps to

HubSpot

Call

1:1
Fully supported

Odoo activities with category='call' migrate as HubSpot Call engagement records. Original call date, duration (x_duration in Odoo), summary (note field), and owner are preserved. Calls are associated to the corresponding HubSpot contact and deal via the Odoo's res.partner and crm.lead linkages.

Odoo CRM

crm.activity (category = 'email')

maps to

HubSpot

Email

1:1
Fully supported

Odoo email activities migrate as HubSpot Email engagement records. The email subject, body (mail.message body), timestamp, and direction (inbound/outbound) are mapped to HubSpot email properties. Thread associations from Odoo's mail.thread model are preserved via the HubSpot associations API, ensuring conversation continuity is maintained across the platform migration.

Odoo CRM

crm.activity (category = 'meeting')

maps to

HubSpot

Meeting

1:1
Fully supported

Odoo meeting activities map to HubSpot Meeting records with original start/end timestamps, title (summary field), and body preserved for complete meeting history. Odoo's calendar.event records (if used for scheduled meetings) are also mapped to HubSpot Meetings with the same property set, maintaining calendar context within the CRM.

Odoo CRM

crm.activity (category = 'note' or generic note)

maps to

HubSpot

Note

1:1
Fully supported

Odoo notes and generic activities without a specific category migrate as HubSpot Notes, preserving the note body, author, and timestamp for historical reference. Notes are associated to the corresponding HubSpot contact, company, or deal record via the associations API after parent records are migrated.

Odoo CRM

sale.order / account.move (quotation state)

maps to

HubSpot

Quote

1:1
Fully supported

Odoo quotations (sale.order in draft or sent state) map to HubSpot Quote records with line items, quantities, and pricing transferred from sale.order.line to HubSpot Quote line items. Odoo's discount fields and tax handling require value-mapping per product configuration to ensure pricing accuracy is maintained in the HubSpot quote records.

Odoo CRM

ir.attachment

maps to

HubSpot

File

1:1
Fully supported

Odoo attachments on crm.lead and res.partner records migrate as HubSpot Files. We download each attachment from Odoo's filestore and re-upload to HubSpot's file storage, preserving filename, mime type, and original upload date. Files are associated to the target record after upload.

Odoo CRM

Odoo custom fields on crm.lead

maps to

HubSpot

Contact/Deal Custom Properties

1:1
Fully supported

Odoo custom fields on crm.lead (x_studio_*, x_custom_*) migrate as HubSpot custom properties on Deal. Field type translation: char → string, integer/float → number, boolean → bool, date → date, datetime → datetime, selection → enumeration. Odoo many2one fields map to HubSpot string (ID reference) or require a lookup table.

Odoo CRM

Odoo custom fields on res.partner

maps to

HubSpot

Contact/Company Custom Properties

1:1
Fully supported

Odoo custom fields on res.partner migrate as HubSpot custom properties on Contact or Company depending on whether the field is defined on individual contact records or company records. Selection fields become HubSpot enumeration properties with exact value lists preserved from the Odoo selection field options.

Odoo CRM

mail.message (thread messages on crm.lead)

maps to

HubSpot

Email / Note

1:1
Fully supported

Odoo's mail.message records on crm.lead objects (internal notes and emails) migrate as HubSpot Notes or Email engagement records based on message type classification. Email subtype messages become HubSpot Emails with full body and headers preserved, while note subtype messages become Notes for internal reference. Author and create date are preserved on both record types.

Odoo CRM

crm.lost_reason

maps to

HubSpot

Deal: Closed Lost (custom field)

1:1
Fully supported

Odoo's crm.lost_reason model stores named loss reasons per stage. These map to a HubSpot custom pick-list property (lost_reason__c) on the Deal object for consistent loss reason tracking. Each named Odoo reason becomes a HubSpot enumeration value so reporting on loss reasons remains consistent across the migrated dataset.

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 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

HubSpot logo

HubSpot gotchas

High

Marketing Contacts billing model is migration-critical

High

Feature tier gating is not visible until onboarding

Medium

Mandatory onboarding fees inflate year-one cost

Medium

HubSpot CSV importer cannot migrate engagements or attachments

Medium

Custom objects require Enterprise and a pre-existing schema

Pair-specific challenges

  • res.partner N:N associations collapse to primary CompanyId in HubSpot

    Odoo permits a contact to have multiple parent companies via multiple res.partner records linked to the same contact through parent_id, or via an intermediate link table. HubSpot's Contact-Company association model supports multiple companies per contact through the associations API, but the import must be sequenced: we migrate all Company records first, then associate each Contact to its companies. If Odoo stores a contact-company relationship only as a shared crm.lead (the contact is linked to a deal which is linked to a company), we surface this during the mapping audit and provide a manual association plan.

  • Odoo Community lacks an external API — extraction requires direct database access

    Odoo Enterprise exposes a full XML-RPC and JSON-RPC external API with search_read, read, and write methods. Odoo Community does not expose this API — only Odoo Online on a Custom Plan ($17.90/user/month) unlocks external API access. For Odoo Community migrations, FlitStack reads directly from the PostgreSQL database. This requires read-only database credentials and a static database snapshot or read replica to avoid impacting a live Odoo instance. We disclose this limitation upfront and scope it as a separate technical workstream.

  • HubSpot's deal model requires a named pipeline before any deal can be created

    HubSpot requires at least one Deal Pipeline to exist before Deals API calls will succeed. If no pipeline is pre-created in the HubSpot portal, the migration will fail all deal upserts. We create the target pipeline in HubSpot before running any deal migration, using Odoo's crm.stage records as the stage definition source. Teams with multiple Odoo sales teams (multiple crm.team records) must decide whether to map them to a single HubSpot pipeline with stage scoping or multiple pipelines — this is a schema decision made during the mapping audit.

  • Original create dates cannot be set in HubSpot — only preserved as custom properties

    HubSpot's Createdate timestamp is set by the platform at record creation time during import and cannot be backdated via API. Odoo's create_date on res.partner and crm.lead records cannot be replicated as the actual created date in HubSpot. We preserve the original Odoo create_date as a custom datetime property (original_create_date__c) on both Contact and Deal records. Odoo's write_date maps directly to HubSpot's lastmodifieddate. Historical reporting that relies on original create date must query the custom property rather than the system timestamp.

  • Odoo lost_reason_id on crm.lead requires pre-existing HubSpot pick-list values

    HubSpot custom pick-list properties must have their allowed values defined before records are imported. If Odoo's crm.lost_reason records contain values not yet added to HubSpot's closed_lost_reason__c custom property, the import will silently drop those values or error depending on the API configuration. We audit Odoo's crm.lost_reason values during the mapping phase, create the corresponding HubSpot enumeration values before the migration run, and flag any mismatches as a manual decision item.

Migration approach

Six steps for a successful Odoo CRM to HubSpot data migration

  1. Audit Odoo data model and extract schema

    FlitStack connects to Odoo (via external API for Enterprise/Custom Plan, or via read-only PostgreSQL access for Community) and pulls the complete schema: all res.partner fields, all crm.lead fields, crm.stage definitions, crm.team records, crm.activity types, and ir.model.fields for custom field names and types. We generate a data audit report showing record counts per object, custom field inventory, blank/null rates, and parent-child relationship depth. This audit identifies Odoo Community database access requirements and flags any fields that cannot be extracted via standard API methods.

  2. Map schema and configure HubSpot destination

    We translate Odoo's object model to HubSpot objects (res.partner → Contact + Company, crm.lead → Deal, crm.activity → Call/Email/Meeting). Custom fields from Odoo are created as HubSpot custom properties with appropriate type translations. We create the HubSpot Deal Pipeline and stages using Odoo's crm.stage names as the source. Owner resolution by email is configured: Odoo user IDs are matched against HubSpot user emails, and unmatched owners are flagged with a fallback assignment recommendation.

  3. Migrate companies first, then contacts, then deals

    HubSpot requires Companies to exist before Contacts can associate via associatedcompanyid, and Contacts to exist before Deals can associate contact roles. We sequence the migration: (1) all res.partner records where is_company=True migrate as HubSpot Companies, (2) all res.partner records where is_company=False migrate as HubSpot Contacts with primary company associations resolved, (3) all crm.lead records migrate as HubSpot Deals with contact associations and stage mapping. Activities and attachments migrate after parent records are in place, maintaining referential integrity throughout.

  4. Run a sample migration with field-level verification

    A representative slice — typically 200–500 records covering the range of contact types, deal stages, and activity categories — migrates to a HubSpot sandbox or test portal. We generate a field-level diff report comparing Odoo source values against the migrated HubSpot values for every mapped field. You review the diff and confirm field mapping correctness, lost-reason value coverage, owner resolution rates, and date preservation before the full run commits.

  5. Execute full migration with delta-pickup cutover window

    The full dataset migrates to HubSpot with real-time progress tracking and QA checkpoints after each object batch. During the migration, your Odoo team continues working. After the primary migration completes, a 24–48 hour delta-pickup window captures any Odoo records created or modified during the cutover, applying the same field mappings and transformations. An audit log records every upsert, association, and transformation. If reconciliation identifies issues, one-click rollback reverts the HubSpot environment to the pre-migration state.

  6. Post-migration validation and workflow rebuild handoff

    FlitStack runs automated validation scripts comparing record counts, field completeness, and association integrity between the Odoo snapshot and HubSpot state. Spot-check verification covers deals at each stage, contacts with attachments, and activity logs. We deliver an export of your Odoo workflow and automation definitions as a structured reference document for your HubSpot admin to use when rebuilding rules in HubSpot's workflow builder. A 30-day post-migration support window covers any data discrepancies discovered after go-live.

Platform deep dives

Context on both ends of the pair

Odoo CRM logo

Odoo CRM

Source

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.
HubSpot logo

HubSpot

Destination

Strengths

  • Genuinely useful free CRM tier with no seat limit on contact records.
  • All-in-one sales engagement layer (sequences, email tracking, calling, dialer) embedded natively in the CRM, eliminating a separate integration.
  • Intuitive interface and fast onboarding for individual reps, per G2 and Capterra reviews.
  • Workflow automation triggers across contacts, deals, and tickets with a visual builder.
  • API coverage for all standard objects including custom objects at Enterprise tier.

Weaknesses

  • Pricing model is contact-based at the marketing layer — importing all records as marketing contacts can multiply the monthly bill by 4×.
  • Feature tier cliffs are frequent surprises: sequences, calling, advanced reporting, and quoting are all gated, often requiring plan upgrades mid-implementation.
  • Mandatory onboarding fees at Professional ($1,500) and Enterprise ($3,500) are not prominently disclosed on the pricing page.
  • API rate limits are restrictive for bulk migration — burst limits of 100-200 req/10sec and search endpoint limits of 4 req/sec require careful job queuing.
  • Custom objects, additional pipelines, and advanced forecasting are Enterprise-only, making cost projections difficult for growing teams.

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 CRM and HubSpot.

  • 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 CRM: Not publicly documented; no published rate limit found in Odoo's official developer documentation.

  • Data volume sensitivity

    B

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

Estimator

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

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

Can't find your answer?

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

Book a free 30 minute consultation

Most Odoo CRM to HubSpot migrations complete within 48–72 hours for under 25,000 total records. Larger datasets with 100,000+ records, extensive crm.activity history, or Odoo Community setups (which require direct PostgreSQL extraction) extend to 7–14 days. The longest single step is typically the mapping audit and HubSpot pipeline configuration, which precedes data movement. Odoo Community database extraction requires a static snapshot or read replica to avoid impacting a live database.

Adjacent paths

Related migrations to explore

Ready when you are

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