Reference · Tools
Odoo
Interact with the Odoo ERP platform via its JSON-RPC 2.0 API to manage contacts, opportunities, notes, and custom resources
The Odoo node reaches into an Odoo ERP instance over JSON-RPC to manage contacts, opportunities, notes and custom resources — including the models specific to your own installation. A typical build is creating an opportunity in Odoo when a qualified lead arrives from a form.
- Node type
- Action
- Parameters
- 38
- Outputs
- Output, Error
- Credentials
- Odoo API
Odoo
Manage contacts, opportunities, notes, and custom resources in Odoo ERP
Overview
Odoo is an open-source ERP and CRM platform. This tool uses the Odoo JSON-RPC 2.0 API to perform CRUD operations on Odoo models. It supports built-in resources (Contact, Opportunity, Note) as well as any custom Odoo model. Authentication uses the Odoo login endpoint to obtain a user ID, which is then included in all subsequent data operation requests. The tool supports filtering for list operations on custom resources, and field selection to limit returned data.
Category: Data & Storage
Tool Name: odoo
Version: 1
Appearance: Icon: si-odoo | Color: #714B67
Node Type
Action — processes input items and produces output
Input / Output
| Direction | Port(s) |
|---|---|
| Input | Input |
| Output | Output, Error |
Credentials
This tool requires Odoo API credentials. See the Credentials Guide for setup instructions.
Resources
| Resource | Value |
|---|---|
| Contact | contact |
| Custom Resource | custom |
| Note | note |
| Opportunity | opportunity |
Operations
Each resource carries its own operation selector, and all four offer the same five operations. Choose the resource first, then the operation.
| Resource | Operation | Value | Description |
|---|---|---|---|
| Contact | Create | create | Create a contact |
| Contact | Delete | delete | Delete a contact by ID |
| Contact | Get | get | Read one contact by ID |
| Contact | Get Many | getAll | Search contacts and return the matches |
| Contact | Update | update | Update a contact by ID |
| Custom Resource | Create | create | Create a record in any Odoo model |
| Custom Resource | Delete | delete | Delete a record by ID |
| Custom Resource | Get | get | Read one record by ID |
| Custom Resource | Get Many | getAll | Search records and return the matches |
| Custom Resource | Update | update | Update a record by ID |
| Note | Create | create | Create a note |
| Note | Delete | delete | Delete a note by ID |
| Note | Get | get | Read one note by ID |
| Note | Get Many | getAll | Search notes and return the matches |
| Note | Update | update | Update a note by ID |
| Opportunity | Create | create | Create a CRM opportunity |
| Opportunity | Delete | delete | Delete an opportunity by ID |
| Opportunity | Get | get | Read one opportunity by ID |
| Opportunity | Get Many | getAll | Search opportunities and return the matches |
| Opportunity | Update | update | Update an opportunity by ID |
Parameters
Collection sub-fields carry their internal name in backticks, because that name — not the label — is the key you write in a JSON configuration.
Contact: Create
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
Name (contactName) | string | Yes | — | The name of the contact to create. Supports expressions like {{ $json.name }}. |
| Additional Fields | collection | No | {} | Additional fields for the new contact. |
— Address (address) | fixedCollection | No | {} | The contact’s address. Each sub-field below is written to Odoo as its own address field on the contact. |
— — City (city) | string | No | — | City name. |
— — Country ID (country_id) | number | No | — | Numeric ID of the country in Odoo. Find in Odoo: Contacts > Configuration > Localization > Countries. |
— — State ID (state_id) | number | No | — | Numeric ID of the state/province in Odoo. Find in Odoo: Contacts > Configuration > Localization > Fed. States. |
— — Street (street) | string | No | — | First address line. |
— — Street 2 (street2) | string | No | — | Second address line. |
— — Zip Code (zip) | string | No | — | Postal code. |
— Email (email) | string | No | — | Email address. |
— Internal Notes (comment) | string | No | — | Free-text notes stored on the contact. |
— Job Position (function) | string | No | — | Job title. |
— Mobile (mobile) | string | No | — | Mobile phone number. |
— Phone (phone) | string | No | — | Phone number. |
— Tax ID (vat) | string | No | — | Tax identification (VAT) number. |
— Website (website) | string | No | — | Website URL. |
Contact: Delete
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Contact ID | string | Yes | — | The numeric ID of the contact. Supports expressions like {{ $json.contactId }}. |
Contact: Get
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Contact ID | string | Yes | — | The numeric ID of the contact. Supports expressions like {{ $json.contactId }}. |
| Options | collection | No | {} | Additional options for the request. |
— Fields to Include (fieldsList) | string | No | — | Comma-separated list of field names to return (e.g. “name,email,phone”). Leave empty to return all fields. Find field names in Odoo Settings > Technical > Database Structure > Models > select model > Fields tab. |
Contact: Get Many
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Return All | boolean | No | false | Whether to return all results or only up to a given limit. |
| Limit | number | No | 50 | Max number of results to return. (shown when Return All is false) |
| Options | collection | No | {} | Additional options for the request. |
— Fields to Include (fieldsList) | string | No | — | Comma-separated list of field names to return (e.g. “name,email,phone”). Leave empty to return all fields. Find field names in Odoo Settings > Technical > Database Structure > Models > select model > Fields tab. |
Contact: Update
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Contact ID | string | Yes | — | The numeric ID of the contact to update. Supports expressions like {{ $json.contactId }}. |
Update Fields (updateFields) | collection | No | {} | Fields to update on the contact. |
— Address (address) | fixedCollection | No | {} | The contact’s address. Each sub-field below is written to Odoo as its own address field on the contact. |
— — City (city) | string | No | — | City name. |
— — Country ID (country_id) | number | No | — | Numeric ID of the country in Odoo. |
— — State ID (state_id) | number | No | — | Numeric ID of the state/province in Odoo. |
— — Street (street) | string | No | — | First address line. |
— — Street 2 (street2) | string | No | — | Second address line. |
— — Zip Code (zip) | string | No | — | Postal code. |
— Email (email) | string | No | — | Email address. |
— Internal Notes (comment) | string | No | — | Free-text notes stored on the contact. |
— Job Position (function) | string | No | — | Job title. |
— Mobile (mobile) | string | No | — | Mobile phone number. |
— Name (name) | string | No | — | New name for the contact. |
— Phone (phone) | string | No | — | Phone number. |
— Tax ID (vat) | string | No | — | Tax identification (VAT) number. |
— Website (website) | string | No | — | Website URL. |
Custom Resource: Create
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Custom Resource Model | string | Yes | — | The Odoo model name to operate on (e.g. “sale.order”, “product.product”, “account.move”). Find available models in Odoo Settings > Technical > Database Structure > Models. Supports expressions like {{ $json.model }}. |
Fields (fieldsToCreateOrUpdate) | fixedCollection | No | {} | Field name-value pairs for the new record. Field names must match Odoo model field names (e.g. “name”, “email”, “partner_id”). |
— Field Name (fieldName) | string | No | — | The Odoo field name. Find available fields in Odoo: Settings > Technical > Database Structure > Models > select model > Fields tab. |
— New Value (fieldValue) | string | No | — | The value to set for this field. |
Custom Resource: Delete
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Custom Resource Model | string | Yes | — | The Odoo model name to operate on (e.g. “sale.order”, “product.product”, “account.move”). Find available models in Odoo Settings > Technical > Database Structure > Models. Supports expressions like {{ $json.model }}. |
| Custom Resource ID | string | Yes | — | The numeric ID of the record. Supports expressions like {{ $json.recordId }}. |
Custom Resource: Get
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Custom Resource Model | string | Yes | — | The Odoo model name to operate on (e.g. “sale.order”, “product.product”, “account.move”). Find available models in Odoo Settings > Technical > Database Structure > Models. Supports expressions like {{ $json.model }}. |
| Custom Resource ID | string | Yes | — | The numeric ID of the record. Supports expressions like {{ $json.recordId }}. |
| Options | collection | No | {} | Additional options for the request. |
— Fields to Include (fieldsList) | string | No | — | Comma-separated list of field names to return. Leave empty to return all fields. Field names depend on the selected custom resource model. |
Custom Resource: Get Many
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Custom Resource Model | string | Yes | — | The Odoo model name to operate on (e.g. “sale.order”, “product.product”, “account.move”). Find available models in Odoo Settings > Technical > Database Structure > Models. Supports expressions like {{ $json.model }}. |
| Return All | boolean | No | false | Whether to return all results or only up to a given limit. |
| Limit | number | No | 50 | Max number of results to return. (shown when Return All is false) |
| Options | collection | No | {} | Additional options for the request. |
— Fields to Include (fieldsList) | string | No | — | Comma-separated list of field names to return. Leave empty to return all fields. Field names depend on the selected custom resource model. |
| Filters | fixedCollection | No | {} | Filter conditions for the search. Each filter has a field name, operator, and value. |
— Field Name (fieldName) | string | No | — | The Odoo field name to filter on. |
— Operator (operator) | options | No | equal | The comparison operator. |
Options: equal (=), notEqual (!=), greaterThen (>), lesserThen (<), greaterOrEqual (>=), lesserOrEqual (<=), like, in, notIn (not in), childOf (child of) | ||||
— Value (value) | string | No | — | The value to compare against. |
Custom Resource: Update
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Custom Resource Model | string | Yes | — | The Odoo model name to operate on (e.g. “sale.order”, “product.product”, “account.move”). Find available models in Odoo Settings > Technical > Database Structure > Models. Supports expressions like {{ $json.model }}. |
| Custom Resource ID | string | Yes | — | The numeric ID of the record to update. Supports expressions like {{ $json.recordId }}. |
Update Fields (fieldsToCreateOrUpdate) | fixedCollection | No | {} | Field name-value pairs to update on the record. |
— Field Name (fieldName) | string | No | — | The Odoo field name to update. |
— New Value (fieldValue) | string | No | — | The new value for this field. |
Note: Create
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Memo | string | Yes | — | The content of the note. Supports expressions like {{ $json.body }}. |
Note: Delete
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Note ID | string | Yes | — | The numeric ID of the note. Supports expressions like {{ $json.noteId }}. |
Note: Get
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Note ID | string | Yes | — | The numeric ID of the note. Supports expressions like {{ $json.noteId }}. |
| Options | collection | No | {} | Additional options for the request. |
— Fields to Include (fieldsList) | string | No | — | Comma-separated list of field names to return (e.g. “memo,create_date”). Leave empty to return all fields. |
Note: Get Many
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Return All | boolean | No | false | Whether to return all results or only up to a given limit. |
| Limit | number | No | 50 | Max number of results to return. (shown when Return All is false) |
| Options | collection | No | {} | Additional options for the request. |
— Fields to Include (fieldsList) | string | No | — | Comma-separated list of field names to return (e.g. “memo,create_date”). Leave empty to return all fields. |
Note: Update
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Note ID | string | Yes | — | The numeric ID of the note to update. Supports expressions like {{ $json.noteId }}. |
| Memo | string | Yes | — | The updated content of the note. Supports expressions like {{ $json.body }}. |
Opportunity: Create
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
Name (opportunityName) | string | Yes | — | The name of the opportunity to create. Supports expressions like {{ $json.dealName }}. |
| Additional Fields | collection | No | {} | Additional fields for the new opportunity. |
— Email (email_from) | string | No | — | Contact email address for the opportunity. |
— Expected Revenue (expected_revenue) | number | No | 0 | Expected revenue for the deal. |
— Internal Notes (description) | string | No | — | Free-text description stored on the opportunity. |
— Phone (phone) | string | No | — | Contact phone number. |
— Priority (priority) | options | No | 1 | Priority of the opportunity. |
Options: 1, 2, 3 | ||||
— Probability (probability) | number | No | 0 | Win probability, from 0 to 100. |
Opportunity: Delete
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Opportunity ID | string | Yes | — | The numeric ID of the opportunity. Supports expressions like {{ $json.opportunityId }}. |
Opportunity: Get
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Opportunity ID | string | Yes | — | The numeric ID of the opportunity. Supports expressions like {{ $json.opportunityId }}. |
| Options | collection | No | {} | Additional options for the request. |
— Fields to Include (fieldsList) | string | No | — | Comma-separated list of field names to return (e.g. “name,email_from,expected_revenue”). Leave empty to return all fields. |
Opportunity: Get Many
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Return All | boolean | No | false | Whether to return all results or only up to a given limit. |
| Limit | number | No | 50 | Max number of results to return. (shown when Return All is false) |
| Options | collection | No | {} | Additional options for the request. |
— Fields to Include (fieldsList) | string | No | — | Comma-separated list of field names to return (e.g. “name,email_from,expected_revenue”). Leave empty to return all fields. |
Opportunity: Update
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Opportunity ID | string | Yes | — | The numeric ID of the opportunity to update. Supports expressions like {{ $json.opportunityId }}. |
Update Fields (updateFields) | collection | No | {} | Fields to update on the opportunity. |
— Email (email_from) | string | No | — | Contact email address for the opportunity. |
— Expected Revenue (expected_revenue) | number | No | 0 | Expected revenue for the deal. |
— Internal Notes (description) | string | No | — | Free-text description stored on the opportunity. |
— Name (name) | string | No | — | New name for the opportunity. |
— Phone (phone) | string | No | — | Contact phone number. |
— Priority (priority) | options | No | 1 | Priority of the opportunity. |
Options: 1, 2, 3 | ||||
— Probability (probability) | number | No | 0 | Win probability, from 0 to 100. |
All Operations
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Max Concurrency | number | No | 10 | Maximum number of items to process concurrently. |
Output Data
The Odoo record is the output item. Whatever the API returns is merged into the item JSON at the top level, so a record field named email is addressable downstream as {{ $json.email }}. The rest of the input item’s JSON passes through unchanged except where a record field overwrites it, and binary data is forwarded.
| Operation | Fields merged onto the output item | Items produced per input item |
|---|---|---|
create | id — the numeric ID Odoo assigned to the new record | One |
get | The record’s fields, or only the ones named in Fields to Include | One |
getAll | Each matching record’s fields, or only the ones named in Fields to Include | One per matching record — a Get Many that finds 200 records turns one input item into 200 output items. No matches yields a single item with its JSON unchanged |
update | id — the ID of the record that was updated | One |
delete | success (true) | One |
Two things to plan around:
- Get Many fans out. Every downstream node sees one item per record, not one item holding an array. Set Return All off and use Limit while you are building, then switch it on once the shape of the data is settled.
- ID parameters are numeric strings. Contact ID, Opportunity ID, Note ID and Custom Resource ID must resolve to a whole number; anything else fails that item before the request is sent.
Usage Examples
- Create a new contact in Odoo
- List all CRM opportunities
- Update an Odoo note by ID
- Delete a custom resource record
- Get all contacts with specific fields
Example Configuration
Create a contact with an address and the usual detail fields:
{
"type": "odoo",
"parameters": {
"resource": "contact",
"operation": "create",
"contactName": "John Doe",
"additionalFields": {
"email": "john.doe@example.com",
"phone": "+1-555-0123",
"mobile": "+1-555-0124",
"function": "Sales Manager",
"website": "https://example.com",
"vat": "US123456789",
"comment": "Important client contact",
"address": {
"value": {
"street": "123 Main St",
"street2": "Suite 100",
"city": "New York",
"state_id": 47,
"zip": "10001",
"country_id": 233
}
}
}
}
}
Read one contact and return only the fields you care about:
{
"type": "odoo",
"parameters": {
"resource": "contact",
"operation": "get",
"contactId": "123",
"options": {
"fieldsList": "name,email,phone,mobile"
}
}
}
List the first 50 contacts:
{
"type": "odoo",
"parameters": {
"resource": "contact",
"operation": "getAll",
"returnAll": false,
"limit": 50,
"options": {
"fieldsList": "name,email,phone"
}
}
}
Update a contact, including its address:
{
"type": "odoo",
"parameters": {
"resource": "contact",
"operation": "update",
"contactId": "123",
"updateFields": {
"name": "John Smith",
"email": "john.smith@example.com",
"phone": "+1-555-9999",
"mobile": "+1-555-8888",
"function": "Senior Sales Manager",
"website": "https://newsite.com",
"vat": "US987654321",
"comment": "Updated contact information",
"address": {
"value": {
"street": "456 Oak Ave",
"street2": "Floor 5",
"city": "Boston",
"state_id": 22,
"zip": "02101",
"country_id": 233
}
}
}
}
}
Delete a contact:
{
"type": "odoo",
"parameters": {
"resource": "contact",
"operation": "delete",
"contactId": "123"
}
}
Create a CRM opportunity:
{
"type": "odoo",
"parameters": {
"resource": "opportunity",
"operation": "create",
"opportunityName": "Big Sales Deal",
"additionalFields": {
"email_from": "client@bigcompany.com",
"phone": "+1-555-0200",
"expected_revenue": 50000,
"probability": 75,
"priority": "2",
"description": "Major client interested in our enterprise solution"
}
}
}
Read one opportunity:
{
"type": "odoo",
"parameters": {
"resource": "opportunity",
"operation": "get",
"opportunityId": "456",
"options": {
"fieldsList": "name,expected_revenue,probability,stage_id"
}
}
}
Move an opportunity forward:
{
"type": "odoo",
"parameters": {
"resource": "opportunity",
"operation": "update",
"opportunityId": "456",
"updateFields": {
"name": "Confirmed Big Sales Deal",
"expected_revenue": 75000,
"probability": 90,
"priority": "3",
"description": "Deal confirmed, moving to final negotiations"
}
}
}
Create a note:
{
"type": "odoo",
"parameters": {
"resource": "note",
"operation": "create",
"memo": "Important meeting notes from client call on 2024-01-15"
}
}
Replace a note’s content:
{
"type": "odoo",
"parameters": {
"resource": "note",
"operation": "update",
"noteId": "789",
"memo": "Updated meeting notes with additional action items"
}
}
Create a record in a model that has no built-in resource — here a sales order:
{
"type": "odoo",
"parameters": {
"resource": "custom",
"customResource": "sale.order",
"operation": "create",
"fieldsToCreateOrUpdate": {
"fields": [
{ "fieldName": "partner_id", "fieldValue": "123" },
{ "fieldName": "date_order", "fieldValue": "2024-01-15" },
{ "fieldName": "amount_total", "fieldValue": "1500.00" }
]
}
}
}
Search a custom model with two filter conditions:
{
"type": "odoo",
"parameters": {
"resource": "custom",
"customResource": "product.product",
"operation": "getAll",
"returnAll": false,
"limit": 20,
"options": {
"fieldsList": "name,default_code,list_price,categ_id"
},
"filterRequest": {
"filter": [
{ "fieldName": "active", "operator": "equal", "value": "true" },
{ "fieldName": "list_price", "operator": "greaterThen", "value": "100" }
]
}
}
}
Update a record in a custom model:
{
"type": "odoo",
"parameters": {
"resource": "custom",
"customResource": "account.move",
"operation": "update",
"customResourceId": "999",
"fieldsToCreateOrUpdate": {
"fields": [
{ "fieldName": "ref", "fieldValue": "INV/2024/001" },
{ "fieldName": "invoice_date", "fieldValue": "2024-01-15" },
{ "fieldName": "state", "fieldValue": "posted" }
]
}
}
}
Error Handling
| Mode | Behavior |
|---|---|
| stop | Halts workflow on first error |
| continue | Skips failed items, passes successful ones through |
| errorPort | Routes failed items to Error output port |
Tips
Manage contacts, opportunities, notes, and custom resources in the Odoo ERP platform via JSON-RPC.
Error Prevention
- Always verify field names match Odoo model definitions
- Ensure numeric IDs are passed as strings for ID parameters
- Use proper data types for field values (strings for text, numbers for numeric fields)
Frequently asked questions
Can it work with custom Odoo models?
Yes — alongside contacts, opportunities and notes it supports custom resources, which matters because most Odoo installations carry models unique to that business.
Why is my field being rejected?
Field names must match the Odoo model definitions exactly. Verify against the model rather than assuming the label shown in the Odoo interface is the field name.
How should IDs and values be typed?
Numeric IDs need to be passed as strings for ID parameters, and field values should use the proper type — strings for text, numbers for numeric fields.
Which credential does it need?
An Odoo API credential with the instance URL, database and user details.
Build with the Odoo node
Drop it into a workflow, wire it to an agent, or call it on a schedule. You'll need Odoo API credentials first.
Open BusyBotLast updated . Spotted something wrong? Tell us.