odoo json rpc

Odoo Json Rpc — a Practitioner’s Honest Breakdown

⏱ 18 min readLongform

Key Metric

Data-Driven Insights on Odoo Json Rpc

Organizations implementing Odoo Json Rpc achieve up to a 3.5x ROI within 90 days. Structured frameworks cut operational friction by up to 40%.

3.5xAverage ROI
40%Less Friction
90dTo Results

Odoo Json Rpc: Understanding the Odoo JSON-RPC Protocol

The **Odoo JSON-RPC** protocol serves as the primary mechanism for external applications to interact with an Odoo instance programmatically. It adheres to the JSON-RPC 2.0 specification, providing a stateless, remote procedure call (RPC) mechanism that uses JSON for data encoding.

This standardized approach simplifies communication, allowing diverse programming languages and platforms to seamlessly send requests and receive responses from Odoo’s backend. At its core, a JSON-RPC request consists of a method name to be invoked, parameters for that method, and a unique identifier.

Odoo’s **Odoo JSON-RPC** implementation differentiates between two primary service endpoints: `/jsonrpc/2/common` and `/jsonrpc/2/object`. The `common` endpoint is primarily used for database-related operations and authentication, such as listing available databases or performing user logins.

In contrast, the `object` endpoint is dedicated to interacting with Odoo’s business logic, allowing external applications to call methods on Odoo models, effectively performing CRUD (Create, Read, Update, Delete) operations on records or executing custom model methods. This clear separation of concerns ensures a structured approach to API interaction, enhancing both security and maintainability for developers.

A typical **Odoo JSON-RPC** request structure includes `jsonrpc` (always “2.0”), `method` (e.g., “call”), `params` (an object containing specific arguments), and `id` (a unique request identifier). For instance, an authentication request to the `common` endpoint might specify the `login` method within its `params`.

The corresponding response will either contain a `result` field with the requested data (like a session ID or user ID) or an `error` field detailing any issues encountered during processing. Understanding this fundamental request-response cycle is paramount for any developer looking to build reliable integrations with Odoo, as it forms the bedrock of all subsequent interactions with the system’s data and business logic.

Actionable Insight: When initiating any Odoo JSON-RPC integration, always begin by thoroughly reviewing the Odoo source code for the specific model or method you intend to call. This practice helps clarify expected parameters, return types, and potential exceptions, significantly streamlining your development process and minimizing debugging efforts.

Relying solely on assumptions can lead to unexpected behavior or security vulnerabilities. Direct code inspection is a critical first step in robust integration development.

Odoo Json Rpc: Authenticating With Odoo JSON-RPC

Establishing a secure connection is the first critical step when interacting with **Odoo JSON-RPC**. Authentication primarily occurs through the `/jsonrpc/2/common` endpoint, utilizing the `login` method. This method requires the database name (`db`), the user’s login (`login`), and their password (`password`) as parameters.

Upon successful authentication, Odoo returns a user ID (UID) and, crucially, sets a session ID cookie.

This session ID is vital for subsequent requests to the `/jsonrpc/2/object` endpoint, as it maintains the authenticated state across multiple API calls. It eliminates the need to re-authenticate for every operation. Your client-side application must correctly handle and store this session cookie, ensuring it is included in the headers of all subsequent requests to the `object` endpoint.

Failure to manage the session cookie properly will result in authentication errors, as Odoo will not recognize the user’s authenticated state for data operations.

Here’s a simplified Python example demonstrating a login request using **Odoo JSON-RPC**:


import requests
import json

url = "http://localhost:8069/jsonrpc/2/common"
headers = {'Content-Type': 'application/json'}
data = {
 "jsonrpc": "2.0",
 "method": "call",
 "params": {
 "service": "common",
 "method": "login",
 "args": ["your_database_name", "your_username", "your_password"]
 },
 "id": 1
}

response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
 result = response.json()
 if 'result' in result:
 print(f"Login successful. User ID: {result['result']}")
 # The session cookie is automatically handled by requests library
 # For other clients, you'd extract and store it from response headers
 elif 'error' in result:
 print(f"Login failed: {result['error']['message']}")
else:
 print(f"HTTP Error: {response.status_code}")
 

Actionable Insight: When connecting Odoo JSON-RPC from an external application, prioritize secure credential management. Avoid hardcoding usernames and passwords directly into your application code. Instead, use environment variables, secure configuration files, or dedicated secret management services.

