Skip to content

Odoo XML-RPC API: Complete Python Integration Guide

DeployMonkey Team · March 22, 2026 14 min read

What Is the Odoo XML-RPC API?

Odoo exposes its entire ORM through XML-RPC — a protocol that lets external programs call Odoo methods remotely. Every operation you can do in the Odoo UI, you can do through the API: create records, search, update, delete, run methods, and generate reports.

Connection Setup

import xmlrpc.client

URL = 'http://localhost:8069'
DB = 'production'
USER = 'admin'
PASS = 'admin'

# Step 1: Authenticate
common = xmlrpc.client.ServerProxy(f'{URL}/xmlrpc/2/common')
uid = common.authenticate(DB, USER, PASS, {})
print(f'Authenticated as uid={uid}')

# Step 2: Get models proxy
models = xmlrpc.client.ServerProxy(f'{URL}/xmlrpc/2/object')

# Helper function
def call(model, method, *args, **kwargs):
    return models.execute_kw(DB, uid, PASS, model, method, list(args), kwargs)

CRUD Operations

Create

# Create one record
partner_id = call('res.partner', 'create', [{
    'name': 'Acme Corp',
    'email': '[email protected]',
    'is_company': True,
}])
print(f'Created partner id={partner_id}')

# Create multiple records
ids = call('res.partner', 'create', [
    {'name': 'Alice', 'email': '[email protected]'},
    {'name': 'Bob', 'email': '[email protected]'},
])

Read

# Read specific fields by IDs
data = call('res.partner', 'read', [partner_id], fields=['name', 'email', 'phone'])
print(data)  # [{'id': 1, 'name': 'Acme Corp', 'email': '[email protected]', 'phone': False}]

Search

# Search returns IDs
ids = call('res.partner', 'search',
    [('is_company', '=', True)],
    limit=10, offset=0, order='name asc'
)

# Search + Read in one call
records = call('res.partner', 'search_read',
    [('is_company', '=', True)],
    fields=['name', 'email', 'country_id'],
    limit=10, order='name asc'
)

# Count
count = call('res.partner', 'search_count',
    [('is_company', '=', True)]
)

Update

# Update one or more records
call('res.partner', 'write', [[partner_id], {
    'phone': '+1-555-0100',
    'city': 'New York',
}])

Delete

# Delete records
call('res.partner', 'unlink', [[partner_id]])

Aggregation (read_group)

# Group sales by month
result = call('sale.order', 'read_group',
    [('state', 'in', ['sale', 'done'])],
    ['amount_total:sum'],
    ['date_order:month'],
    orderby='date_order:month asc'
)
for row in result:
    print(f"{row['date_order:month']}: ${row['amount_total']}")

Calling Model Methods

# Call any public method on a model
call('sale.order', 'action_confirm', [[order_id]])
call('account.move', 'action_post', [[invoice_id]])

Many2many and One2many Commands

# Commands for relational fields:
# (0, 0, values) — Create new linked record
# (1, id, values) — Update existing linked record
# (2, id, 0) — Delete linked record
# (3, id, 0) — Unlink (remove relationship, keep record)
# (4, id, 0) — Link existing record
# (5, 0, 0) — Unlink all
# (6, 0, [ids]) — Replace with list of IDs

# Add tags to a partner
call('res.partner', 'write', [[partner_id], {
    'category_id': [(4, tag_id_1), (4, tag_id_2)],  # Link existing tags
}])

# Replace all tags
call('res.partner', 'write', [[partner_id], {
    'category_id': [(6, 0, [tag_id_1, tag_id_2, tag_id_3])],
}])

Error Handling

import xmlrpc.client

try:
    result = call('res.partner', 'create', [{'name': ''}])  # Missing required field
except xmlrpc.client.Fault as e:
    print(f"Odoo error: {e.faultString}")
except ConnectionRefusedError:
    print("Cannot connect to Odoo server")

Best Practices

  • Use search_read instead of search + read for fewer API calls
  • Use read_group for aggregations instead of reading all records
  • Batch operations — Create/update multiple records in one call
  • Set limits on search operations to prevent loading millions of records
  • Use a dedicated API user with appropriate permissions, not admin

DeployMonkey Integration

DeployMonkey's built-in AI agent uses XML-RPC internally to interact with your Odoo instance. For custom integrations, connect to your DeployMonkey-hosted Odoo via XML-RPC using the same patterns above.