Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Expert on Odoo's external JSON-RPC and XML-RPC APIs. Covers authentication, model calls, record CRUD, and real-world integration examples in Python, JavaScript, and curl.
.claude/skills/lingxling-odoo-rpc-api/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-13 | ✗→✓ | ▲ Improved | 18% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 82% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 107% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 49% | 0% |
Odoo exposes a powerful external API via JSON-RPC and XML-RPC, allowing any external application to read, create, update, and delete records. This skill guides you through authenticating, calling models, and building robust integrations.
@odoo-rpc-api and describe the integration you need.pythonimport xmlrpc.client url = 'https://myodoo.example.com' db = 'my_database' username = 'admin' password = 'my_api_key' # Use API keys, not passwords, in production # Step 1: Authenticate common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common') uid = common.authenticate(db, username, password, {}) print(f"Authenticated as UID: {uid}") # Step 2: Call models models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object') # Search confirmed sale orders orders = models.execute_kw(db, uid, password, 'sale.order', 'search_read', [[['state', '=', 'sale']]], {'fields': ['name', 'partner_id', 'amount_total'], 'limit': 10} ) for order in orders: print(order)
pythonnew_partner_id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{'name': 'Acme Corp', 'email': 'info@acme.com', 'is_company': True}] ) print(f"Created partner ID: {new_partner_id}")
bashcurl -X POST https://myodoo.example.com/web/dataset/call_kw \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "call", "id": 1, "params": { "model": "res.partner", "method": "search_read", "args": [[["is_company", "=", true]]], "kwargs": {"fields": ["name", "email"], "limit": 5} } }' # Note: "id" is required by the JSON-RPC 2.0 spec to correlate responses. # Odoo 16+ also supports the /web/dataset/call_kw endpoint but # prefer /web/dataset/call_kw for model method calls.
search_read instead of search + read to reduce network round trips..env file)./xmlrpc/2/) does not support file uploads — use the REST-based ir.attachment model via JSON-RPC for binary data.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 19,896 | 31,494 | +58% | 1 | 1 | 0% | 1,983 | 2,814 | +42% | 0 | 0 | — |
case-06 | fail→fail | 11,181 | 11,041 | -1% | 1 | 1 | 0% | 1,924 | 3,136 | +63% | 0 | 0 | — |
case-02 | pass→pass | 6,181 | 4,876 | -21% | 1 | 1 | 0% | 953 | 1,735 | +82% | 0 | 0 | — |
case-03 | pass→pass | 4,864 | 4,241 | -13% | 1 | 1 | 0% | 805 | 1,670 | +107% | 0 | 0 | — |
case-04 | pass→pass | 10,069 | 7,787 | -23% | 1 | 1 | 0% | 1,523 | 2,268 | +49% | 0 | 0 | — |
case-05 | pass→pass | 15,242 | 9,437 | -38% | 1 | 1 | 0% | 2,218 | 2,698 | +22% | 0 | 0 | — |
case-07 | pass→pass | 8,975 | 6,232 | -31% | 1 | 1 | 0% | 1,578 | 2,262 | +43% | 0 | 0 | — |
case-08 | pass→pass | 8,646 | 6,906 | -20% | 1 | 1 | 0% | 1,689 | 2,377 | +41% | 0 | 0 | — |
case-09 | pass→pass | 11,544 | 9,883 | -14% | 1 | 1 | 0% | 1,872 | 2,690 | +44% | 0 | 0 | — |
case-10 | pass→pass | 14,261 | 14,161 | -1% | 1 | 1 | 0% | 2,537 | 3,217 | +27% | 0 | 0 | — |
case-16 | pass→pass | 17,260 | 13,670 | -21% | 1 | 1 | 0% | 2,392 | 3,471 | +45% | 0 | 0 | — |
case-11 | pass→pass | 10,884 | 9,546 | -12% | 1 | 1 | 0% | 1,657 | 2,602 | +57% | 0 | 0 | — |
case-12 | pass→pass | 17,657 | 8,119 | -54% | 1 | 1 | 0% | 2,399 | 2,417 | +1% | 0 | 0 | — |
case-13 | fail→pass | 16,063 | 11,297 | -30% | 1 | 1 | 0% | 2,569 | 3,030 | +18% | 0 | 0 | — |
case-14 | pass→pass | 25,133 | 18,272 | -27% | 1 | 1 | 0% | 2,989 | 3,640 | +22% | 0 | 0 | — |
case-15 | fail→fail | 9,641 | 8,315 | -14% | 1 | 1 | 0% | 1,449 | 2,486 | +72% | 0 | 0 | — |
case-17 | pass→pass | 12,835 | 10,377 | -19% | 1 | 1 | 0% | 2,468 | 2,554 | +3% | 0 | 0 | — |
case-18 | pass→pass | 22,030 | 15,363 | -30% | 1 | 1 | 0% | 3,982 | 4,504 | +13% | 0 | 0 | — |
case-19 | pass→pass | 5,153 | 4,657 | -10% | 1 | 1 | 0% | 901 | 1,770 | +96% | 0 | 0 | — |
case-20 | pass→pass | 3,479 | 2,356 | -32% | 1 | 1 | 0% | 570 | 1,416 | +148% | 0 | 0 | — |
case-21 | pass→pass | 7,026 | 5,044 | -28% | 1 | 1 | 0% | 881 | 1,687 | +91% | 0 | 0 | — |
case-22 | fail→pass | 11,352 | 10,942 | -4% | 1 | 1 | 0% | 1,898 | 2,758 | +45% | 0 | 0 | — |
case-23 | fail→fail | 12,715 | 8,572 | -33% | 1 | 1 | 0% | 2,341 | 2,549 | +9% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.