Odoo REST and XML-RPC API Integration Tutorial: Connect Any System

Step-by-step tutorial for integrating with Odoo APIs using REST, XML-RPC, and JSON-RPC. Covers authentication, CRUD operations, and real-world integration patterns.

E
ECOSIRE Research and Development Team
|March 16, 20268 min read1.7k Words|

Odoo REST and XML-RPC API Integration Tutorial: Connect Any System

Odoo exposes its entire data model through external APIs, making it possible to integrate with virtually any system---eCommerce platforms, CRM tools, business intelligence software, mobile apps, and custom applications. This tutorial covers all three API protocols (XML-RPC, JSON-RPC, and REST), authentication methods, CRUD operations, and real-world integration patterns with code examples and best practices.

Key Takeaways

  • Odoo provides three API protocols: XML-RPC (most mature), JSON-RPC (browser-friendly), and REST (Odoo 19, OpenAPI-compliant)
  • All APIs require authentication using database name, username, and password or API key
  • CRUD operations follow a consistent pattern across all protocols: search, read, create, write, unlink
  • Domain filters use a Polish notation syntax for complex queries
  • Pagination, field selection, and batch operations optimize performance for large datasets

API Protocol Comparison

FeatureXML-RPCJSON-RPCREST (Odoo 19)
MaturityStable since Odoo 8Stable since Odoo 10New in Odoo 19
AuthenticationUsername/passwordSession-basedAPI key or OAuth 2.0
DocumentationManualManualAuto-generated OpenAPI
Response formatXMLJSONJSON
Batch operationsYesYesYes
WebhooksNo (requires custom module)NoYes (configurable)
Language supportAny (XML-RPC is universal)JavaScript-friendlyAny (HTTP standard)

Authentication

XML-RPC Authentication

XML-RPC authentication uses a two-step process: authenticate to get a user ID (uid), then use that uid for subsequent calls.

The authentication call hits the /xmlrpc/2/common endpoint with authenticate method, passing the database name, username, password, and an empty object. The response is the numeric user ID. All subsequent data calls use /xmlrpc/2/object with execute_kw method, passing the database, uid, password, model name, method name, and arguments.

JSON-RPC Authentication

JSON-RPC uses session-based authentication through the /web/session/authenticate endpoint. The request body is a JSON object with jsonrpc: "2.0", a method of call, and params containing db, login, and password. The response includes a session ID in the cookie that authenticates subsequent requests.

REST API Authentication (Odoo 19)

The REST API supports API keys generated in the Odoo backend:

  1. Navigate to Settings > Users > API Keys
  2. Generate a new key with specified permissions
  3. Include the key in the Authorization: Bearer header

REST endpoints follow the pattern /api/{model} for collections and /api/{model}/{id} for individual records.

CRUD Operations

Search and Read

The most common operation is searching for records with specific criteria and reading their field values.

Domain filters use Polish notation (prefix notation) with operators:

OperatorDescriptionExample
=Equals['state', '=', 'sale']
!=Not equals['state', '!=', 'draft']
>Greater than['amount_total', '>', 1000]
&lt;Less than['date_order', '<', '2026-01-01']
&gt;=Greater or equal['qty_available', '>=', 10]
inIn list['state', 'in', ['sale', 'done']]
likePattern match['name', 'like', 'ECOSIRE']
ilikeCase-insensitive pattern['email', 'ilike', '@gmail.com']

Combining conditions: Use & (AND), | (OR), and ! (NOT) as prefix operators:

  • AND: ['&', ['state', '=', 'sale'], ['amount_total', '>', 1000]] matches sale orders over 1000
  • OR: ['|', ['state', '=', 'sale'], ['state', '=', 'done']] matches either state
  • Complex: ['&', ['state', '=', 'sale'], '|', ['partner_id', '=', 5], ['partner_id', '=', 10]]

Field selection: Request only the fields you need to reduce payload size and improve performance. Pass a fields parameter with a list of field names. If omitted, all fields are returned.

Pagination: Use offset and limit parameters to paginate results. Example: offset: 20, limit: 20 returns records 21-40.

Create Records

Create records by calling the create method with a dictionary of field values. Required fields must be included. The response returns the ID of the newly created record (or an array of IDs for batch creation).

Example: Creating a contact requires at minimum the name field. Optional fields include email, phone, company_id, street, city, state_id, country_id, and custom fields.

For related records (one2many or many2many), use special command tuples:

