CRM migration
Field-level mapping, validation, and rollback between KulaHub and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
KulaHub
Source
Odoo CRM
Destination
Compatibility
8 of 13
objects map 1:1 between KulaHub and Odoo CRM.
Complexity
BStandard
Timeline
3-5 weeks
Overview
Moving from KulaHub to Odoo CRM is a schema remodelling migration, not a record copy. KulaHub stores all business entities as Contacts with company name, domain, and address embedded in the contact record; Odoo separates these into Contacts linked to Companies (Accounts). We extract company-level fields from KulaHub contacts into Odoo Company records during transform, then link the corresponding Odoo Contact back to the Company. KulaHub has no Deals or Pipeline object, so opportunity tracking is not present in source data unless it was recorded informally in notes. Odoo CRM's Lead object captures unqualified prospects, while Contacts represent qualified buyers attached to Accounts. We handle that split during scoping using any KulaHub contact tags or stage indicators. Email campaign history migrates to Odoo Marketing Campaign records, but marketing automation workflows, email templates, and sequences do not migrate. We deliver a written inventory of these for the customer to rebuild in Odoo or a separate marketing platform. Activity history (calls, emails, meetings, tasks) migrates via Odoo's XML-RPC or JSON-RPC API with batch chunking and chronological ordering preserved.
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 KulaHub 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.
KulaHub
Contact
Odoo CRM
Contact + Company (split required)
1:manyKulaHub stores all business entities as Contact records with company name, domain, address, and industry embedded as contact fields. We extract company-level fields (company_name, website, industry, company phone) into Odoo res.partner records with partner_type = 'company', then create a separate individual Contact (partner_type = 'person') linked to the Company via parent_id. The original KulaHub contact ID is preserved in a custom field x_kulahub_id for deduplication and audit. Any contacts that have no embedded company data become individual Contacts without a parent Company.
KulaHub
Contact
Odoo CRM
Lead
1:manyKulaHub contacts with no prior purchase history or informal stage indicators (captured in tags or notes) may represent unqualified prospects that map to Odoo crm.lead. We apply a split rule during scoping: contacts tagged 'lead', 'prospect', or 'unqualified' map to Odoo Lead. Contacts with active tasks, recent engagement, or formal company affiliation map to Odoo Contact attached to a Company. The customer defines the split rule based on their KulaHub tagging convention. The original KulaHub contact name and email migrate to Lead name and email_from.
KulaHub
Activity: Call
Odoo CRM
Note (comment) on Lead or Contact
1:1KulaHub call activities (type=CALL) with disposition, duration, and timestamp migrate to Odoo Mail Message records attached to the corresponding Lead or Contact (res.partner). Odoo does not have a native Task object equivalent for call logging outside of Project tasks; we use the Note/comment channel (mail.message with message_type='notification') to preserve the call record in the chatter timeline of the parent record, preserving the timestamp and disposition text.
KulaHub
Activity: Email
Odoo CRM
Mail Message on Lead or Contact
1:1KulaHub email activity records migrate to Odoo Mail Message records on the corresponding Lead or Contact. The email body, subject, and timestamp are preserved. KulaHub's GDPR unsubscribe flag migrates to a custom field x_email_opt_out on the Odoo partner record so that Odoo's mass mailing features respect existing suppression lists. Email attachments migrate as IrAttachment records linked to the mail.message.
KulaHub
Activity: Meeting
Odoo CRM
Calendar Event (calendar.event)
1:1KulaHub meeting activities map to Odoo calendar.event records. Start datetime, end datetime, location, and attendee list (KulaHub contact references) migrate to the corresponding Odoo fields. Attendees are resolved to Odoo res.partner records via email match and linked via calendar.event.res.partner records. If a KulaHub meeting has no matching Odoo Contact or Lead, the event is attached to the nearest parent Company record.
KulaHub
Activity: Task
Odoo CRM
Project Task (project.task) or Note
1:1KulaHub tasks with an assigned user and due date migrate to Odoo project.task records within a default 'CRM' project. Tasks with no assigned user or no due date migrate as Note records (mail.message) on the parent Contact or Lead. KulaHub task priority and completion status map to Odoo task priority and stage values. Task assignment resolves KulaHub owner email to Odoo res.users via email match.
KulaHub
Activity: System Event / Note
Odoo CRM
Note (mail.message) on Contact or Lead
1:1KulaHub system event logs and informal notes attached to contacts migrate to Odoo Mail Message records on the corresponding Lead or Contact. These are logged as internal notes (message_type='notification', subtype='note') so they appear in the chatter timeline without triggering email notifications to the contact. Timestamps are preserved from the KulaHub activity date.
KulaHub
Email Campaign
Odoo CRM
Marketing Campaign (utm.campaign) + Mass Mailing
lossyKulaHub email campaigns, templates, and tracking data (opens, clicks, unsubscribes) migrate to Odoo Marketing module's utm.campaign record and associated mail.mass_mailing records. The campaign name, description, and GDPR unsubscribe list migrate as utm.campaign metadata and mass mailing suppression records. KulaHub email templates migrate as mail.template records. Marketing automation workflows (KulaHub sequences, drip logic) do not migrate; we document each automation as a written step-list for the customer's Odoo admin to rebuild using Odoo's Marketing automation or Studio tools.
KulaHub
Document / Attachment
Odoo CRM
IrAttachment (linked to res.partner)
1:1KulaHub documents attached to contacts are linked via a foreign-key relationship. We extract each document blob (stored as base64 or URL reference in KulaHub) and create Odoo IrAttachment records with res_model='res.partner' and res_id pointing to the migrated Contact. Document name and file type (MIME) are preserved. We maintain the original KulaHub attachment ID in x_kulahub_attachment_id for audit.
KulaHub
User
Odoo CRM
Res.users
1:1KulaHub users appear in activity logs and task assignments. We export the full user list first (name, email, active status) and create matching Odoo res.users records via the Odoo XML-RPC API before any records that reference users are loaded. KulaHub user email is the dedupe key. Users without a matching Odoo instance are held in a reconciliation queue for the customer's admin to provision before record import resumes. Archived KulaHub users map to inactive Odoo users to preserve historical assignment.
KulaHub
Report / Activity Log Export
Odoo CRM
Custom Report (SQL view) or Spreadsheet
lossyKulaHub reports (All Contacts export, activity reports, CRM activity logs) are extracted as CSV and presented to the customer as a supplemental dataset. Odoo has a native Reporting module (crm_analysis) and Spreadsheet app, but the report layouts and metrics from KulaHub do not transfer directly. We deliver the KulaHub report data as a structured CSV and a written mapping to Odoo report fields so the customer's admin can rebuild reports in Odoo Reporting or connect the data to an external BI tool.
KulaHub
Form Submission
Odoo CRM
Custom Fields on Contact or Lead
1:1KulaHub website enquiry forms are linked to contact records but the form-field schema is not publicly documented. We request a sample export of form submission data during discovery and map key-value pairs to custom fields (x_field_name) on the Odoo res.partner or crm.lead model. Any unmapped fields are held in a staging table and presented to the customer for manual mapping before the production run. KulaHub form-to-contact associations migrate as Note records on the parent Contact.
KulaHub
GDPR Preference / Unsubscribe
Odoo CRM
Custom Field on Res.partner
lossyKulaHub stores email unsubscribe states and GDPR preference flags per contact but the data format is not documented. We export the preference flags as a custom field x_email_opt_out (boolean) and x_gdpr_consent_date (date) on the Odoo res.partner record, alongside the standard Odoo mailing.contact.opt_out_ids linktable. This ensures existing suppression lists are respected by Odoo's mass mailing features and can be re-exported if the customer later moves to another platform.
| KulaHub | Odoo CRM | Compatibility | |
|---|---|---|---|
| Contact | Contact + Company (split required)1:many | Fully supported | |
| Contact | Lead1:many | Fully supported | |
| Activity: Call | Note (comment) on Lead or Contact1:1 | Fully supported | |
| Activity: Email | Mail Message on Lead or Contact1:1 | Fully supported | |
| Activity: Meeting | Calendar Event (calendar.event)1:1 | Fully supported | |
| Activity: Task | Project Task (project.task) or Note1:1 | Fully supported | |
| Activity: System Event / Note | Note (mail.message) on Contact or Lead1:1 | Fully supported | |
| Email Campaign | Marketing Campaign (utm.campaign) + Mass Mailinglossy | Fully supported | |
| Document / Attachment | IrAttachment (linked to res.partner)1:1 | Fully supported | |
| User | Res.users1:1 | Fully supported | |
| Report / Activity Log Export | Custom Report (SQL view) or Spreadsheetlossy | Fully supported | |
| Form Submission | Custom Fields on Contact or Lead1:1 | Fully supported | |
| GDPR Preference / Unsubscribe | Custom Field on Res.partnerlossy | 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.
KulaHub gotchas
API has no public documentation or developer portal
No self-service bulk export or documented rate limits
Deleted record restoration costs £80/hour with 30-day window
Contact form field schema is not publicly documented
GDPR preference data portability not confirmed
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 KulaHub API access coordination
We begin by coordinating with KulaHub support to obtain API credentials and confirm the data extraction scope. We audit the KulaHub portal across contacts, activities, documents, tasks, campaigns, users, and form submissions. We measure API response behaviour with a small batch of requests to establish throughput baselines and identify any access limitations. We also confirm with the customer whether any contacts represent companies (and should be split) versus individuals, and whether KulaHub notes or tasks contain informal deal information that the customer wants preserved as note records in Odoo.
Schema design and company-contact split rule
We design the Odoo CRM schema before any data moves. This includes creating Odoo Company records (res.partner with partner_type='company') as parent entities, then creating individual Contact records (res.partner with partner_type='person') linked via parent_id. We define the split rule: which KulaHub contact fields indicate a company versus an individual, and how to handle contacts with no company data. We also configure the crm.lead model for unqualified prospects, create custom fields (x_kulahub_id, x_email_opt_out, x_gdpr_consent_date) on res.partner and crm.lead, and set up a default CRM project for task migration. Schema is deployed into a staging Odoo database first.
Data extraction, deduplication, and transform
We extract all KulaHub records via the REST API (coordinated with KulaHub support) or assisted export. We deduplicate contacts by email address before migration, keeping the most recently updated record. For each contact, we run the company-extraction transform: company-level fields create or match an Odoo Company record; individual fields create an Odoo Contact record linked to the Company. Activities are timestamped and sorted chronologically so that engagement history loads in the correct order. GDPR opt-out flags and email preferences are extracted as structured fields alongside standard contact properties.
Staging migration and reconciliation
We run a full migration into a staging Odoo database using production-like data volume. The customer's admin reviews record counts (Companies in, Contacts in, Leads in, Activities in), spot-checks 25-50 random records against the KulaHub source, and validates that the company-contact split produced the expected hierarchy. The customer also reviews how KulaHub notes and task data appear in Odoo chatter and the project task list. Any mapping corrections are applied before the production migration begins.
Production migration in dependency order
We run production migration in record-dependency order: res.users (validated), res.partner as Companies (from extracted company fields), res.partner as Contacts (linked to Companies), crm.lead (for unqualified prospects), Documents (as IrAttachment linked to Contact), Tasks and Activities (in chronological order via Odoo API batch calls), Email Campaign history (as utm.campaign and mail.mass_mailing records), Form submission data (as custom fields on Contact), GDPR preference data (as x_email_opt_out). Each phase emits a row-count reconciliation report before the next phase begins. We freeze KulaHub write access during cutover and run a final delta migration of any records modified during the window.
Cutover, validation, and automation rebuild handoff
We enable Odoo CRM as the system of record after the delta pass. We deliver the automation inventory document (every KulaHub email sequence and workflow, documented by trigger, condition, and action) to the customer's Odoo admin. We deliver the KulaHub report exports as structured CSVs with a field-mapping guide for Odoo Reporting or external BI. We support a one-week hypercare window where we resolve any reconciliation issues raised by the customer's team. We do not rebuild KulaHub sequences or marketing automations as Odoo Marketing automation plans inside the migration scope; that is a separate engagement or an internal admin task.
Platform deep dives
KulaHub
Source
Strengths
Weaknesses
Odoo CRM
Destination
Strengths
Weaknesses
Complexity grading
Standard CRM migration. All 8 core objects map 1:1 between KulaHub and Odoo CRM.
Overall complexity
Standard migration
Derived from compatibility, mapping clarity, API constraints, and data volume across KulaHub and Odoo CRM.
Object compatibility
All 8 core objects map 1:1 between KulaHub 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
KulaHub: Not publicly documented.
Data volume sensitivity
KulaHub 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 KulaHub to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your KulaHub 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 KulaHub
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.