Syncing a CRM with Odoo without paying for an iPaaS subscription
Odoo is great as an ERP, but the moment sales wants to keep using HubSpot or Pipedrive as their CRM, you're stuck with a sync problem: contacts and orders need to exist correctly in both places, in both directions, without double-creating records or silently dropping updates.
The "just use Zapier/Make/Workato" answer works, but at CRM+ERP volume you're often paying $50-300/mo for what is, underneath, a scheduled poll and a webhook. I ended up building this as a plain n8n workflow instead, and wanted to share the pattern since it generalizes to basically any "sync system A with system B" problem, not just Odoo.
The two directions are not symmetric, and that matters
Odoo → CRM: a scheduled poll every 15 minutes, using Odoo's write_date field to pull only records changed since the last run (a delta sync, not a full table scan — this is the difference between a sync that stays fast at 50 records and one that stays fast at 50,000). Each changed res.partner or sale.order gets upserted into the CRM via its REST API.
CRM → Odoo: a webhook, because CRMs push changes in real time and there's no reason to wait 15 minutes for a lead update to land in Odoo. The webhook branches on whether the incoming record is new (create) or existing (update), matched by an external-ID field kept on both sides.
The asymmetry is the part people usually get wrong when they build this the first time: they either poll both directions (adds needless latency on the CRM side) or webhook both directions (Odoo doesn't push webhooks natively without extra modules). Poll the system that doesn't push, webhook the one that does.
Matching records without collisions
Both res.partner (contacts) and sale.order (orders) get an external-ID field synced on both sides at creation time, so updates always match the right record instead of relying on fuzzy matching (name + email, which breaks the moment someone has a typo or a duplicate).
If you want the built version
I packaged this as a 27-node n8n workflow — Odoo delta poll, CRM webhook with create/update branching, external-ID matching for both contacts and orders:
$49, one-time, works with HubSpot, Pipedrive, or any CRM with a REST webhook — you import it into your own n8n instance and point it at your credentials.
If you've built a two-way sync between other systems, I'd like to hear what matching strategy you used instead of external IDs — curious if anyone's had a cleaner approach.
Top comments (0)