How to integrate Odoo with Medusa

Type
Concept
Applies to
Medusa v2.x
Updated

Short answer

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

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 APIEndpointStatus
External JSON-2 APIPOST to /json/2/<model>/<method> with an API key as a bearer tokenNew in Odoo 19.0. The replacement for the RPC APIs
XML-RPC and JSON-RPC/xmlrpc, /xmlrpc/2, /jsonrpcDeprecated 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 Copy to clipboardjson-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 dataMedusa equivalentDirectionStatus
Product templates and variants (product.template)Products and product variants (Product Module)Odoo to MedusaOfficial guide
On-hand quantity (qty_available)Inventory levels per stock location (Inventory Module)Odoo to MedusaCustom
Pricelists, including a pricelist set on a customer's contactPrice lists with customer group rules (Pricing Module), or a live price lookup in add-to-cartOdoo to MedusaCustom
Contacts (res.partner)Customers and customer groups (Customer Module)BothCustom
Sales orders (sale.order)Orders (Order Module)Medusa to OdooCustom
Order and delivery statusOrder updatesOdoo to MedusaCustom

Store the Odoo record ID on the Medusa record, for example in Copy to clipboardmetadata or the product's Copy to clipboardexternal_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 runs the product sync workflow once a day (cron Copy to clipboard0 0 * * *), paging through Odoo products until none are left.
  • Real-time, Medusa to Odoo. A subscriber on Copy to clipboardorder.placed runs a workflow that creates the sales order in Odoo.
  • Real-time, inside checkout. A workflow hook on Copy to clipboardaddToCartWorkflow 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.

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}`)

The rest of the guide applies unchanged: register the module in Copy to clipboardmedusa-config.ts, create the sync workflow with Copy to clipboardcreateProductsWorkflow and Copy to clipboardupdateProductsWorkflow, 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.

OptionHow it uses Odoo dataSync needed
Odoo eCommerce appBuilt into Odoo, with orders, stock, and invoicing handled in OdooNo
Shopify with OdooThird-party connector or iPaaSYes. Check vendor docs
Medusa with OdooCustom Medusa module from the official guideYes, 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.