CRM migration
Field-level mapping, validation, and rollback between Cordial and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
Cordial
Source
Odoo CRM
Destination
Compatibility
8 of 12
objects map 1:1 between Cordial and Odoo CRM.
Complexity
BStandard
Timeline
3-5 weeks
Overview
Moving from Cordial to Odoo CRM is a structural migration from a marketing-centric JSON-flexible platform to an ERP-integrated relational model. Cordial organizes data into collections (Contacts, Products, Channels) with unlimited custom contact attributes stored as flattened properties, while Odoo CRM uses res.partner with a fixed schema and custom fields via Studio. Cordial's product-centric architecture with nested variant JSON maps to Odoo's product.template and product.product split, and any order data stored as custom events or attributes in Cordial requires pre-migration discovery before it can land as sale.order records in Odoo. We do not migrate Cordial Programs, automation workflows, or A/B test experiment results; we deliver a written inventory of these for your admin to rebuild in Odoo's workflow builder.
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 Cordial 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.
Cordial
Contacts
Odoo CRM
res.partner
1:1Cordial Contacts map to Odoo res.partner records. We export the flat attribute schema (email, first_name, last_name, phone, address fields) and map each standard Cordial contact attribute to an Odoo custom field on res.partner. Array-type attributes (tags, favorite colors, behavioral lists) require schema normalization: we flatten to delimited strings or create a related res.partner.tag record with a many2many relationship, agreed upon with the customer during scoping. The res.partner record is the parent for all downstream lookups.
Cordial
Contact Attributes (Custom Fields)
Odoo CRM
res.partner Custom Fields
lossyCordial's unlimited custom contact attributes (string, number, geo, array types) map to Odoo custom fields on res.partner. We create each custom field via Odoo Studio or Python model migration before data import. Array-type attributes require the customer to choose between a multi-value char field, a dedicated res.partner.tag relation table, or separate normalization. Geo-type attributes (latitude, longitude) map to Odoo's res.partner partner_latitude and partner_longitude fields or to a separate geo.point relation.
Cordial
Lists
Odoo CRM
res.partner.category or mailing.contact
1:1Cordial Lists (static contact sub-collections) map to Odoo res.partner.category records (tags) with a many2many relation to res.partner. Each Cordial list becomes a category record with the list name as the tag name, and list membership migrates as partner-category associations. If the customer uses Odoo Email Marketing, we alternatively map to mailing.contact for precise opt-in audience management.
Cordial
Channels
Odoo CRM
res.partner email/sms fields
1:1Cordial Channels (email, SMS opt-in status and preferences per contact) map to Odoo res.partner fields: email becomes email, email_cohorts or opt-out flags become opt_out, and mobile preferences become mobile with SMS-specific opt-in mapped to a custom field cordialsms_optin__c. We export channel preferences as separate boolean fields and flag any non-standard channel types that have no Odoo equivalent.
Cordial
Products
Odoo CRM
product.template + product.product
1:manyCordial Products with nested variant JSON arrays require unpacking. Each Cordial product record generates one product.template in Odoo. Each variant within the Cordial variants array (color, size, SKU pairs) generates a separate product.product record linked to the template via product.attribute.value. We preserve the parent Cordial product ID as an external reference field for reconciliation. If Odoo does not already have the relevant product attributes (color, size) defined, we create them during the migration schema setup.
Cordial
Orders
Odoo CRM
sale.order + sale.order.line
lossyOrders are not a native Cordial object and require pre-migration schema discovery. We identify order-related custom attributes and custom event types (purchase events) during discovery, extract order records from the behavioral event log, and map them to Odoo sale.order and sale.order.line. Customer association resolves to the res.partner record; product association resolves to product.product via SKU lookup; pricing and quantity map directly. This phase is scoped separately because order data location varies per customer implementation.
Cordial
Companies
Odoo CRM
res.partner (company_type = company)
1:1Cordial Companies stored in the Companies collection map to Odoo res.partner records with company_type = company. Address, domain, and industry fields map to standard Odoo partner fields. A separate res.partner contact record is created under the company partner for each related contact record, linked via parent_id. If Cordial Company is used only for enrichment and not as a separate collection, the company data is extracted from the contact attributes and applied to the partner record directly.
Cordial
Segments / Audiences
Odoo CRM
res.partner.category + domain filters
1:1Cordial Segments (dynamic rule-based audiences) do not have a direct Odoo equivalent in the standard CRM module. We export segment definitions as rule summaries and document which contacts currently match each segment. For static lists we create res.partner.category records; for dynamic segments we document the rule logic so the customer's admin can implement Odoo Search Filters or domain filters on a saved search as the equivalent.
Cordial
Events / Contact Activities
Odoo CRM
mail.activity
1:1Cordial Contact Activities (opens, clicks, purchases, custom events) map to Odoo mail.activity records linked to res.partner. We export activity data via the Contact Activity Export API with time-range and event-type filters. Each activity type (email_open, purchase, custom_event_name) becomes an activity with activity_type_id set to a custom Odoo activity type created during schema setup. ActivityDate maps to date_deadline and create_date preserves the original timestamp. If the customer uses the Odoo CRM module heavily, mail.activity provides a workable activity timeline; note that Odoo does not natively support the granular A/B engagement metrics that Cordial captures per message.
Cordial
Owner
Odoo CRM
res.users
1:1Cordial Owners (sales reps assigned to contacts and products) map to Odoo res.users by email match. We extract every distinct owner referenced in the Cordial export, match against the Odoo destination User list, and flag any owner without a corresponding Odoo user for the customer's admin to provision before the migration proceeds. user_id on res.partner is set during import to maintain rep assignment.
Cordial
Message Analytics
Odoo CRM
mail.message (limited)
1:1Cordial Message Analytics (opens, clicks, bounces, unsubscribes) migrate to Odoo mail.message records linked to the relevant res.partner. We preserve aggregate metrics (open count, click count, bounce status) as custom fields on the partner record. Experiment results (A/B and multivariate test outcomes) are explicitly not API-exportable from Cordial and cannot be migrated programmatically; we flag this gap during discovery and recommend exporting experiment data from the Cordial UI before cutover.
Cordial
Automation Programs
Odoo CRM
Server Actions (documentation only)
lossyCordial Programs (automation sequences and campaign logic) are not API-exportable. We deliver a written inventory of every active Program including trigger events, conditions, delay rules, and action sequence with a recommended Odoo Server Action or CRM Activity Plan equivalent. The customer's Odoo admin or implementation partner rebuilds the automations post-migration. We do not execute automation logic inside the migration scope.
| Cordial | Odoo CRM | Compatibility | |
|---|---|---|---|
| Contacts | res.partner1:1 | Fully supported | |
| Contact Attributes (Custom Fields) | res.partner Custom Fieldslossy | Fully supported | |
| Lists | res.partner.category or mailing.contact1:1 | Fully supported | |
| Channels | res.partner email/sms fields1:1 | Mapping required | |
| Products | product.template + product.product1:many | Fully supported | |
| Orders | sale.order + sale.order.linelossy | Mapping required | |
| Companies | res.partner (company_type = company)1:1 | Fully supported | |
| Segments / Audiences | res.partner.category + domain filters1:1 | Mapping required | |
| Events / Contact Activities | mail.activity1:1 | Mapping required | |
| Owner | res.users1:1 | Fully supported | |
| Message Analytics | mail.message (limited)1:1 | Mapping required | |
| Automation Programs | Server Actions (documentation only)lossy | 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.
Cordial gotchas
Message experiment results are not API-exportable
Rate limits are method- and endpoint-specific
Custom contact attribute arrays require schema normalization
Products collection uses nested JSON with variants
Odoo CRM gotchas
Odoo.sh version gating blocks assisted migrations from trial
Enterprise modules fail to install on Community after database restore
Custom module view inheritance breaks between Odoo major versions
Custom fields risk losing their application context on Community
API access for Community is gated behind the Custom Plan
Pair-specific challenges
Migration approach
Discovery and schema mapping
We audit the Cordial account across collections (Contacts, Companies, Products, Channels), custom contact attributes by type (string, number, geo, array), event types in the behavioral log, and any order-related custom attributes or custom event types. We pair this with an Odoo module inventory: which Odoo apps are installed (CRM, Sales, Inventory, Accounting), which are the target for migration, and whether Odoo Studio or custom Python models are needed for complex attribute types. The discovery output is a written migration scope document and a field-level mapping matrix covering every Cordial attribute.
Odoo schema preparation and custom field creation
We create the destination schema in the Odoo instance before any data import. This includes provisioning product.attributes and product.attribute.values for each Cordial product variant dimension (color, size, material), creating product.template and product.product records, and defining custom fields on res.partner for every Cordial custom attribute that does not map to a standard Odoo partner field. If array-type attributes require a normalization strategy, we create the supporting res.partner.tag model and many2many relation. Schema changes deploy into a non-production environment first for validation.
Data quality audit and normalization
We run a data quality audit against the Cordial export, identifying missing email addresses, malformed phone numbers, duplicate contacts, array-typed attributes requiring normalization, and order-related custom events requiring extraction. We present a data cleansing report to the customer and agree on a cleansing strategy before migration. Records that cannot be automatically normalized are flagged in a manual review queue. This step is critical because Odoo's field validation will reject records with invalid formats on the first import attempt.
Staging migration and reconciliation
We run a full migration into the customer's Odoo staging environment using production-like data volume. The customer reconciles record counts (Partners in, Products in, Activities in), spot-checks 25-50 random records against the Cordial source, and validates that custom field data is correctly populated. Any mapping corrections, missed custom attributes, or variant unpacking issues surface here and are resolved before production migration. No production data moves until staging sign-off.
Production migration in dependency order
We run production migration in record-dependency order: product.attributes and product.attribute.values first, then product.template, then product.product variants, then res.partner (companies first, then contacts with parent_id resolved), then mail.activity records linked to res.partner, then sale.order and sale.order.line (if order data exists and was scoped). Each phase emits a row-count reconciliation report before the next phase begins. Array-typed attributes normalize during the transform step before partner insert.
Cutover, validation, and automation rebuild handoff
We freeze writes in Cordial during the cutover window, run a final delta migration of any records modified during the window, and enable Odoo as the system of record. We deliver the Program inventory and automation rebuild guide to the customer's admin team, with Odoo Server Action and CRM Activity Plan equivalents documented per program. We support a one-week hypercare window for reconciliation issues. We do not rebuild Cordial automation programs inside the migration scope; that work requires an Odoo implementation partner or internal admin effort.
Platform deep dives
Cordial
Source
Strengths
Weaknesses
Odoo CRM
Destination
Strengths
Weaknesses
Complexity grading
Standard CRM migration. All 8 core objects map 1:1 between Cordial and Odoo CRM.
Overall complexity
Standard migration
Derived from compatibility, mapping clarity, API constraints, and data volume across Cordial and Odoo CRM.
Object compatibility
All 8 core objects map 1:1 between Cordial and Odoo CRM.
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
Cordial: Method- and endpoint-specific limits; default limits vary per tier; X-Rate-Limit-* response headers exposed; Retry-After header for backoff; limits are customizable per customer contract.
Data volume sensitivity
Cordial exposes a bulk API — large-volume migrations stream efficiently.
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 Cordial to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your Cordial to Odoo 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 Cordial
Other ways to arrive at Odoo 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.