Understanding Odoo XML-RPC
Odoo exposes an XML-RPC API on the same port as the web interface (default 8069). It provides two services: common (for authentication) and object (for model operations). Most connection problems fall into one of three categories: network blocked, Odoo configured to reject the interface, or authentication errors.
Root Cause 1 — Firewall Blocking Port 8069
If Odoo is behind a firewall or nginx, port 8069 may not be publicly accessible (and should not be in production). Test from your client machine:
nc -zv your-odoo-server.com 8069
# or
curl -I http://your-odoo-server.com:8069/xmlrpc/2/common
If you get "Connection refused" or timeout, the port is blocked. For production, go through HTTPS (port 443) via nginx — not direct port 8069. Update your XML-RPC client to use https://your-domain.com/xmlrpc/2/common.
Root Cause 2 — xmlrpc_interface Restriction
Odoo can be configured to only accept XML-RPC connections from specific interfaces:
# /etc/odoo/odoo.conf
xmlrpc_interface = 127.0.0.1 # restricts to localhost only
If this is set and you are connecting from outside, change it to empty (all interfaces) or the specific IP you need:
xmlrpc_interface = # blank = all interfaces
Restart Odoo after any config change.
Root Cause 3 — Using HTTP When HTTPS Is Required
If Odoo is behind an SSL-terminating proxy (nginx), the Odoo process itself only speaks HTTP. Your XML-RPC client should connect to the nginx HTTPS endpoint, not directly to Odoo's HTTP port.
A Working Python XML-RPC Example
import xmlrpc.client
import ssl
url = "https://your-odoo.example.com"
db = "your_database"
username = "admin"
password = "your_password"
# Authenticate
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, username, password, {})
print(f"Authenticated as UID: {uid}")
# Call a model method
models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")
partners = models.execute_kw(
db, uid, password,
"res.partner", "search_read",
[[["is_company", "=", True]]],
{"fields": ["name", "email"], "limit": 5}
)
for p in partners:
print(p["name"], p.get("email"))
If you get SSL certificate errors in development, add context=ssl._create_unverified_context() to ServerProxy (never in production).
Root Cause 4 — Authentication Errors
If common.authenticate() returns False instead of a UID:
- Wrong database name — list databases with
common.db.list()(iflist_db = True). - Wrong username — use the login field, not display name.
- Wrong password — this is the user password, not the master password.
- User is inactive or archived — check in Settings > Users.
- Two-factor authentication enabled — XML-RPC does not support 2FA; use an API key instead.
Using API Keys Instead of Passwords
Odoo 14+ supports API keys, which are safer than passwords for external scripts:
# Generate in Odoo: Settings > Users > your user > API Keys tab
# Then use it as the password in XML-RPC calls
password = "your_api_key_here"
uid = common.authenticate(db, username, password, {})
Root Cause 5 — JSON-RPC vs XML-RPC
Odoo also supports JSON-RPC at /web/dataset/call_kw. Some client libraries default to this. Ensure your client is using the correct protocol for the endpoint you are targeting.
How DeployMonkey Handles External API Access
DeployMonkey instances are accessible via HTTPS on port 443. XML-RPC works through the standard HTTPS endpoint — no special firewall rules needed. API keys are the recommended authentication method. See Odoo Security Best Practices for API security recommendations.
Start free at deploymonkey.app.
Frequently Asked Questions
Should I expose port 8069 directly to the internet?
No. Always proxy through nginx with SSL. Port 8069 should be bound to 127.0.0.1 only. Direct exposure skips SSL and exposes Odoo to direct attacks.
Why does XML-RPC work on localhost but not from my script?
Your script is hitting port 8069 directly while the server firewall blocks it from external IPs. Use the HTTPS nginx endpoint instead.
What is the difference between xmlrpc/2/common and xmlrpc/2/object?
Common provides unauthenticated methods (authenticate, version). Object requires a UID and provides access to all Odoo model methods (execute_kw).
Can I use XML-RPC to install modules?
Yes, via ir.module.module — but this requires admin privileges and restarts Odoo's worker pool, so it should only be done in maintenance windows.