Welcome to a special deep dive brought to you by Exema Max! In this article, we’ll explore one of the most exciting new features in the latest version of Odoo: the Odoo 19 JSON-RPC API. If you’ve ever wrestled with Odoo integrations, get ready for a breath of fresh air. This new API promises a significantly smoother and more accessible experience for developers.
This guide is inspired by the insightful demonstration by Ignacio, our Director of Technology at XMAX, showcasing the power and simplicity of this new API. You can watch the original Spanish video walkthrough here: https://www.youtube.com/watch?v=FG0K6yaF_nM
Why the Odoo 19 JSON-RPC API is a Game-Changer
For years, developers integrating with Odoo primarily relied on the XML-RPC API. While functional, it often presented a steeper learning curve, particularly for those accustomed to modern web service paradigms. XML-RPC required specific libraries and an understanding of its unique structure, which could feel cumbersome.
The introduction of the Odoo 19 JSON-RPC API marks a pivotal shift. JSON (JavaScript Object Notation) has become the de facto standard for data exchange on the web due to its human-readability and widespread support across virtually all programming languages. This means integrating with Odoo 19 is now dramatically simpler and more intuitive. Developers can leverage standard HTTP requests and native JSON handling, making external application development faster and more efficient. It’s a huge step forward for Odoo’s extensibility and developer experience.
Key Benefits of the New Odoo 19 JSON-RPC API
- Modern Standard: JSON is universally supported and understood, reducing the need for specialized libraries.
- Enhanced Readability: JSON’s clear, hierarchical structure makes requests and responses easy to interpret.
- Simplified Integration: Connect Odoo 19 with external systems, mobile apps, or custom web applications with greater ease.
- Versatility: Perform various operations – search, read, create, update, delete – across Odoo models efficiently.
- Native Support: Unlike XML-RPC, which often felt like an add-on, JSON-RPC feels integrated and native to the Odoo 19 ecosystem.
Understanding the Core Concepts of Odoo 19 JSON-RPC API
Before we dive into the practical steps, let’s briefly touch upon some fundamental concepts crucial for working with the Odoo 19 JSON-RPC API:
- Endpoint: The dedicated URL where your API requests will be sent. For Odoo 19, this is typically
/jason/2appended to your Odoo instance’s base URL. - Models: In Odoo, everything is built around models, which represent different business objects (e.g.,
res.partnerfor contacts,product.templatefor products,sale.orderfor sales orders). When you interact with the API, you specify the model you want to work with. - Methods: These are the actions you want to perform on a model. Common methods include
search(to find records based on criteria),read(to retrieve specific fields of identified records),create,write(update), andunlink(delete). Odoo 19 allows direct calling of these methods. - API Keys (APKs): For secure communication, the Odoo 19 JSON-RPC API utilizes API keys. These are unique tokens generated within Odoo for specific users, serving as a secure authentication mechanism. They replace traditional username/password authentication for API calls, significantly enhancing security.
- Domain Filters: When searching for records, you’ll use Odoo’s powerful domain syntax. This allows you to specify complex criteria to filter results (e.g.,
[('email', '!=', False)]to find records with an email address).
Now, let’s get our hands dirty with a practical, step-by-step tutorial.
Tutorial: Connecting to Odoo 19 JSON-RPC API and Fetching Contacts with Python
This tutorial will guide you through connecting to an Odoo 19 instance and retrieving contact data (res.partner) using the new Odoo 19 JSON-RPC API with Python. We’ll replicate the core logic demonstrated in Ignacio’s video.
Prerequisites:
- An active Odoo 19 instance (Enterprise or a test instance like the one from Odoo Runbot).
- Python 3.x installed on your machine.
- The
requestslibrary for Python. If you don’t have it, install it via pip:pip install requests - Familiarity with basic Python syntax.
Step 1: Generate an API Key (APK) in Odoo 19
The first and most crucial step for secure integration with the Odoo 19 JSON-RPC API is to generate an API key. This key will act as your authentication token.
- Log in to your Odoo 19 instance as an administrator or a user with API access permissions.
- Navigate to Settings > Users & Companies > Users.
- Select the user for whom you want to generate the API key (e.g., your administrator user).
- On the user form, look for the “API Keys” section, often found under the “Security” tab or a similar advanced setting.
- Click “Generate API Key” or “Add API Key.”
- You’ll be prompted to enter the user’s password for confirmation.
- Provide a meaningful description for your API key (e.g., “External CRM Integration,” “Python Script Test”).
- Important: Once generated, Odoo will display the API key only once. Copy this key immediately and store it securely. If you lose it, you’ll have to generate a new one.
Step 2: Python Script Setup
Create a new Python file (e.g., odoo_api_client.py) and start by importing the necessary libraries. The requests library will handle our HTTP communication, and json will help us serialize and deserialize JSON data.
import requests
import json
Step 3: Define API Parameters
Now, let’s set up the essential parameters for connecting to your Odoo 19 instance. Remember to replace the placeholder values with your actual Odoo URL, the API key you just generated, and your Odoo database name.
# --- API Parameters ---
# Replace with your Odoo instance's base URL (e.g., "https://your-odoo.example.com")
# Ensure it ends without a trailing slash if you plan to append paths directly.
base_url = "YOUR_ODOO_INSTANCE_URL"
# The specific JSON-RPC API endpoint for Odoo 19
api_endpoint = base_url + "/jason/2"
# Replace with the API key you generated in Step 1
api_key = "YOUR_API_KEY"
# Replace with your Odoo database name. This is crucial if your Odoo instance hosts multiple databases.
database_name = "YOUR_DATABASE_NAME"
# Headers required for all Odoo 19 JSON-RPC API requests
# The User-Agent header typically carries the API Key for authentication.
headers = {
"Content-Type": "application/json",
"User-Agent": api_key # Odoo uses User-Agent for API key authentication
}
Step 4: Construct the Search Request
Our goal is to fetch contact records that have an email address. The first step in Odoo’s API pattern is often to search for the IDs of the records you’re interested in, and then read their details.
# --- Search Payload: Find IDs of partners with an email ---
search_payload = {
"jsonrpc": "2.0", # JSON-RPC protocol version
"method": "call", # We are calling an Odoo method
"params": {
"model": "res.partner", # The Odoo model we want to query (Contacts)
"method": "search", # The method to execute on the model
# Domain filter: email is not False (i.e., it exists and is populated)
"args": [[("email", "!=", False)]],
"kwargs": {
# You might add context here if needed, e.g., for multi-company
# "context": {"company_id": 1}
}
},
"id": 1 # A unique request ID, useful for matching responses
}
Step 5: Send the Search Request and Process IDs
Now, let’s send this search request to the Odoo 19 JSON-RPC API endpoint. We’ll use requests.post and include our headers and the JSON-serialized payload. Robust error handling is essential for any API integration.
# --- Send Search Request ---
try:
print(f"Sending search request to {api_endpoint}...")
search_response = requests.post(api_endpoint, headers=headers, data=json.dumps(search_payload))
search_response.raise_for_status() # Raises HTTPError for bad responses (4xx or 5xx)
search_result = search_response.json()
if search_result.get("error"):
print("Error during search:", search_result["error"])
exit()
partner_ids = search_result.get("result", [])
if not partner_ids:
print("No partners found with email addresses.")
exit()
print(f"Found {len(partner_ids)} partner IDs.")
except requests.exceptions.RequestException as e:
print(f"An error occurred during the search request: {e}")
exit()
Step 6: Construct the Read Request
Once we have the IDs of the contacts, the next step is to read their actual data. We’ll specify which fields we want to retrieve (name and email in this case).
# --- Read Payload: Fetch details for the found IDs ---
read_payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"model": "res.partner",
"method": "read",
"args": [partner_ids], # Pass the list of IDs obtained from the search
"kwargs": {
"fields": ["name", "email", "id"], # Fields to retrieve
"context": {"lang": "en_US"} # Specify language for context
},
},
"id": 2 # Another unique request ID
}
Step 7: Send the Read Request and Print Results
Finally, send the read request and then iterate through the retrieved partners to print their details. This showcases the seamless data exchange facilitated by the Odoo 19 JSON-RPC API.
# --- Send Read Request ---
try:
print(f"Sending read request for {len(partner_ids)} partners...")
read_response = requests.post(api_endpoint, headers=headers, data=json.dumps(read_payload))
read_response.raise_for_status()
read_result = read_response.json()
if read_result.get("error"):
print("Error during read:", read_result["error"])
exit()
partners = read_result.get("result", [])
print("\n--- Retrieved Partners ---")
for partner in partners:
print(f"ID: {partner['id']}, Name: {partner['name']}, Email: {partner['email']}")
print("--------------------------")
except requests.exceptions.RequestException as e:
print(f"An error occurred during the read request: {e}")
exit()
Step 8: Complete Python Code
Here’s the full script combining all the steps. Remember to replace the placeholder values before running it!
import requests
import json
# --- API Parameters ---
# Replace with your Odoo instance's base URL (e.g., "https://your-odoo.example.com")
base_url = "YOUR_ODOO_INSTANCE_URL"
api_endpoint = base_url + "/jason/2"
# Replace with the API key you generated in Step 1
api_key = "YOUR_API_KEY"
# Replace with your Odoo database name
database_name = "YOUR_DATABASE_NAME"
# Headers required for all Odoo 19 JSON-RPC API requests
headers = {
"Content-Type": "application/json",
"User-Agent": api_key
}
# --- Search Payload: Find IDs of partners with an email ---
search_payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"model": "res.partner",
"method": "search",
"args": [[("email", "!=", False)]], # Domain filter: email is not False
"kwargs": {
# "context": {"company_id": 1} # Example of adding context
}
},
"id": 1
}
# --- Send Search Request ---
try:
print(f"Sending search request to {api_endpoint}...")
search_response = requests.post(api_endpoint, headers=headers, data=json.dumps(search_payload))
search_response.raise_for_status() # Raises HTTPError for bad responses (4xx or 5xx)
search_result = search_response.json()
if search_result.get("error"):
print("Error during search:", search_result["error"])
exit()
partner_ids = search_result.get("result", [])
if not partner_ids:
print("No partners found with email addresses.")
exit()
print(f"Found {len(partner_ids)} partner IDs.")
except requests.exceptions.RequestException as e:
print(f"An error occurred during the search request: {e}")
exit()
# --- Read Payload: Fetch details for the found IDs ---
read_payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"model": "res.partner",
"method": "read",
"args": [partner_ids], # Pass the list of IDs obtained from the search
"kwargs": {
"fields": ["name", "email", "id"], # Fields to retrieve
"context": {"lang": "en_US"} # Specify language for context
},
},
"id": 2
}
# --- Send Read Request ---
try:
print(f"Sending read request for {len(partner_ids)} partners...")
read_response = requests.post(api_endpoint, headers=headers, data=json.dumps(read_payload))
read_response.raise_for_status()
read_result = read_response.json()
if read_result.get("error"):
print("Error during read:", read_result["error"])
exit()
partners = read_result.get("result", [])
print("\n--- Retrieved Partners ---")
for partner in partners:
print(f"ID: {partner['id']}, Name: {partner['name']}, Email: {partner['email']}")
print("--------------------------")
except requests.exceptions.RequestException as e:
print(f"An error occurred during the read request: {e}")
exit()
Important Notes for Working with the Odoo 19 JSON-RPC API
- Replace Placeholders: Double-check that you’ve replaced
"YOUR_ODOO_INSTANCE_URL","YOUR_API_KEY", and"YOUR_DATABASE_NAME"with your actual Odoo instance details. Incorrect values are a common source of connection errors. - Error Handling: The provided script includes basic error handling. For production-grade applications, expand this with more specific error checks, logging, and retry mechanisms. The
raise_for_status()method is a powerful first line of defense against HTTP errors. - Security Best Practices:
- API Key Management: Never hardcode API keys directly into production code. Use environment variables, a secure configuration file, or a secrets management service.
- Least Privilege: Generate API keys for users with the minimum necessary permissions to perform their intended tasks. Don’t use an administrator’s API key for routine integrations if a more restricted user will suffice.
- Odoo Context: The
contextdictionary inkwargsis powerful. It allows you to control various aspects of Odoo’s behavior during an API call, such as the language (lang), user ID, or company ID for multi-company environments. For instance, setting{"lang": "en_US"}ensures data is returned in US English. - Model and Field Names: Always refer to the official Odoo documentation or use Odoo’s developer mode (technical features) to verify the exact model names (
res.partner) and field names (name,email) you intend to use. Misspellings will lead to errors. - Domain Filters: Mastering Odoo’s domain syntax is key to performing powerful searches. Domains are lists of tuples, allowing for complex
AND/ORlogic. Explore the Odoo documentation on domains for advanced filtering. - Rate Limiting: Be mindful of potential API rate limits, especially when interacting with shared Odoo instances or cloud environments. Excessive requests in a short period might lead to temporary blocking.
- Further Operations: This tutorial demonstrated
searchandread. The Odoo 19 JSON-RPC API also fully supportscreate,write(update), andunlink(delete) operations, allowing for comprehensive data management from external systems. - Official Documentation: For the most up-to-date and complete reference, always consult the official Odoo documentation for the JSON-RPC API (note: link might point to 17.0 as 19.0 docs might still be emerging, but the JSON-RPC principles are consistent). Also, refer to the Python Requests documentation for more advanced HTTP client usage.
Conclusion
The Odoo 19 JSON-RPC API is a fantastic addition, making Odoo more open, accessible, and developer-friendly than ever before. By embracing modern web standards, Odoo 19 empowers businesses and developers to build robust, efficient, and seamless integrations with external applications. Whether you’re connecting a custom e-commerce front-end, a mobile app, or another enterprise system, the power and simplicity of this new API will significantly streamline your workflow.
We hope this comprehensive guide and tutorial have given you a solid foundation to start experimenting and integrating with Odoo 19. If you enjoyed this content and want to see more Odoo development insights, please leave a like, subscribe to our channel for the latest updates, and share any questions or suggestions in the comments below!
For more insightful Odoo development tips and tutorials, explore our Odoo Developer Hub [internal link placeholder].
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.

