---
title: "How to integrate Odoo with Medusa"
description: "How to integrate Odoo with Medusa: the official guide, Odoo JSON-2 vs XML-RPC/JSON-RPC, data mapping, real-time vs scheduled sync, and a code skeleton."
url: https://medusajs.com/kb/erp-integration/odoo
last_updated: 2026-10-29T06:55:50Z
topic: "erp-integration"
type: "concept"
applies_to: "Medusa v2.x"
related:
  - "https://medusajs.com/kb/erp-integration/ecommerce-erp-integration.md"
  - "https://medusajs.com/kb/erp-integration/business-central.md"
  - "https://medusajs.com/kb/b2b/b2b-customer-specific-pricing.md"
sources:
  - "https://docs.medusajs.com/resources/recipes/erp/odoo"
  - "https://docs.medusajs.com/resources/recipes/erp"
  - "https://www.odoo.com/documentation/19.0/developer/reference/external_api.html"
  - "https://www.odoo.com/documentation/19.0/developer/reference/external_rpc_api.html"
  - "https://www.odoo.com/documentation/20.0/developer/reference/external_rpc_api.html"
  - "https://www.odoo.com/documentation/19.0/applications/studio/automated_actions.html"
  - "https://www.odoo.com/documentation/19.0/applications/sales/sales/products_prices/prices/pricing.html"
  - "https://www.odoo.com/documentation/19.0/applications/websites/ecommerce.html"
  - "https://docs.medusajs.com/learn/fundamentals/events-and-subscribers"
  - "https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks"
  - "https://docs.medusajs.com/learn/fundamentals/scheduled-jobs"
  - "https://docs.medusajs.com/resources/commerce-modules/pricing/concepts"
  - "https://docs.medusajs.com/resources/commerce-modules/inventory/concepts"
---

# How to integrate Odoo with Medusa

> Medusa has an official guide for integrating Odoo. It builds a custom Medusa module that authenticates with Odoo's external API and syncs products into Medusa with a workflow and a daily scheduled job. You extend it with the Medusa ERP recipe's patterns for orders, prices, and stock. On Odoo 19 and later, prefer the JSON-2 API.

## Does Medusa have an Odoo integration?