For browser-based applications, ensure session cookies are marked `HttpOnly` and `Secure` to mitigate cross-site scripting (XSS) attacks and ensure transmission over HTTPS, enhancing security.

Odoo Json Rpc: Executing Odoo Model Methods Via JSON-RPC

Once authenticated, the real power of the **Odoo JSON-RPC** API becomes accessible through the `/jsonrpc/2/object` endpoint. This endpoint allows external applications to interact directly with Odoo’s ORM (Object-Relational Mapping), enabling the execution of any public method defined on an Odoo model.

The primary method used here is `execute_kw`, which serves as a versatile gateway to Odoo’s business logic. It requires several key parameters: the database name (`db`), the authenticated user’s ID (`uid`), the user’s password (`password`), the Odoo model name (`model`), the method to be called on that model (`method`), and two lists for arguments: `args` (positional arguments) and `kwargs` (keyword arguments).

Common operations performed via `execute_kw` include standard CRUD functionalities. For instance, creating a new record involves calling the `create` method on a specific model, passing a dictionary of field values in the `args`. Reading records is typically done using the `search_read` method, which allows you to specify a domain (filter criteria), fields to retrieve, and pagination options (limit, offset).

Updating existing records utilizes the `write` method, requiring record IDs and a dictionary of updated field values. Deleting records is straightforward with the `unlink` method, taking a list of record IDs.

Consider an example of reading partner records from the `res.partner` model:


import requests
import json

# Assuming you have a valid session from a previous login
session = requests.Session()
# ... perform login and get session cookie into 'session' object ...

url_object = "http://localhost:8069/jsonrpc/2/object"
headers = {'Content-Type': 'application/json'}
db_name = "your_database_name"
uid = 2 # Example UID from login, or obtained from session
password = "your_password" # Still needed for object calls

# Example: Read all partners with 'Customer' tag
read_data = {
 "jsonrpc": "2.0",
 "method": "call",
 "params": {
 "service": "object",
 "method": "execute_kw",
 "args": [
 db_name,
 uid,
 password,
 "res.partner", # Model name
 "search_read", # Method to call
 [
 [['is_company', '=', True]] # Domain: filter for companies
 ],
 {
 "fields": ["name", "email", "phone"], # Fields to retrieve
 "limit": 5,
 "offset": 0
 }
 ]
 },
 "id": 2
}

response = session.post(url_object, headers=headers, data=json.dumps(read_data))
if response.status_code == 200:
 result = response.json()
 if 'result' in result:
 print("Retrieved Partners:")
 for partner in result['result']:
 print(f"- Name: {partner.get('name')}, Email: {partner.get('email')}, Phone: {partner.get('phone')}")
 elif 'error' in result:
 print(f"Error reading partners: {result['error']['message']}")
else:
 print(f"HTTP Error: {response.status_code}")
 

Actionable Insight: For efficient data retrieval using Odoo JSON-RPC, always specify the `fields` parameter in your `search_read` calls. Requesting only the necessary fields reduces the data payload transferred over the network and improves performance. Furthermore, use `domain` filters to fetch only relevant records.

Utilize `limit` and `offset` for pagination, especially with large datasets, to prevent overwhelming your client application and the Odoo server.

Integrating Odoo JSON-RPC With JavaScript Frontends

Connecting a modern JavaScript frontend application to Odoo via **Odoo JSON-RPC** is a common and powerful integration pattern, enabling dynamic, custom user interfaces. The primary challenge involves managing HTTP requests, handling session cookies, and addressing Cross-Origin Resource Sharing (CORS) policies.

Frontend frameworks like React, Vue, or Angular can interact with Odoo using standard browser APIs like `fetch` or libraries such as `axios` to send JSON-RPC requests.

When making requests from a browser, configure your HTTP client to send and receive cookies. The `fetch` API requires setting `credentials: ‘include’` in the request options, while `axios` achieves this with `withCredentials: true`. This ensures the session cookie established during login is automatically sent with subsequent requests, maintaining the authenticated state.

Without this, every request to the `/jsonrpc/2/object` endpoint will fail due to a lack of authentication.

CORS is another significant consideration. If your JavaScript frontend is hosted on a different domain or port than your Odoo instance, the browser’s same-origin policy will block requests unless Odoo is configured to allow them. This involves adding your frontend’s origin to Odoo’s `web.cors.origins` system parameter.

Proper CORS configuration is essential for your browser-based application to communicate with Odoo.

Here’s a basic JavaScript example using `fetch` for an **Odoo JSON-RPC JavaScript** integration:


