Why Authentication Matters
Odoo's API is powerful — it exposes the entire ORM. Any client that authenticates can create, read, update, and delete records. Choosing the right authentication method determines security, performance, and maintainability of your integration.
Method 1: XML-RPC Authentication
The most documented and widely used method.
import xmlrpc.client
# Authenticate
common = xmlrpc.client.ServerProxy('https://odoo.company.com/xmlrpc/2/common')
uid = common.authenticate('database', '[email protected]', 'password', {})
# Use uid + password for all subsequent calls
models = xmlrpc.client.ServerProxy('https://odoo.company.com/xmlrpc/2/object')
result = models.execute_kw(
'database', uid, 'password',
'res.partner', 'search_read',
[[('is_company', '=', True)]],
{'fields': ['name', 'email'], 'limit': 10}
)Pros/Cons
- Pros: Simple, well-documented, works with every Odoo version
- Cons: Password sent with every request, XML overhead, no token expiry
Method 2: JSON-RPC Authentication
Same capabilities as XML-RPC but uses JSON format.
import requests
import json
url = 'https://odoo.company.com/jsonrpc'
# Authenticate
payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"service": "common",
"method": "authenticate",
"args": ["database", "[email protected]", "password", {}]
},
"id": 1
}
response = requests.post(url, json=payload)
uid = response.json()['result']
# Call method
payload = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"service": "object",
"method": "execute_kw",
"args": ["database", uid, "password",
"res.partner", "search_read",
[["is_company", "=", True]]]
},
"id": 2
}
result = requests.post(url, json=payload).json()['result']Pros/Cons
- Pros: JSON (lighter than XML), same capabilities as XML-RPC
- Cons: Same security model (password per request), less documented
Method 3: Session Authentication (Web)
Used by the Odoo web client and for browser-based integrations.
import requests
session = requests.Session()
# Login (get session cookie)
login_response = session.post('https://odoo.company.com/web/session/authenticate', json={
"jsonrpc": "2.0",
"params": {
"db": "database",
"login": "[email protected]",
"password": "password"
}
})
# Session cookie is automatically stored
# Subsequent requests use the session cookie
result = session.post('https://odoo.company.com/web/dataset/call_kw', json={
"jsonrpc": "2.0",
"method": "call",
"params": {
"model": "res.partner",
"method": "search_read",
"args": [[('is_company', '=', True)]],
"kwargs": {"fields": ["name"], "limit": 10}
}
})Pros/Cons
- Pros: No password after login, session expiry, CSRF protection
- Cons: Requires cookie management, not suitable for server-to-server
Method 4: API Keys (Odoo 14+)
API keys replace passwords for non-interactive authentication.
# Generate API key:
# User → Preferences → Account Security → API Keys → New API Key
# Use API key instead of password in XML-RPC/JSON-RPC:
uid = common.authenticate('database', '[email protected]', 'api_key_here', {})
result = models.execute_kw(
'database', uid, 'api_key_here', # API key instead of password
'res.partner', 'search_read', ...
)Pros/Cons
- Pros: No password exposure, revocable per key, per-integration keys
- Cons: Still sent with every request, no expiry (revoke manually)
Method 5: Custom JWT (Advanced)
For modern applications, implement JWT authentication via a custom controller:
# Custom Odoo controller:
@http.route('/api/auth/token', type='json', auth='public')
def get_token(self, **kwargs):
# Validate credentials
# Generate JWT with expiry
# Return access + refresh tokens
# Client uses JWT in Authorization header:
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get('https://odoo.company.com/api/v1/partners', headers=headers)Pros/Cons
- Pros: Modern, token expiry, refresh mechanism, stateless
- Cons: Requires custom development, not built into standard Odoo
Comparison
| Method | Security | Ease | Use Case |
|---|---|---|---|
| XML-RPC | Basic | Easy | Simple integrations, scripts |
| JSON-RPC | Basic | Easy | Modern integrations, less XML |
| Session | Good | Medium | Browser-based, web apps |
| API Keys | Good | Easy | Server-to-server, CI/CD |
| JWT | Best | Complex | SPA, mobile apps, microservices |
Security Best Practices
- Always use HTTPS — credentials and tokens are sent in plaintext over HTTP
- Use API keys over passwords for automated integrations
- Create dedicated API users with minimal permissions
- Rotate API keys periodically
- For customer-facing apps, implement JWT with short-lived tokens
- Never log or store credentials in version control
DeployMonkey
DeployMonkey uses JWT RS256 authentication with rotating refresh tokens — the most secure method. The AI agent communicates with your Odoo instance via authenticated API calls with full audit logging.