Medusa has an official step-by-step guide, [Integrate Odoo with Medusa](https://docs.medusajs.com/resources/recipes/erp/odoo), with example code. It builds a custom Odoo module in Medusa that authenticates with Odoo, fetches products and their variants, and syncs them into Medusa with a workflow and a daily scheduled job. Orders, prices, and stock checks are not in the guide; you add them with the patterns in the [Medusa ERP integration recipe](https://docs.medusajs.com/resources/recipes/erp).

There is no installable Medusa Odoo plugin. The integration is code that lives in your Medusa project.

## Which Odoo APIs to use from Medusa

Odoo exposes its models (products, contacts, sales orders, and more) to external systems through two API generations.

| Odoo API | Endpoint | Status |
| --- | --- | --- |
| External JSON-2 API | POST to /json/2/<model>/<method> with an API key as a bearer token | New in Odoo 19.0. The replacement for the RPC APIs |
| XML-RPC and JSON-RPC | /xmlrpc, /xmlrpc/2, /jsonrpc | Deprecated since Odoo 19.0. Scheduled for removal in Odoo 22 (fall 2028) and Odoo Online 21.1 (winter 2027) |

The Medusa Odoo guide uses the JSON-RPC endpoint with the `json-rpc-2.0` package, which works on current Odoo versions. On Odoo 19 or later, write new code against JSON-2 so you do not have to migrate later.

Two Odoo constraints matter before you start. Odoo's documentation states that external API access is only available on Custom pricing plans, not on One App Free or Standard. For pushing changes out of Odoo, automation rules (in Odoo Studio) include a Send Webhook Notification action that POSTs selected fields to a URL.

## How Odoo data maps to Medusa

Each row is a sync in your Odoo module. The Medusa side of every row uses native commerce modules.

| Odoo data | Medusa equivalent | Direction | Status |
| --- | --- | --- | --- |
| Product templates and variants (product.template) | Products and product variants (Product Module) | Odoo to Medusa | Official guide |
| On-hand quantity (qty_available) | Inventory levels per stock location (Inventory Module) | Odoo to Medusa | Custom |
| Pricelists, including a pricelist set on a customer's contact | Price lists with customer group rules (Pricing Module), or a live price lookup in add-to-cart | Odoo to Medusa | Custom |
| Contacts (res.partner) | Customers and customer groups (Customer Module) | Both | Custom |
| Sales orders (sale.order) | Orders (Order Module) | Medusa to Odoo | Custom |
| Order and delivery status | Order updates | Odoo to Medusa | Custom |

Store the Odoo record ID on the Medusa record, for example in `metadata` or the product's `external_id`, so later syncs can match records.

## Real-time vs scheduled sync with Odoo

Medusa supports both timing models with built-in tools. The Odoo guide uses the scheduled model for products.

- **Scheduled.** A [scheduled job](https://docs.medusajs.com/learn/fundamentals/scheduled-jobs) runs the product sync workflow once a day (cron `0 0 * * *`), paging through Odoo products until none are left.
- **Real-time, Medusa to Odoo.** A [subscriber](https://docs.medusajs.com/learn/fundamentals/events-and-subscribers) on `order.placed` runs a workflow that creates the sales order in Odoo.
- **Real-time, inside checkout.** A [workflow hook](https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks) on `addToCartWorkflow` checks stock in Odoo before an item enters the cart.
- **Real-time, Odoo to Medusa.** An Odoo automation rule sends a webhook to a custom Medusa API route that runs an update workflow.

## Code skeleton: call the Odoo JSON-2 API from a Medusa module

A Medusa module service holds the Odoo connection, and workflows resolve it from the Medusa container. This sketch uses JSON-2 instead of the JSON-RPC client in the guide. The method name and body fields follow Odoo's JSON-2 reference.

```ts
type Options = { url: string; database: string; apiKey: string }

export default class OdooModuleService {
  private options: Options

  constructor({}, options: Options) {
    this.options = options
  }

  async searchRead(model: string, body: Record<string, unknown>) {
    const res = await fetch(`${this.options.url}/json/2/${model}/search_read`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `bearer ${this.options.apiKey}`,
        "X-Odoo-Database": this.options.database,
      },
      body: JSON.stringify(body),
    })
    if (!res.ok) throw new Error(`Odoo request failed: ${res.status}`)
    return res.json()
  }
}
```

The rest of the guide applies unchanged: register the module in `medusa-config.ts`, create the sync workflow with `createProductsWorkflow` and `updateProductsWorkflow`, and run it from a scheduled job.

## Odoo eCommerce vs Shopify vs Medusa with Odoo

Odoo ships its own eCommerce app, which handles the order lifecycle inside Odoo, including stock management, returns, and invoicing. That option deserves a fair look before you add a second system.

| Option | How it uses Odoo data | Sync needed |
| --- | --- | --- |
| Odoo eCommerce app | Built into Odoo, with orders, stock, and invoicing handled in Odoo | No |
| Shopify with Odoo | Third-party connector or iPaaS | Yes. Check vendor docs |
| Medusa with Odoo | Custom Medusa module from the official guide | Yes, in Medusa workflows and scheduled jobs |

## When Medusa is not the right choice for Odoo

- Odoo eCommerce covers your storefront and checkout needs. It avoids a second system and all sync work.
- You are on an Odoo Standard or One App Free plan. The external API is not available there, so no outside storefront can integrate.
- You have no developer. The Medusa Odoo integration is TypeScript code your team maintains.

Medusa fits when you need a custom storefront or checkout, multiple sales channels, or commerce logic Odoo eCommerce does not offer, while Odoo stays the system of record for products, stock, and orders.

## Common questions

### Is there a Medusa plugin for Odoo?

No installable plugin exists. Medusa provides an official guide with example code that you copy into your project as a custom Odoo module.

### Does the Odoo external API work on every Odoo plan?

No. Odoo's documentation states that access to data through the external API is only available on Custom pricing plans, not on One App Free or Standard plans.

### Is Odoo's XML-RPC and JSON-RPC API being removed?

Yes. Odoo deprecated the XML-RPC and JSON-RPC APIs in Odoo 19.0 and scheduled them for removal in Odoo 22 (fall 2028) and Odoo Online 21.1 (winter 2027). The External JSON-2 API replaces them.

### Can Odoo send webhooks to Medusa?

Yes. Odoo automation rules include a Send Webhook Notification action that sends a POST request with selected fields to a URL, such as a custom Medusa API route.

## Documentation

- [Integrate Odoo with Medusa](https://docs.medusajs.com/resources/recipes/erp/odoo)
- [Integrate ERP with Medusa](https://docs.medusajs.com/resources/recipes/erp)
- [Scheduled Jobs](https://docs.medusajs.com/learn/fundamentals/scheduled-jobs)
- [Workflow Hooks](https://docs.medusajs.com/learn/fundamentals/workflows/workflow-hooks)
- [Modules](https://docs.medusajs.com/learn/fundamentals/modules)

## Related

- [Which ecommerce platform is easiest to integrate with an ERP?](https://medusajs.com/kb/erp-integration/ecommerce-erp-integration.md)
- [Integrate Microsoft Dynamics 365 Business Central with Medusa](https://medusajs.com/kb/erp-integration/business-central.md)
- [How to build a B2B store with custom pricing per customer](https://medusajs.com/kb/b2b/b2b-customer-specific-pricing.md)