async function odooLogin(db, username, password) {
 const url = "http://localhost:8069/jsonrpc/2/common";
 const payload = {
 jsonrpc: "2.0",
 method: "call",
 params: {
 service: "common",
 method: "login",
 args: [db, username, password]
 },
 id: 1
 };

 try {
 const response = await fetch(url, {
 method: 'POST',
 headers: {
 'Content-Type': 'application/json',
 },
 body: JSON.stringify(payload),
 credentials: 'include' // Essential for sending/receiving cookies
 });

 if (!response.ok) {
 throw new Error(`HTTP error! status: ${response.status}`);
 }

 const data = await response.json();
 if (data.result) {
 console.log("Login successful. UID:", data.result);
 return data.result; // Returns UID
 } else if (data.error) {
 throw new Error(`Odoo Login Error: ${data.error.message}`);
 }
 } catch (error) {
 console.error("Login failed:", error);
 throw error;
 }
}

async function odooSearchRead(db, uid, password, model, domain, fields) {
 const url = "http://localhost:8069/jsonrpc/2/object";
 const payload = {
 jsonrpc: "2.0",
 method: "call",
 params: {
 service: "object",
 method: "execute_kw",
 args: [
 db,
 uid,
 password,
 model,
 "search_read",
 [domain],
 { fields: fields }
 ]
 },
 id: 2
 };

 try {
 const response = await fetch(url, {
 method: 'POST',
 headers: {
 'Content-Type': 'application/json',
 },
 body: JSON.stringify(payload),
 credentials: 'include' // Essential for sending/receiving cookies
 });

 if (!response.ok) {
 throw new Error(`HTTP error! status: ${response.status}`);
 }

 const data = await response.json();
 if (data.result) {
 console.log("Search Read successful:", data.result);
 return data.result;
 } else if (data.error) {
 throw new Error(`Odoo Search Read Error: ${data.error.message}`);
 }
 } catch (error) {
 console.error("Search Read failed:", error);
 throw error;
 }
}

// Example usage:
// (async () => {
// try {
// const uid = await odooLogin("your_database_name", "your_username", "your_password");
// if (uid) {
// const partners = await odooSearchRead("your_database_name", uid, "your_password", "res.partner", [], ["name", "email"]);
// console.log("Partners:", partners);
// }
// } catch (e) {
// console.error("Overall process failed:", e);
// }
// })();
 

Actionable Insight: When building a JavaScript frontend, implement robust error handling and provide clear UI feedback for Odoo JSON-RPC calls. Catch network errors, parse Odoo’s error responses (which include `code`, `message`, and `data`), and display user-friendly messages. This proactive approach improves the user experience and simplifies debugging.

Developers can quickly identify and resolve issues arising from API interactions or Odoo’s backend validations.

Advanced Odoo JSON-RPC Operations and Error Handling

Beyond basic CRUD operations, Odoo JSON-RPC supports advanced features that enhance the performance and reliability of your integrations. One such feature is batch requests, allowing you to send multiple RPC calls within a single HTTP request. This reduces network overhead and latency, especially beneficial for applications needing several independent operations quickly.

To execute batch requests, send an array of JSON-RPC request objects in the body of a single POST request to the `/jsonrpc/2/object` endpoint.

Odoo will process each request individually and return an array of responses, corresponding to the order of the original requests. Understanding and effectively handling Odoo’s error responses is paramount for building resilient applications. When an Odoo JSON-RPC call fails, the response will contain an `error` object instead of a `result`.

This `error` object typically includes three key fields: `code` (an integer error code), `message` (a human-readable description of the error), and `data` (a detailed object containing more specific information, such as the Python exception type, traceback, and context).

For example, a batch request might look like this:


[
 {
 "jsonrpc": "2.0",
 "method": "call",
 "params": {
 "service": "object",
 "method": "execute_kw",
 "args": [
 "your_database_name",
 uid,
 "your_password",
 "res.partner",
 "create",
 [{ "name": "New Partner 1" }]
 ]
 },
 "id": 1
 },
 {
 "jsonrpc": "2.0",
 "method": "call",
 "params": {
 "service": "object",
 "method": "execute_kw",
 "args": [
 "your_database_name",
 uid,
 "your_password",
 "res.partner",
 "search_read",
 [[["is_company", "=", True]]],
 {"fields": ["name"]}
 ]
 },
 "id": 2
 }
]
 

The `data` field is particularly useful for debugging, as it often provides the exact Odoo exception that occurred, like `AccessError` for permission issues or `ValidationError` for data integrity problems. Handling errors effectively involves parsing the `error` object and implementing conditional logic based on the `code` or the exception type found in `data`.