CommandSyntaxDescription
Create[0, 0, {values}]Create a new related record
Update[1, id, {values}]Update an existing related record
Delete[2, id, 0]Delete a related record
Unlink[3, id, 0]Remove the link (don't delete)
Link[4, id, 0]Add a link to existing record
Replace[6, 0, [ids]]Replace all links with provided IDs

Update Records

Update records by calling the write method with the record ID(s) and a dictionary of changed fields. Only include fields that need to change---omitted fields retain their current values.

Batch updates are supported: pass a list of IDs to update multiple records with the same values in a single call.

Delete Records

Delete records by calling the unlink method with the record ID(s). The method returns True on success.

Be cautious with deletion---many Odoo records are protected by business rules. Attempting to delete a posted invoice, for example, will raise an error. Use the appropriate business method instead (e.g., button_cancel before deletion).

Real-World Integration Patterns

eCommerce Order Sync

Synchronize orders from an external eCommerce platform to Odoo:

  1. Poll for new orders: Query the eCommerce API for orders since the last sync timestamp
  2. Match customers: Search Odoo contacts by email; create if not found
  3. Create sales order: Build the order with customer, lines, shipping, and payment info
  4. Confirm order: Call action_confirm to process the order through the workflow
  5. Update eCommerce: Send the Odoo order reference back to the eCommerce platform

Inventory Sync

Keep inventory levels synchronized between Odoo and an external channel:

  1. Read stock levels: Call search_read on stock.quant with location filters
  2. Push updates: Send quantity changes to the external channel
  3. Handle reservations: Account for reserved stock (committed to pending orders)
  4. Schedule sync: Run every 15-30 minutes to maintain accuracy

CRM Lead Import

Import leads from marketing platforms into Odoo CRM:

  1. Fetch leads: Pull new leads from the marketing platform API
  2. Deduplicate: Search Odoo for existing contacts by email or phone
  3. Create leads: Create records in crm.lead with source tracking
  4. Assign: Use Odoo's lead assignment rules or assign based on custom logic

Financial Data Export

Export financial data to a business intelligence platform:

  1. Export chart of accounts: Read account.account for the account structure
  2. Export journal entries: Read account.move.line with date filters
  3. Export balances: Use read_group to aggregate balances by account and period
  4. Schedule: Run daily after the accounting close window

Error Handling

Common API Errors

ErrorCauseResolution
Access DeniedInvalid credentials or permissionsVerify username, password, and access rights
Record not foundInvalid ID in read/write/unlinkVerify the record exists with a search first
Validation ErrorMissing required fields or invalid valuesInclude all required fields with valid data
UserErrorBusiness rule violationCheck the error message for specific rule
ConcurrencyExceptionRecord modified by another userRe-read the record and retry

Rate Limiting

Odoo does not enforce API rate limits by default, but production deployments should implement rate limiting at the reverse proxy level. For Odoo.sh, default limits apply to prevent abuse. Design integrations with reasonable polling intervals and batch operations.

Retry Strategy

Implement exponential backoff for transient errors:

  1. First retry after 1 second
  2. Second retry after 4 seconds
  3. Third retry after 16 seconds
  4. Log and alert after maximum retries

Performance Optimization

Batch Operations

Prefer batch operations over individual record processing:

  • create accepts a list of value dictionaries for batch creation
  • write accepts a list of IDs for batch updates
  • search_read with pagination is more efficient than individual read calls

Field Selection

Always specify the fields parameter to avoid loading unnecessary data. Loading all fields on a model with 50+ columns creates significant overhead, especially for models like sale.order or account.move.line.

Caching

Cache slowly changing data locally:

  • Product catalog (refresh hourly)
  • Customer list (refresh on change notification)
  • Tax rates and fiscal positions (refresh daily)

ECOSIRE Integration Services

Building reliable integrations requires understanding both the external system and Odoo's data model. ECOSIRE's Odoo integration services cover API design, connector development, data mapping, and ongoing monitoring. For organizations connecting eCommerce platforms, our specialized Shopify-Odoo integration and marketplace connectors handle the most common scenarios.

Which API protocol should I choose for a new integration?

For new projects on Odoo 19, use the REST API. It follows HTTP standards, has auto-generated documentation, and supports API keys for authentication. For Odoo 17 or 18, XML-RPC is the most reliable and well-documented option. JSON-RPC is best for browser-based integrations or JavaScript applications.

Is there a rate limit on Odoo's external API?

Odoo itself does not enforce rate limits. However, Odoo.sh deployments have infrastructure-level limits, and self-hosted deployments should implement rate limiting at the reverse proxy (Nginx) level. Design integrations to use batch operations and reasonable polling intervals regardless of limits.

Can I trigger workflows (confirm order, post invoice) through the API?

Yes. Use the execute_kw method with the workflow method name. For example, call action_confirm on a sale.order to confirm it, or action_post on an account.move to post a journal entry. The workflow methods enforce the same business rules as the UI.

E

Written by

ECOSIRE Research and Development Team

Building enterprise-grade digital products at ECOSIRE. Sharing insights on Odoo integrations, e-commerce automation, and AI-powered business solutions.

Chat on WhatsApp