OdooWebApps.com

Why Your Odoo API Call Returns Data From the Wrong Company (and How to Scope It Correctly)

Published September 19, 2026

What's the actual gotcha here?

A recurring one, documented across plenty of Odoo community forum threads: when you call Odoo's external API (XML-RPC or JSON-RPC) as a user who has access to multiple companies, a query can quietly return records from every company that user is allowed to see, not just the one company your integration meant to query. It doesn't throw an error or warn you; the call just succeeds and hands back more data than intended.

Why does this happen at all?

Because company scoping in Odoo isn't automatically inferred from "which company does this record belong to" on every read; it's governed by context. A multi-company user's session context determines which companies' records are visible to them at all, and unless a request explicitly narrows that further, an API call runs with the same broad visibility that user would have anywhere else in Odoo. It's consistent with how Odoo's access rules work generally, but it's easy to overlook if you're assuming an API call for "this company's sales orders" is automatically scoped that way by default.

How do you actually scope a request to one company?

Two real, complementary mechanisms. One is passing the allowed_company_ids context key on the call, which constrains which companies' records the request can see for that specific call. The other is adding an explicit domain filter on the company_id field of the model you're querying, so the query itself states which company's records it wants rather than relying on ambient context. Using an explicit domain filter on company_id is generally the more defensive of the two, since it makes the intended scope part of the query itself rather than something set elsewhere and easy to forget.

Why is this easy to miss in a one-off script?

Because it often works perfectly fine in testing. If the user credentials used during development only have access to one company, or the test data doesn't have overlapping records across companies, an unscoped query returns exactly what you expect, and the missing company filter never surfaces as a bug until the integration runs against a real multi-company account or a second company is added to the setup later.

What's the actual risk if it's missed?

Data leaking across company boundaries inside your own integration: a dashboard showing figures blended across companies that should have stayed separate, a report meant for one entity quietly including another's orders or invoices, or a write-back action operating against the wrong company's records entirely. For a multi-company business, that's not a cosmetic bug; it can mean genuinely incorrect numbers being acted on.

Why does this matter for a properly built app versus a quick script?

Because it's exactly the kind of small, easy-to-skip detail that a one-off integration script written quickly is likely to miss, and that a properly scoped, tested app is built to get right from the start. If your Odoo setup involves more than one company at all, this is worth confirming explicitly for every model any integration touches, rather than assuming the default behavior already does the right thing.

Want this looked at for your setup?

Every Odoo instance is configured a little differently. Tell us what you're working with and we'll give you a straight answer.