For instance, an `AccessError` might prompt a re-authentication attempt or a message indicating insufficient permissions. Logging these errors comprehensively, including the full `data` payload, is crucial for post-mortem analysis and system maintenance.

Actionable Insight: Implement a centralized error logging and reporting mechanism for all Odoo JSON-RPC interactions. Capture the full `error` object, especially the `data` field, which contains valuable traceback information. This detailed logging allows for quick identification of recurring issues and helps diagnose complex problems.

It provides necessary context for Odoo administrators or developers to resolve backend exceptions, leading to a more stable integration.

Extending Odoo With Custom Web Controllers for JSON-RPC

While direct interaction with Odoo models via `execute_kw` is powerful, creating custom web controllers for **Odoo JSON-RPC** endpoints offers significant advantages. Custom controllers expose tailored APIs, encapsulate complex business logic, perform specific data transformations, and implement fine-grained access control.

This approach is useful when you need a simplified interface for external systems, aggregate data from multiple models, or implement custom validation rules. It allows for custom logic before interacting with the Odoo ORM.

To create a custom JSON-RPC controller in Odoo, define a Python class that inherits from `http.Controller` within an Odoo module. Methods within this controller are decorated with `@http.route` to define the URL path and `@http.json_rpc` to specify JSON-RPC accessibility. The `@http.json_rpc` decorator automatically handles JSON parsing of the request body and serialization of the response.

Inside your controller method, you have full access to the Odoo environment (`request.env`), allowing interaction with any Odoo model, execution of SQL queries, or calling other Python functions.

Here’s an example of a custom **Odoo web controllers** for JSON-RPC:


# my_custom_module/controllers/main.py
from odoo import http
from odoo.http import request

class CustomJsonRpcController(http.Controller):

 @http.route('/my_custom_api/get_partner_info', type='json', auth='user', methods=['POST'])
 def get_partner_info(self, partner_id):
 # The 'type="json"' argument automatically sets up JSON-RPC handling
 # 'auth="user"' ensures the user is logged in
 
 if not partner_id:
 return {'error': 'Partner ID is required.'}

 partner = request.env['res.partner'].sudo().browse(partner_id)
 if not partner.exists():
 return {'error': 'Partner not found.'}

 # Example of custom logic: fetch specific fields and format
 return {
 'id': partner.id,
 'name': partner.name,
 'email': partner.email,
 'phone': partner.phone,
 'is_company': partner.is_company,
 'salesperson': partner.user_id.name if partner.user_id else False
 }

 @http.route('/my_custom_api/create_simple_partner', type='json', auth='user', methods=['POST'])
 def create_simple_partner(self, name, email=False):
 if not name:
 return {'error': 'Name is required to create a partner.'}
 
 try:
 new_partner = request.env['res.partner'].sudo().create({'name': name, 'email': email})
 return {'success': True, 'partner_id': new_partner.id, 'message': f"Partner '{name}' created successfully."}
 except Exception as e:
 request.env.cr.rollback() # Rollback transaction on error
 return {'success': False, 'error': str(e)}

 

Actionable Insight: When designing custom Odoo web controllers for JSON-RPC, prioritize security and performance. Always implement robust input validation to prevent malicious data injection and ensure data integrity. Apply appropriate access control (`auth=’user’`, `auth=’public’`) and use `sudo()` judiciously, or implement record rules.

Optimize database queries within your controller methods and avoid fetching unnecessary data, ensuring your custom endpoints remain efficient and secure.

Frequently Asked Questions About Odoo JSON-RPC

What is the difference between Odoo JSON-RPC and XML-RPC?

Odoo supports both JSON-RPC and XML-RPC protocols for external API communication. The fundamental difference lies in their data encoding format: JSON-RPC uses JSON (JavaScript Object Notation), while XML-RPC uses XML (Extensible Markup Language). JSON is generally more lightweight and human-readable, making it a preferred choice for modern web applications, especially those built with JavaScript.

XML-RPC, being an older standard, might be used for legacy system integrations. Functionally, both protocols allow you to call Odoo methods, but JSON-RPC often offers better performance and easier parsing in contemporary development environments.

How do I handle file uploads/downloads using Odoo JSON-RPC?

Handling file uploads and downloads with Odoo JSON-RPC typically involves base64 encoding. For uploads, read the file content, encode it into a base64 string, and then pass this string as a field value (e.g., `datas` for `ir.attachment`) in a `create` or `write` call to the relevant Odoo model.

