Odoo connector: let staff query sales, stock and receivables in plain language
This page is for the Odoo administrator or partner who will connect a company database to OrgRelay. After reading it you will know which Odoo models the AI reads, which two actions wait for an approver, and how to create a narrowly scoped integration user and API key.
What staff can ask
The connector maps everyday questions onto a small set of standard tools. A few examples from a typical sales and purchasing team:
- "Which quotations for Lumen Trading are still in draft?" calls
orders.searchwithstatus: draftandcustomer: Lumen. - "What's on S00412?" calls
orders.getwithorder_no: S00412and returns the order lines with product, quantity and subtotal. - "Which SKUs will go negative once current orders ship?" calls
inventory.listwithlow_only: true. That filter uses Odoo's forecast quantity (virtual_available), so incoming and outgoing moves are already counted. - "Who owes us money past the due date?" calls
finance.receivableswithoverdue_only: true. - "Draft a PO to supplier 57 for 200 units of CHAIR-OAK at 38.50." calls
purchase.create, which stops at an approval card before anything is written.
Staff only see these tools if the owner has granted the Odoo connection to their role. Sales staff often get the read tools only, while purchasing gets purchase.create as well.
Tools
| Tool | Access | What it does | Key parameters |
|---|---|---|---|
orders.search |
read | Searches sale.order, newest first |
status (draft, sent, sale, done, cancel), customer, date_from, date_to, limit, cursor |
orders.get |
read | One sales order with its sale.order.line rows |
order_no (for example S00012), required |
products.search |
read | Searches product.product by name or internal reference, with list price and category |
keyword (name or SKU) |
inventory.list |
read | On-hand (qty_available) and forecast (virtual_available) quantity for goods products |
sku, low_only |
customers.search |
read | Searches res.partner by name or email; without a keyword lists partners with a customer rank |
keyword |
finance.receivables |
read | Posted customer invoices (out_invoice) that are not paid or partly paid, with days overdue |
overdue_only |
purchase.search |
read | Searches purchase.order by vendor and state |
supplier, status (draft, sent, purchase, done, cancel) |
purchase.create |
write · approval | Creates a draft purchase order; never confirms it | supplier_id (partner ID), lines of {sku, qty, unit_price?}, note |
customers.add_note |
write · approval | Posts an internal note (subtype mail.mt_note) in the partner's chatter |
customer_id, note |
Every list tool takes limit (default 20, maximum 100) and cursor. The cursor is an offset into search_read, ordered by id desc. Searches use Odoo domains under the hood. For example, a customer filter becomes ['partner_id.name', 'ilike', ...], so partial names match. The output shape follows the connector spec, so a sales order from Odoo looks the same to the AI as one from Shopify or WooCommerce.
Credentials and scopes
The connection form has four required fields and one advanced field:
- Odoo URL, for example
https://yourcompany.odoo.com. - Database. On odoo.com this is usually the subdomain. On a self-hosted server with several databases, check the database manager.
- Login (email) of the Odoo user the AI acts as.
- API key for that user. It is stored encrypted and only the last four characters are shown afterwards. The authentication overview explains how OrgRelay handles keys of this kind.
- API protocol (advanced):
auto,json2orjsonrpc. Leave it onauto. OrgRelay then probes/json/2/res.users/search_readonce per database. If the server returns 404, it uses/jsonrpcwithcommon.authenticateandobject.execute_kw; otherwise it sends JSON-2 calls withAuthorization: bearer <key>and theX-Odoo-Databaseheader. Forcejsonrpconly if a proxy in front of Odoo blocks the JSON-2 path.
Odoo has no OAuth scopes for this API. The key carries exactly the access rights of its user: groups, record rules and multi-company rules all apply. That makes the user you choose the real permission boundary. Create a dedicated internal user, give it only the apps it needs (Sales, Inventory, Invoicing or Accounting, Purchase) and read-only groups where Odoo offers them. Leave purchase rights off if you never want purchase.create to succeed, even after approval.
Multi-company databases need one extra thought. The connector does not send an allowed_company_ids context, so Odoo uses all companies the user is allowed in. Reads span those companies, and a draft PO lands in the user's default company. To keep the AI inside one company, restrict the integration user to that company.
Key lifetime depends on your Odoo version. The Odoo 19 external API documentation says a key needs a description and a duration, and that keys cannot last more than three months. Plan to rotate before the expiry date: create the new key, update it in the OrgRelay connection, then revoke the old one in Odoo. An expired key shows up as an access-denied error that names the three-month limit.
Which actions need approval and what the approver sees
Two tools change data, and both go through approvals:
purchase.create. The approver sees the supplier ID, each SKU with quantity and optional unit price, and the note. When approved, the connector looks up each SKU againstdefault_code, buildsorder_linecommands and creates thepurchase.order. Odoo assigns the PO number (P000xx), and the result reports it. The order stays in the RFQ/draft state. Someone in purchasing still has to confirm it, which is when Odoo would create receipts. If a SKU is not found, the call fails before anything is created.customers.add_note. The approver sees the partner ID and the full note text. The note is posted as an internal note, so followers outside the company are not emailed.
Unit prices left blank are filled by Odoo's own logic, such as vendor pricelists. Approvers should check the supplier ID carefully, because the tool takes an ID, not a name. Running customers.search first and pasting the ID into the request avoids mistakes. The human-in-the-loop pattern explains why OrgRelay asks before writes instead of reviewing them afterwards.
Set it up
- On Odoo Online, confirm the database is on the Custom plan. Then create an internal user for OrgRelay and set its access rights as described above. On multi-company databases, limit its allowed companies.
- Sign in as that user and open Preferences → Account Security → New API Key. Name it OrgRelay, pick the longest duration your policy allows (three months at most on Odoo 19) and copy the key. Odoo shows it once. Put a reminder in the calendar for the renewal.
- Note the database name and the base URL.
- In OrgRelay, go to Admin → Business systems → App directory, choose Odoo, fill in URL, database, login and API key, and click Connect. OrgRelay checks the login, records which protocol the server answered on, and shows the user name and company it connected as.
- Grant the connection to the roles that need it and switch off any tools you don't want. For example, turn off
customers.add_noteif the chatter must stay human-only. - Ask a test question such as "show five draft quotations" and check the result against Odoo.
The quickstart covers the same bind-and-test flow for custom connectors, if you also plan to connect an in-house system.
Limits and things it deliberately does not do
- Plan requirement on Odoo Online. Odoo's external API page states that external API access is only available on Custom plans. One App Free and Standard databases will reject the connection.
- Version. The connector works with Odoo 14 and later on Online, Odoo.sh or self-hosted. Odoo 19 and later are reached through JSON-2, older versions through
/jsonrpcas described in the Odoo 17 external API reference, so the same connection keeps working when Odoo removes the old endpoints in Odoo 22 and Odoo Online 21.1. - No rate limit is published by Odoo for the external API. OrgRelay applies its own cap of 120 calls per minute per connection and pauses for 60 seconds after three consecutive failures.
- Not exposed: confirming or cancelling orders, validating pickings, posting or paying invoices, editing products or prices, accounting journals, HR, manufacturing and custom models. If you need a custom model, describe it in a small connector of your own, built from the examples.
- Prices in
products.searchare the product's list price without currency. Order and invoice amounts carry the record's currency. - Large answers are cut to about 12,000 characters for the AI, so ask for narrower date ranges rather than raising
limit. - Trial databases. A free Odoo trial database is a safe place to try approvals before you point the connection at production.
Official MCP server and OrgRelay
Odoo's developer documentation does not describe a first-party MCP server. The official vendor servers page lists the vendors that do publish one. The Odoo Apps store lists several MCP modules from third-party publishers for versions 14 to 20. They install inside Odoo and expose models through an /mcp endpoint. If your partner has already installed one, OrgRelay can connect it as a third-party MCP server, next to or instead of this connector, provided it speaks the Streamable HTTP transport and accepts a bearer key or OAuth client credentials. Modules that only offer an interactive OAuth 2.1 sign-in do not fit that connection type.
What OrgRelay adds is the same whichever route you pick. Tools are granted per role and per department. Every write waits for an approver, and one audit log records Odoo calls alongside QuickBooks, HubSpot or any other system. All of it runs on the company's own Mac mini, where the API key is stored encrypted. The security model describes the encryption and audit details. The enterprise patterns page compares the two approaches in more detail, and the security overview covers how keys are stored.
Common questions
Does the Odoo connector work on Odoo Online Standard plans? Odoo's own documentation says external API access is only available on Custom pricing plans, not on One App Free or Standard. Self-hosted and Odoo.sh databases are not affected by that plan rule.
Which API does the connector call, XML-RPC, JSON-RPC or JSON-2?
By default it tries JSON-2 first (POST /json/2/<model>/<method> with a bearer API key) and falls back to /jsonrpc when the server answers 404, which is the case before Odoo 19. JSON-2 support requires OrgRelay 1.4.0 or later. Odoo lists /xmlrpc and /jsonrpc for removal in Odoo 22 (fall 2028) and Odoo Online 21.1 (winter 2027).
Can the AI confirm a purchase order or post an invoice?
No. The only Odoo writes are purchase.create, which creates a purchase order in draft, and customers.add_note, which posts an internal note. Confirming, receiving and invoicing stay in Odoo.