En bref
- Nouveau modèle : un POST vers
/json/2/<modèle>/<méthode>, une clé API, un corps JSON. - À faire : convertir vos scripts un par un, sur une copie de la base.
- À vérifier : les changements incompatibles d'Odoo 20 et l'accès à l'API selon votre forfait.
Dans ce tutoriel
Pourquoi migrer vos intégrations XML-RPC maintenant ?
Si un script, un connecteur ou un outil maison lit ou écrit dans Odoo par XML-RPC, il repose sur un mécanisme que l'éditeur retire par étapes. Voici le calendrier, tel que nous le comprenons à partir de la documentation officielle.
| Point | Statut | Détail |
|---|---|---|
| XML-RPC et JSON-RPC | Confirmé | Dépréciés depuis Odoo 19. |
Service db | Confirmé | Retiré dans Odoo 20. |
Points d'entrée common et object | Confirmé | Retrait prévu pour Odoo 22. |
API JSON-2 (/json/2/) | Confirmé | Remplaçante officielle, appels HTTP POST avec clé API. |
| Liste complète des changements incompatibles entre Odoo 19 et 20 | À vérifier | Non confirmée de notre côté. Lisez les notes de version officielles avant de migrer. |
| Accès à l'API externe selon le forfait Odoo Online | À vérifier | La documentation d'Odoo 19 réserve l'API aux forfaits Custom. Confirmez pour Odoo 20. |
Avant de commencer
Travaillez toujours sur une copie de la base de données, jamais sur la production. Les exemples ci-dessous créent et suppriment des enregistrements.
Quels sont les prérequis ?
- Une instance Odoo 20 (ou une copie de test de votre base)
- Un utilisateur dédié à l'intégration, avec seulement les droits nécessaires
- Une clé API générée pour cet utilisateur
- Python 3 et la bibliothèque
requests(pip install requests)
Pour la clé API, ouvrez les préférences de l'utilisateur d'intégration et cherchez la section de sécurité du compte. Les libellés exacts peuvent varier d'une version à l'autre : vérifiez-les dans votre instance. Copiez la clé tout de suite, elle ne sera plus affichée.
Bonne pratique
Créez un utilisateur technique par intégration plutôt que d'utiliser un compte de personne. Si un accès doit être révoqué, vous ne touchez qu'à une seule clé.
Étape 1 : comment faire un premier appel JSON-2 ?
Un appel JSON-2 suit toujours le même modèle : une requête POST vers /json/2/<modèle>/<méthode>, la clé API dans Authorization, et les arguments de la méthode dans le corps JSON. Testons-le d'abord avec curl.
curl -X POST "https://mon-odoo.example.com/json/2/res.partner/search_read" \
-H "Authorization: bearer VOTRE_CLE_API" \
-H "X-Odoo-Database: ma_base" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{"domain": [["is_company", "=", true]], "fields": ["name", "email"], "limit": 5}' Si tout est bien configuré, la réponse est une liste JSON de cinq contacts au plus. Passons maintenant à Python, avec une petite fonction réutilisable.
import requests
BASE_URL = "https://mon-odoo.example.com"
API_KEY = "VOTRE_CLE_API"
DB = "ma_base"
session = requests.Session()
session.headers.update({
"Authorization": f"bearer {API_KEY}",
"X-Odoo-Database": DB,
"Content-Type": "application/json; charset=utf-8",
})
def call(model, method, **payload):
"""Appelle une méthode d'un modèle via l'API JSON-2."""
r = session.post(f"{BASE_URL}/json/2/{model}/{method}", json=payload, timeout=30)
r.raise_for_status()
return r.json()
contacts = call(
"res.partner", "search_read",
domain=[["is_company", "=", True]],
fields=["name", "email"],
limit=5,
)
print(contacts)À retenir
Il n'y a plus d'étape d'authentification qui renvoie un identifiant d'utilisateur. La clé API dans l'en-tête suffit à chaque appel.
Étape 2 : comment créer, modifier et supprimer des enregistrements ?
Les méthodes classiques de l'ORM s'appellent de la même façon. Les arguments portent leur nom dans le corps JSON : vals_list pour créer, ids et vals pour modifier, ids pour supprimer.
# Créer un contact (vals_list est une liste de dictionnaires)
nouveaux = call("res.partner", "create", vals_list=[{"name": "Client test API"}])
partner_id = nouveaux[0]
print("Créé :", partner_id)
# Modifier ce contact
call("res.partner", "write", ids=[partner_id], vals={"phone": "514 555 0100"})
# Relire le résultat
print(call("res.partner", "search_read",
domain=[["id", "=", partner_id]],
fields=["name", "phone"]))
# Supprimer le contact de test
call("res.partner", "unlink", ids=[partner_id])Vérifiez dans votre version
La forme exacte des réponses peut varier selon la méthode appelée. Affichez toujours la réponse brute lors de vos premiers tests plutôt que de supposer sa structure.
Étape 3 : comment convertir un appel XML-RPC existant ?
Voici un appel typique en XML-RPC. Il demande deux requêtes distinctes (authentification, puis appel) et passe les arguments par position.
import xmlrpc.client
url, db, user, password = "https://mon-odoo.example.com", "ma_base", "api@exemple.com", "motdepasse"
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, user, password, {})
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},
)Le même appel en JSON-2 devient une seule requête, avec des arguments nommés.
partners = call(
"res.partner", "search_read",
domain=[["is_company", "=", True]],
fields=["name", "email"],
limit=5,
)| XML-RPC | JSON-2 |
|---|---|
/xmlrpc/2/common puis /xmlrpc/2/object | Une seule route : /json/2/<modèle>/<méthode> |
Authentification avec identifiant et mot de passe, puis uid | Clé API dans l'en-tête Authorization |
Arguments par position dans args et kwargs | Arguments nommés dans le corps JSON |
| Base choisie dans chaque appel | En-tête X-Odoo-Database |
Étape 4 : comment gérer les erreurs et plusieurs bases ?
Dans la fonction call, raise_for_status() transforme un statut HTTP d'erreur en exception Python. Le corps de la réponse contient le détail de l'erreur, utile à journaliser. Ajoutons-le proprement.
import requests
class OdooApiError(Exception):
pass
def call(model, method, **payload):
r = session.post(f"{BASE_URL}/json/2/{model}/{method}", json=payload, timeout=30)
if not r.ok:
raise OdooApiError(f"{r.status_code} sur {model}.{method} : {r.text[:500]}")
return r.json()Pour un serveur qui héberge plusieurs bases, gardez une session par base, chacune avec son en-tête X-Odoo-Database. Ne mettez jamais la clé API dans le code source : lisez-la depuis une variable d'environnement.
Sécurité
Une clé API donne les mêmes droits que l'utilisateur qui la porte. Limitez ses droits, changez-la périodiquement, et ne la versionnez jamais dans Git.
Comment planifier la bascule sans interrompre vos opérations ?
- Lister tous les scripts, connecteurs et outils tiers qui appellent Odoo
- Vérifier si chaque outil tiers offre déjà une version compatible JSON-2
- Convertir vos propres scripts un par un et les tester sur une copie de la base
- Comparer les résultats ancien et nouveau appel sur les mêmes données
- Basculer en production en dehors des heures de pointe, avec un plan de retour
Les intégrations avec une boutique en ligne, un outil de paie ou un système d'expédition touchent souvent plusieurs modules à la fois. Si vous hésitez sur la portée du chantier, un partenaire Odoo peut en faire l'inventaire avec vous.
Une clé API, une route, des arguments nommés : JSON-2 simplifie l'intégration, à condition de convertir avant l'échéance.
À explorer aussi
- Parler à un expert Kuantiik pour auditer vos intégrations Odoo
- Le blogue Kuantiik pour la suite de la série Odoo 20
Foire aux questions sur l'API JSON-2 d'Odoo 20
Qu'est-ce que l'API JSON-2 d'Odoo 20 ?
C'est l'API externe moderne d'Odoo. Chaque appel est une requête HTTP POST vers /json/2/<modèle>/<méthode>, avec une clé API en en-tête et les paramètres dans un corps JSON. Elle remplace progressivement XML-RPC et JSON-RPC.
XML-RPC fonctionne-t-il encore dans Odoo 20 ?
Les points d'entrée XML-RPC et JSON-RPC sont dépréciés depuis Odoo 19. Dans Odoo 20, le service db a été retiré, et le retrait de common et object est prévu pour Odoo 22. Vos intégrations existantes ne tombent donc pas toutes en même temps, mais il vaut mieux migrer avant l'échéance.
Faut-il un mot de passe pour utiliser l'API JSON-2 ?
Non. L'authentification se fait avec une clé API envoyée dans l'en-tête Authorization, sous la forme bearer suivi de la clé. Il n'y a plus d'appel d'authentification préalable pour obtenir un identifiant d'utilisateur.
Comment choisir la base de données avec JSON-2 ?
En ajoutant l'en-tête X-Odoo-Database avec le nom de la base, utile surtout quand le serveur héberge plusieurs bases.
L'API JSON-2 est-elle offerte sur Odoo Online ?
Selon la documentation d'Odoo 19, l'API externe est réservée aux forfaits Custom d'Odoo Online. Confirmez la situation de votre forfait pour Odoo 20 auprès d'Odoo ou de votre partenaire avant de bâtir une intégration.
Par où commencer pour migrer une intégration existante ?
Dressez la liste de vos appels XML-RPC, convertissez-les un à un en suivant le modèle search_read, create, write et unlink de ce tutoriel, puis testez sur une copie de la base avant de basculer la production.
Vos intégrations Odoo sont-elles prêtes pour Odoo 20 ?
On en fait l'inventaire avec vous et on convertit ce qui doit l'être, sans toucher à la production.
Parler à un expert KuantiikSources
- Odoo, documentation de l'API externe (version 19), odoo.com
- Notes de version et calendrier de dépréciation d'Odoo 20 : à valider sur la documentation officielle avant toute migration
Une question sur la migration vers JSON-2 ?
On répond sous 24h ouvrées aux questions des entreprises québécoises.
Écrire à KuantiikAvant de partir
Demandez une évaluation de vos intégrations Odoo avant l'échéance XML-RPC.
Demander mon évaluationEn bref
- Nouveau modèle : un POST vers
/json/2/<modèle>/<méthode>, une clé API, un corps JSON. - À faire : convertir vos scripts un par un, sur une copie de la base.
- À vérifier : les changements incompatibles d'Odoo 20 et l'accès à l'API selon votre forfait.
Dans ce tutoriel
Pourquoi migrer vos intégrations XML-RPC maintenant ?
Si un script, un connecteur ou un outil maison lit ou écrit dans Odoo par XML-RPC, il repose sur un mécanisme que l'éditeur retire par étapes. Voici le calendrier, tel que nous le comprenons à partir de la documentation officielle.
| Point | Statut | Détail |
|---|---|---|
| XML-RPC et JSON-RPC | Confirmé | Dépréciés depuis Odoo 19. |
Service db | Confirmé | Retiré dans Odoo 20. |
Points d'entrée common et object | Confirmé | Retrait prévu pour Odoo 22. |
API JSON-2 (/json/2/) | Confirmé | Remplaçante officielle, appels HTTP POST avec clé API. |
| Liste complète des changements incompatibles entre Odoo 19 et 20 | À vérifier | Non confirmée de notre côté. Lisez les notes de version officielles avant de migrer. |
| Accès à l'API externe selon le forfait Odoo Online | À vérifier | La documentation d'Odoo 19 réserve l'API aux forfaits Custom. Confirmez pour Odoo 20. |
Avant de commencer
Travaillez toujours sur une copie de la base de données, jamais sur la production. Les exemples ci-dessous créent et suppriment des enregistrements.
Quels sont les prérequis ?
- Une instance Odoo 20 (ou une copie de test de votre base)
- Un utilisateur dédié à l'intégration, avec seulement les droits nécessaires
- Une clé API générée pour cet utilisateur
- Python 3 et la bibliothèque
requests(pip install requests)
Pour la clé API, ouvrez les préférences de l'utilisateur d'intégration et cherchez la section de sécurité du compte. Les libellés exacts peuvent varier d'une version à l'autre : vérifiez-les dans votre instance. Copiez la clé tout de suite, elle ne sera plus affichée.
Bonne pratique
Créez un utilisateur technique par intégration plutôt que d'utiliser un compte de personne. Si un accès doit être révoqué, vous ne touchez qu'à une seule clé.
Étape 1 : comment faire un premier appel JSON-2 ?
Un appel JSON-2 suit toujours le même modèle : une requête POST vers /json/2/<modèle>/<méthode>, la clé API dans Authorization, et les arguments de la méthode dans le corps JSON. Testons-le d'abord avec curl.
curl -X POST "https://mon-odoo.example.com/json/2/res.partner/search_read" \
-H "Authorization: bearer VOTRE_CLE_API" \
-H "X-Odoo-Database: ma_base" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{"domain": [["is_company", "=", true]], "fields": ["name", "email"], "limit": 5}' Si tout est bien configuré, la réponse est une liste JSON de cinq contacts au plus. Passons maintenant à Python, avec une petite fonction réutilisable.
import requests
BASE_URL = "https://mon-odoo.example.com"
API_KEY = "VOTRE_CLE_API"
DB = "ma_base"
session = requests.Session()
session.headers.update({
"Authorization": f"bearer {API_KEY}",
"X-Odoo-Database": DB,
"Content-Type": "application/json; charset=utf-8",
})
def call(model, method, **payload):
"""Appelle une méthode d'un modèle via l'API JSON-2."""
r = session.post(f"{BASE_URL}/json/2/{model}/{method}", json=payload, timeout=30)
r.raise_for_status()
return r.json()
contacts = call(
"res.partner", "search_read",
domain=[["is_company", "=", True]],
fields=["name", "email"],
limit=5,
)
print(contacts)À retenir
Il n'y a plus d'étape d'authentification qui renvoie un identifiant d'utilisateur. La clé API dans l'en-tête suffit à chaque appel.
Étape 2 : comment créer, modifier et supprimer des enregistrements ?
Les méthodes classiques de l'ORM s'appellent de la même façon. Les arguments portent leur nom dans le corps JSON : vals_list pour créer, ids et vals pour modifier, ids pour supprimer.
# Créer un contact (vals_list est une liste de dictionnaires)
nouveaux = call("res.partner", "create", vals_list=[{"name": "Client test API"}])
partner_id = nouveaux[0]
print("Créé :", partner_id)
# Modifier ce contact
call("res.partner", "write", ids=[partner_id], vals={"phone": "514 555 0100"})
# Relire le résultat
print(call("res.partner", "search_read",
domain=[["id", "=", partner_id]],
fields=["name", "phone"]))
# Supprimer le contact de test
call("res.partner", "unlink", ids=[partner_id])Vérifiez dans votre version
La forme exacte des réponses peut varier selon la méthode appelée. Affichez toujours la réponse brute lors de vos premiers tests plutôt que de supposer sa structure.
Étape 3 : comment convertir un appel XML-RPC existant ?
Voici un appel typique en XML-RPC. Il demande deux requêtes distinctes (authentification, puis appel) et passe les arguments par position.
import xmlrpc.client
url, db, user, password = "https://mon-odoo.example.com", "ma_base", "api@exemple.com", "motdepasse"
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, user, password, {})
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},
)Le même appel en JSON-2 devient une seule requête, avec des arguments nommés.
partners = call(
"res.partner", "search_read",
domain=[["is_company", "=", True]],
fields=["name", "email"],
limit=5,
)| XML-RPC | JSON-2 |
|---|---|
/xmlrpc/2/common puis /xmlrpc/2/object | Une seule route : /json/2/<modèle>/<méthode> |
Authentification avec identifiant et mot de passe, puis uid | Clé API dans l'en-tête Authorization |
Arguments par position dans args et kwargs | Arguments nommés dans le corps JSON |
| Base choisie dans chaque appel | En-tête X-Odoo-Database |
Étape 4 : comment gérer les erreurs et plusieurs bases ?
Dans la fonction call, raise_for_status() transforme un statut HTTP d'erreur en exception Python. Le corps de la réponse contient le détail de l'erreur, utile à journaliser. Ajoutons-le proprement.
import requests
class OdooApiError(Exception):
pass
def call(model, method, **payload):
r = session.post(f"{BASE_URL}/json/2/{model}/{method}", json=payload, timeout=30)
if not r.ok:
raise OdooApiError(f"{r.status_code} sur {model}.{method} : {r.text[:500]}")
return r.json()Pour un serveur qui héberge plusieurs bases, gardez une session par base, chacune avec son en-tête X-Odoo-Database. Ne mettez jamais la clé API dans le code source : lisez-la depuis une variable d'environnement.
Sécurité
Une clé API donne les mêmes droits que l'utilisateur qui la porte. Limitez ses droits, changez-la périodiquement, et ne la versionnez jamais dans Git.
Comment planifier la bascule sans interrompre vos opérations ?
- Lister tous les scripts, connecteurs et outils tiers qui appellent Odoo
- Vérifier si chaque outil tiers offre déjà une version compatible JSON-2
- Convertir vos propres scripts un par un et les tester sur une copie de la base
- Comparer les résultats ancien et nouveau appel sur les mêmes données
- Basculer en production en dehors des heures de pointe, avec un plan de retour
Les intégrations avec une boutique en ligne, un outil de paie ou un système d'expédition touchent souvent plusieurs modules à la fois. Si vous hésitez sur la portée du chantier, un partenaire Odoo peut en faire l'inventaire avec vous.
Une clé API, une route, des arguments nommés : JSON-2 simplifie l'intégration, à condition de convertir avant l'échéance.
À explorer aussi
- Parler à un expert Kuantiik pour auditer vos intégrations Odoo
- Le blogue Kuantiik pour la suite de la série Odoo 20
Foire aux questions sur l'API JSON-2 d'Odoo 20
Qu'est-ce que l'API JSON-2 d'Odoo 20 ?
C'est l'API externe moderne d'Odoo. Chaque appel est une requête HTTP POST vers /json/2/<modèle>/<méthode>, avec une clé API en en-tête et les paramètres dans un corps JSON. Elle remplace progressivement XML-RPC et JSON-RPC.
XML-RPC fonctionne-t-il encore dans Odoo 20 ?
Les points d'entrée XML-RPC et JSON-RPC sont dépréciés depuis Odoo 19. Dans Odoo 20, le service db a été retiré, et le retrait de common et object est prévu pour Odoo 22. Vos intégrations existantes ne tombent donc pas toutes en même temps, mais il vaut mieux migrer avant l'échéance.
Faut-il un mot de passe pour utiliser l'API JSON-2 ?
Non. L'authentification se fait avec une clé API envoyée dans l'en-tête Authorization, sous la forme bearer suivi de la clé. Il n'y a plus d'appel d'authentification préalable pour obtenir un identifiant d'utilisateur.
Comment choisir la base de données avec JSON-2 ?
En ajoutant l'en-tête X-Odoo-Database avec le nom de la base, utile surtout quand le serveur héberge plusieurs bases.
L'API JSON-2 est-elle offerte sur Odoo Online ?
Selon la documentation d'Odoo 19, l'API externe est réservée aux forfaits Custom d'Odoo Online. Confirmez la situation de votre forfait pour Odoo 20 auprès d'Odoo ou de votre partenaire avant de bâtir une intégration.
Par où commencer pour migrer une intégration existante ?
Dressez la liste de vos appels XML-RPC, convertissez-les un à un en suivant le modèle search_read, create, write et unlink de ce tutoriel, puis testez sur une copie de la base avant de basculer la production.
Vos intégrations Odoo sont-elles prêtes pour Odoo 20 ?
On en fait l'inventaire avec vous et on convertit ce qui doit l'être, sans toucher à la production.
Parler à un expert KuantiikSources
- Odoo, documentation de l'API externe (version 19), odoo.com
- Notes de version et calendrier de dépréciation d'Odoo 20 : à valider sur la documentation officielle avant toute migration
Une question sur la migration vers JSON-2 ?
On répond sous 24h ouvrées aux questions des entreprises québécoises.
Écrire à KuantiikAvant de partir
Demandez une évaluation de vos intégrations Odoo avant l'échéance XML-RPC.
Demander mon évaluation