For downloads, retrieve the base64 encoded content from Odoo (e.g., the `datas` field of an `ir.attachment` record), decode it on your client side, and then serve it as a file. Manage the base64 encoding/decoding efficiently to avoid performance issues with large files.

Is Odoo JSON-RPC secure for public-facing applications?

Odoo JSON-RPC can be secure for public-facing applications if implemented with proper security measures. Key considerations include always using HTTPS to encrypt data in transit, implementing strong authentication (e.g., OAuth 2.0 if applicable, or robust session management), and carefully managing user permissions (access rights) within Odoo.

For public-facing endpoints, consider creating custom web controllers with `auth=’public’` and implementing your own token-based authentication and strict input validation. Never expose sensitive Odoo model methods directly without adequate security layers, and regularly audit your API for vulnerabilities.

Can I use Odoo JSON-RPC with Odoo Online (SaaS)?

Yes, Odoo JSON-RPC is fully compatible with Odoo Online (SaaS) instances. The principles and methods for authentication and interaction remain the same as with self-hosted Odoo instances. You will need to use your Odoo Online instance’s URL as the base for your JSON-RPC endpoints (e.g., `https://your-company.odoo.com/jsonrpc/2/common`).

Ensure that any external applications connecting to Odoo Online adhere to Odoo’s terms of service and best practices for API usage, including rate limiting and efficient data retrieval, to maintain optimal performance and avoid service interruptions.

What are common pitfalls when implementing Odoo JSON-RPC?

Common pitfalls include incorrect session management (not sending cookies with subsequent requests), misconfigured CORS headers preventing browser-based applications from connecting, incorrect parameter types or order in `execute_kw` calls, and inadequate error handling. Developers often struggle with understanding Odoo’s domain syntax for filtering records or correctly mapping complex data structures.

Additionally, neglecting security best practices, such as hardcoding credentials or exposing too much functionality, can lead to significant vulnerabilities. Thorough testing and detailed error logging are crucial for mitigating these issues.

How does Odoo JSON-RPC handle multi-company environments?

In a multi-company Odoo environment, the JSON-RPC API respects the user’s active company context. When an authenticated user makes an API call, Odoo automatically filters records and applies business logic based on the company currently set for that user’s session. If you need to perform operations across different companies, you can explicitly pass the `company_id` in the context of your `execute_kw` call’s keyword arguments (e.g., `{‘context’: {‘company_id’: 1}}`).

This allows you to programmatically switch context and interact with data belonging to specific companies within your multi-company setup.

What are the performance implications of frequent Odoo JSON-RPC calls?

Frequent Odoo JSON-RPC calls can impact performance due to network latency, server processing overhead, and database query load. Each call incurs a round trip to the server, and complex operations can consume significant server resources. To mitigate this, utilize batch requests for multiple operations, optimize your `search_read` calls by specifying only necessary fields and precise domains, and implement caching strategies on your client side for static or infrequently changing data.

For very high-volume scenarios, consider custom controllers that aggregate data efficiently or explore Odoo’s message queue system for asynchronous processing.

Conclusion

The **Odoo JSON-RPC** API stands as a cornerstone for extending and integrating Odoo with virtually any external system or custom application. Its adherence to the JSON-RPC 2.0 standard, coupled with Odoo’s robust ORM, provides developers with a powerful and flexible toolkit. From securely authenticating users and performing intricate CRUD operations on Odoo models to developing custom web controllers, Odoo JSON-RPC offers the flexibility needed for sophisticated web integrations.

By mastering the concepts and techniques outlined in this guide, developers can confidently build robust, scalable, and secure applications that interact seamlessly with Odoo. The ability to connect Odoo JSON-RPC with external systems unlocks new possibilities for tailored user experiences and automated workflows.

Continue exploring Odoo’s official documentation and community forums to deepen your understanding and discover advanced integration patterns.

Frequently Asked Questions

What is the core benefit of Odoo Json Rpc?

Implementing Odoo Json Rpc strategically lets organizations scale efficiently, driving measurable ROI and reducing daily friction.

How quickly can I see results from Odoo Json Rpc?

Initial improvements are visible within 14-30 days. Comprehensive benefits compound over 60-90 days.

Is Odoo Json Rpc suitable for small businesses?

Yes. Solutions are highly scalable and most impactful for small to mid-size businesses seeking growth.


Leave a Reply

Your email address will not be published. Required fields are marked *