Connecter un ERP d'entreprise à un agent d'intelligence artificielle a longtemps été synonyme de connecteurs XML-RPC verbeux, de gestion fragile de cookies de session ou de sérialisation positionnelle difficile à fiabiliser pour un grand modèle de langage (LLM). Avec l'introduction de l'API externe JSON-2 dans Odoo 19, l'architecture d'intégration change d'ère : chaque modèle et chaque méthode publique de l'ORM sont désormais accessibles via un contrat HTTP RESTful moderne, sans état (stateless) et conçu autour d'objets JSON nommés.

Cet article détaille comment brancher un agent IA sur Odoo via l'API JSON-2, quels sont les endpoints réellement accessibles, et surtout ce que l'on peut automatiser en toute sécurité en production.

Schéma d'architecture pour connecter un agent IA à Odoo avec l'API JSON-2 et ses garde-fous de sécurité

Pourquoi l'API JSON-2 d'Odoo est idéale pour le tool calling des agents IA

Historiquement, les intégrations externes passaient par /xmlrpc/2/object (execute_kw) ou /jsonrpc. Pour un agent IA, ces protocoles posaient deux problèmes : l'obligation d'empiler des listes d'arguments positionnels ([[['is_company', '=', True]], {'fields': ['name']}]) sources d'erreurs de parenthésage, et l'absence de sémantique HTTP standard.

L'API JSON-2 résout ces limites grâce à quatre caractéristiques natives :

  1. Un adressage explicite par URL : Toutes les requêtes suivent le format POST /json/2/<model>/<method>, où <model> désigne le nom technique de l'objet Odoo (par exemple res.partner, sale.order, account.move) et <method> la méthode ORM ou métier invoquée (search_read, read_group, create, write).
  2. Une authentification Bearer sans session : La clé API personnelle générée dans le profil d'un utilisateur dédié est transmise dans l'en-tête standard Authorization: Bearer <API_KEY>. Aucune gestion de cookie session_id ni jeton CSRF n'est nécessaire.
  3. Un corps de requête exclusivement composé de paramètres nommés : L'agent envoie un dictionnaire JSON plat (domain, fields, ids, vals_list, context), ce qui correspond exactement au format JSON Schema utilisé par le function calling des modèles IA modernes.
  4. Une documentation auto-générée sur /doc : Chaque instance Odoo expose son catalogue de modèles et de signatures sur l'endpoint /doc (disponible sur les plans Odoo Custom et les déploiements On-Premise / Odoo.sh).

Comment configurer la connexion technique étape par étape

1. Créer un compte de service au moindre privilège dans Odoo

Ne donnez jamais la clé API d'un administrateur système à un agent IA. Créez un utilisateur technique dédié (par exemple agent-ia@entreprise.ch), rattachez-le uniquement aux groupes de sécurité requis (lecture CRM, création de devis en brouillon, lecture analytique) et générez une clé API dédiée depuis Préférences → Sécurité du compte → Nouvelles clés API. En cas d'incident, cette clé est révocable instantanément sans impacter les collaborateurs humains.

2. Anatomie d'un appel HTTP vers /json/2/<model>/<method>

Chaque appel vers l'API JSON-2 requiert l'en-tête Authorization, le Content-Type: application/json; charset=utf-8 et, lorsque le serveur héberge plusieurs bases, l'en-tête X-Odoo-Database.

import os
import requests

ODOO_URL = os.environ["ODOO_BASE_URL"]          # ex: https://erp.entreprise.ch
ODOO_DB = os.environ["ODOO_DATABASE"]           # ex: entreprise_prod
ODOO_API_KEY = os.environ["ODOO_AGENT_API_KEY"] # Clé de l'utilisateur restreint

def call_odoo_json2(model: str, method: str, payload: dict) -> dict | list:
    """Exécute un appel sécurisé sur l'API JSON-2 d'Odoo."""
    url = f"{ODOO_URL}/json/2/{model}/{method}"
    headers = {
        "Authorization": f"Bearer {ODOO_API_KEY}",
        "Content-Type": "application/json; charset=utf-8",
        "X-Odoo-Database": ODOO_DB,
        "User-Agent": "21datas-agent-connector/1.0",
    }
    response = requests.post(url, headers=headers, json=payload, timeout=30)
    response.raise_for_status()
    return response.json()

# Exemple : rechercher les 5 opportunités CRM les plus importantes en Suisse
leads = call_odoo_json2(
    model="crm.lead",
    method="search_read",
    payload={
        "domain": [["type", "=", "opportunity"], ["probability", ">=", 50]],
        "fields": ["name", "partner_id", "expected_revenue", "stage_id", "date_deadline"],
        "order": "expected_revenue desc",
        "limit": 5,
        "context": {"lang": "fr_CH"},
    },
)

Quels sont les endpoints accessibles via l'API JSON-2 ?

