AI Summary - 20-sec read - Reviewed by experts
- If your Odoo runs the business but your website, marketplace, logistics, or payment tools live in their own silos, someone is re-keying data or nursing brittle CSV exports - and that is where stock counts and invoices drift apart.
- Odoo exposes an external API over XML-RPC and JSON-RPC that lets outside systems read and write the same records your staff use - search_read to pull, create and write to push - so the two systems stay in step automatically.
- Four things decide whether an integration is stable or a mess: authenticate with a dedicated API user and key (never a person's admin login), match records by an external ID rather than by name, respect Odoo's data model and required fields, and handle rate limits with batching and retries.
- Reach for the API only when Odoo's own scheduled actions and automation rules cannot do the job in-database - a lot of 'integration' work is better and safer done inside Odoo itself.
- Short on time? We will map what needs to sync, build it on the Odoo API the right way, and stop the double entry. Book a free call.
Short on time? Book a free call.
Your team lives in Odoo - sales orders, stock, invoices, GST - but the storefront, the marketplace seller panel, the courier's dashboard, and the payment gateway all sit outside it. So every day someone copies an order from Shopify into Odoo, exports a stock file to upload to Amazon, and pastes tracking numbers back by hand. Each hop is slow, and each one is where a number goes wrong - Odoo says 40 in stock, the website oversells to 45, and now you are cancelling orders. Odoo has an external API built exactly to end this. The trick is using it the way that stays stable at volume, not the way that quietly creates duplicates.
How you reach Odoo from outside: XML-RPC and JSON-RPC
Odoo ships an external API that any other system can call over the network. It comes in two flavours that do the same job in different wire formats:
- XML-RPC is the long-standing interface, supported by every Odoo version and by ready-made client libraries in Python, PHP, Java and more. If you are wiring up a server-side integration, this is usually the path of least resistance.
- JSON-RPC exposes the same models and methods over JSON, which is friendlier for JavaScript and modern HTTP tooling. Same capabilities, different envelope.
Either way, you authenticate once, then call methods on Odoo's models. The handful you will use most: 'search_read' to pull records with a filter, 'create' to insert a new one, 'write' to update, and 'unlink' to delete. A storefront-to-Odoo order sync, at its core, is just 'search_read' on stock going out to the website and 'create' on sale orders coming back in. You are not scraping screens or hitting an undocumented endpoint - you are using the same data model your staff use, over the wire.
Still copying orders and stock between Odoo and your other tools by hand?
We will map exactly what needs to flow each way, then build it on Odoo's API so the systems stay in step without anyone re-keying. No pitch, reply in 2 hrs, no card needed, NDA on request.
Get a free auditThe four things every Odoo integration must get right
A working proof-of-concept and a stable production integration are different animals. These four decisions are what separate them - get them wrong and you get duplicates, security holes, and 3am pager calls.
- Authenticate with a dedicated integration user and an API key. Do not hard-code a real person's login, and do not use the admin account. Create a specific integration user, give it only the access it needs, and use an API key rather than a password so you can revoke it without locking anyone out. Scope its rights deliberately - the same access rights and record rules that govern your staff apply to the API, and an over-privileged integration user is a real risk.
- Match records by external ID, never by name. When you push a Shopify order into Odoo, store the Shopify order reference against the Odoo record and check for it before you create. Match on a stable external ID and a re-run finds the existing record and updates it instead of making a second one. This one habit prevents the classic integration failure: a retried sync that double-posts every order.
- Respect the data model. Odoo records have required fields, and links between records - a sale order line needs a product that exists, a partner needs a country for a valid GST record. Related fields for one-to-many and many-to-many use command tuples, not plain values. Read how the model is shaped before you write to it, or your 'create' calls will fail validation in ways that are confusing from the outside.
- Handle rate and volume. Do not fire one API call per row for a 5,000-line catalogue. Batch reads and writes, add retry-with-backoff for transient failures, and make your sync resumable so a mid-run failure does not leave half the data updated. Idempotent writes keyed on the external ID make retries safe.
One integration that matches records by name instead of ID can duplicate every order you sync.
We build Odoo integrations that authenticate safely, dedupe on external IDs, and retry without double-posting - so the data stays trustworthy. Reply in 2 hrs, NDA on request.
Book a free callAPI or Odoo's own automation - use the right tool
Before you build an external integration, ask whether the job even needs to leave Odoo. A surprising amount of 'integration' work is really automation that Odoo can do inside its own database - faster, with less to maintain, and no network in the middle. If the logic is 'when this Odoo record changes, do that other thing in Odoo', an automation rule or a server action is the right tool, and you should reach for the API only when an outside system is genuinely involved. We cover that split in the guide to scheduled actions, automation rules, and server actions. The external API earns its place when data must move between Odoo and a system it does not control - a storefront, a marketplace like the ones in a multi-channel inventory sync, a courier, a bank - not for logic that could stay in-house.
Takeaways
- Odoo's external API (XML-RPC or JSON-RPC) lets outside systems read and write the same records your staff use - search_read, create, write, unlink.
- Authenticate with a dedicated integration user and an API key scoped to only what it needs, never a person's admin login.
- Match records by a stored external ID, not by name, so a re-run updates instead of duplicating.
- Respect required fields and related-record links, and handle volume with batching, backoff, and idempotent writes.
- Use Odoo's own automation rules and server actions for in-Odoo logic; save the API for systems Odoo does not control.
A safe way to roll it out
Build against a copy of your database first, never straight against live - a bad 'write' loop can touch thousands of records fast. Start with reads to confirm your filters return exactly what you expect, then add writes one record type at a time, checking for duplicates after each. Log every call and its result so that when a sync misbehaves you can see what it actually sent. This is the discipline behind the Odoo integration work we do, and when the job needs a genuinely custom endpoint or transformation, it moves into a proper custom Odoo module rather than a fragile script no one owns.
Frequently asked questions
Do I need to write a custom module to use the Odoo API?
No. The external API is available out of the box - you can read and write records from an outside system using a client library and an API key without touching Odoo's code. You only need a custom module when you want to add your own API endpoint, run server-side logic on Odoo's side, or transform data in ways the standard methods do not cover.
Is the Odoo API safe to expose to the internet?
It is safe when you treat it like any production API: a dedicated integration user with tightly-scoped access rights, an API key you can rotate, HTTPS, and ideally network restrictions on who can reach it. The danger is using the admin account or an over-privileged user - then a leaked key is a full breach. Scope the user down and the exposure is limited to what that user can do.
Why does my integration keep creating duplicate records?
Almost always because it matches on something unstable - a name, an email, a date - or does not check for an existing record at all before calling create. Store the external system's own ID against the Odoo record and search for it first; if it exists, write to it, if not, create it. That single change fixes the large majority of duplicate-record problems.
XML-RPC or JSON-RPC - which should I use?
For most server-side integrations, XML-RPC, because it is universally supported and has mature client libraries in almost every language. Choose JSON-RPC when you are integrating from JavaScript or a stack where JSON is the natural fit. They expose the same models and methods, so the choice is about tooling comfort, not capability.
The short version: if your team is re-keying data between Odoo and your other systems, the fix already exists in Odoo's external API. Call it with a dedicated, scoped user, match records by external ID so re-runs never duplicate, respect the data model, and batch for volume - and reach for it only when the data genuinely has to leave Odoo. Do that and the double entry stops, the stock counts agree, and the systems finally talk to each other.
Leads the Odoo practice at Braincuber. Has delivered Odoo ERP implementations, NetSuite/Tally migrations, and Shopify–Odoo integrations for US mid-market and D2C brands. Owns scoping, data migration, and go-live for every Odoo engagement.