L'API JSON-2 n'expose pas une liste figée de routes codées en dur : elle expose dynamiquement toutes les méthodes publiques (@api.model, @api.model_create_multi, méthodes d'instance) autorisées par les règles d'accès (ir.model.access et ir.rule) de l'utilisateur appelant. Voici les endpoints fondamentaux à déclarer comme outils (tools) pour un agent IA :

Endpoint JSON-2Paramètres clés du corps JSONRôle pour l'agent IA
POST /json/2/<model>/search_readdomain, fields, limit, offset, orderRechercher et lire des enregistrements filtrés en un seul aller-retour réseau.
POST /json/2/<model>/read_groupdomain, fields, groupby, lazyCalculer des sommes, moyennes et comptages côté PostgreSQL sans saturer le contexte du LLM.
POST /json/2/<model>/search_countdomainCompter instantanément le volume de dossiers (ex. : factures en retard).
POST /json/2/<model>/fields_getattributes (string, type, relation, selection)Permettre à l'agent d'inspecter dynamiquement le schéma et les champs personnalisés (x_studio_*).
POST /json/2/<model>/createvals_list, contextCréer un ou plusieurs enregistrements (piste CRM, devis brouillon, tâche projet).
POST /json/2/<model>/writeids, valsMettre à jour des champs précis sur des identifiants existants.
POST /json/2/<model>/message_postids, body, message_type, subtype_xmlidPublier un compte-rendu d'analyse ou une note interne directement dans le chatter Odoo.
POST /json/2/sale.order/action_confirmidsDéclencher une transition de workflow métier (confirmation d'un devis en commande).

Ce que l'on est vraiment capable de faire en production (et les pièges à éviter)

Au-delà de la démonstration technique, que peut-on réellement confier à un agent IA connecté à Odoo en production ? Notre retour d'expérience chez 21datas distingue clairement les automatisations à fort ROI immédiat et les opérations qui exigent une validation humaine.

1. Ce qui fonctionne avec une fiabilité supérieure à 95 % en autonomie

  • Le pilotage analytique en langage naturel via read_group : Un piège classique consiste à laisser l'agent appeler search_read sur 25 000 lignes de factures (account.move.line) pour les additionner lui-même. Un LLM ne doit jamais faire d'arithmétique de masse dans sa fenêtre de contexte. En exposant un outil basé sur /json/2/account.move/read_group ou /json/2/sale.report/read_group, c'est PostgreSQL qui exécute l'agrégation exacte par mois, commercial ou axe analytique, et l'agent reçoit un tableau synthétique de 12 lignes parfaitement juste.
  • La qualification CRM et la préparation de devis (crm.lead & sale.order) : Lorsqu'un e-mail client ou une demande issue du site arrive, l'agent vérifie si le client existe dans res.partner, recherche l'historique de ses tarifs dans product.pricelist, crée l'opportunité dans crm.lead et génère un devis complet à l'état brouillon (state = 'draft') dans sale.order, avec les lignes d'articles (order_line) via les commandes ORM (0, 0, {...}).
  • Le triage support et la synthèse dans le chatter (helpdesk.ticket & project.task) : L'agent lit le ticket entrant, consulte la base documentaire technique, vérifie le contrat d'abonnement actif du client et poste une proposition de réponse en note interne via /json/2/helpdesk.ticket/message_post pour faire gagner 80 % du temps au consultant support.
  • La saisie assistée des feuilles de temps (account.analytic.line) : À partir d'un message Slack ou d'un calendrier, l'agent résout le projet et la tâche Odoo correspondants puis pré-remplit les imputations horaires des collaborateurs.

2. Les garde-fous indispensables : ce qu'il ne faut jamais laisser en exécution aveugle

Un agent IA connecté à un ERP manipule des données financières et légales. Trois règles d'ingénierie sont impératives :

  1. Interdire l'endpoint unlink et la validation comptable directe : Le compte de service de l'agent ne doit jamais posséder le droit de suppression (unlink), ni le droit d'appeler action_post sur une écriture comptable (account.move) ou un paiement (account.payment) sans validation humaine. L'agent crée la pièce à l'état draft, joint le justificatif PDF analysé et mentionne le comptable dans le chatter.
  2. Encapsuler JSON-2 derrière des outils métiers typés (MCP / Tool Server) : Plutôt que de donner un outil générique call_any_odoo_endpoint(model, method, body) au LLM, exposez des fonctions bornées comme search_customer_invoices(), create_draft_quotation() ou post_internal_chatter_note() qui imposent des limites (limit <= 100) et valident les paramètres avec Zod ou Pydantic.
  3. Gérer l'idempotence des écritures : Avant tout appel à create sur res.partner, crm.lead ou sale.order, le connecteur vérifie l'existence d'une clé externe ou d'une référence unique afin qu'une relance réseau ne crée jamais de doublon dans l'ERP.

Vous souhaitez connecter votre instance Odoo à des agents IA gouvernés ou déployer une interface conversationnelle comme 21brain sur vos données ERP et votre entrepôt data engineering ? Prenez rendez-vous avec notre équipe ou contactez-nous.

in Data