Guide technique

Comment tracer et journaliser les appels à l'API REST de Dolibarr

Dernière mise à jour : juillet 2026

Trois façons d'auditer qui appelle quoi sur votre API Dolibarr — selon que vous ayez accès à la configuration du serveur ou seulement au dossier de l'application (cas fréquent en hébergement mutualisé).

1. Pourquoi tracer les appels API Dolibarr

Dès qu'un logiciel tiers, un connecteur ou un module se connecte à Dolibarr via son API REST, la question de la traçabilité se pose : qui appelle quoi, depuis quelle clé, à quelle fréquence ? Trois besoins reviennent le plus souvent — l'audit de sécurité (détecter une clé API compromise ou un usage anormal), la conformité (pouvoir démontrer qui a lu ou modifié quelles données), et le débogage d'intégration (comprendre pourquoi un appel échoue ou renvoie un résultat inattendu).

Il n'existe pas une seule bonne réponse : la méthode la plus adaptée dépend du niveau d'accès dont vous disposez (serveur dédié vs mutualisé standard) et du niveau de détail recherché (simple compteur, ou traçabilité complète avec clé, utilisateur et endpoint). Les trois méthodes ci-dessous peuvent d'ailleurs se combiner.

2. Rappel technique

Tous les appels à l'API REST de Dolibarr transitent par le même point d'entrée, /api/index.php, et s'authentifient via un header DOLAPIKEY (ou, à défaut, un paramètre api_key dans l'URL) — cette clé est vérifiée par Dolibarr en la comparant à la colonne api_key de la table llx_user. C'est ce point de passage unique qui rend possible les trois approches de traçabilité présentées ici.

3. Méthode 1 — Journalisation au niveau du serveur web

Accès requis : configuration du serveur (vhost Nginx ou Apache). Non applicable en mutualisé standard.

Le principe : ne journaliser que le chemin /api/, pas l'ensemble du trafic Dolibarr, avec un format de log dédié qui capture la méthode HTTP, l'URI appelée, le code de statut retourné et le header DOLAPIKEY utilisé.

Nginx

nginx.conf / vhost
log_format api_audit '$time_iso8601 $remote_addr "$request_method $request_uri" '
                      'status=$status dolapikey="$http_dolapikey" '
                      'ua="$http_user_agent"';

server {
    # ... configuration existante du vhost Dolibarr ...

    location /api/ {
        access_log /var/log/nginx/dolibarr-api-audit.log api_audit;
        try_files $uri $uri/ /api/index.php?$query_string;
    }
}

Apache

httpd.conf / vhost
LogFormat "%h %{%Y-%m-%dT%H:%M:%S%z}t \"%m %U\" status=%>s dolapikey=\"%{DOLAPIKEY}i\" ua=\"%{User-Agent}i\"" api_audit

<LocationMatch "^/api/">
    CustomLog /var/log/apache2/dolibarr-api-audit.log api_audit
</LocationMatch>
Limite — ce niveau de log capture l'URL, la méthode, le statut et la clé API, mais pas le corps des requêtes POST/PUT (la donnée effectivement écrite) sans module additionnel type mod_security ou njs/Lua. Et il faut, par définition, un accès à la configuration du serveur — ce qui exclut la plupart des hébergements mutualisés.

4. Méthode 2 — Constantes natives Dolibarr (zéro code, zéro accès serveur)

C'est le point de départ le plus simple : deux constantes activables en un clic depuis Dolibarr, sans écrire une ligne de code ni toucher à la configuration du serveur.

  • MAIN_API_DEBUG — à activer depuis Configuration > Autres (Divers). Une fois activée, chaque appel API journalise automatiquement l'URL et les données de la requête dans le journal de Dolibarr. Désactivable tout aussi simplement une fois l'audit terminé.
  • API_ENABLE_COUNT_CALLS — active un compteur natif du nombre d'appels API par utilisateur, stocké dans llx_user_param. Utile pour repérer rapidement une clé anormalement active, sans avoir à dépouiller des fichiers de log.
À privilégier en premier — avant d'installer un module dédié, ces deux constantes suffisent souvent à répondre à un besoin ponctuel d'audit ou de débogage.

5. Méthode 3 — Module personnalisé basé sur le hook beforeApiCall

Pour une traçabilité structurée et durable (une table dédiée, interrogeable, avec utilisateur résolu et endpoint), Dolibarr expose un hook officiel, beforeApiCall, déclenché sur le contexte api avant le traitement de chaque endpoint. Son avantage principal : un module Dolibarr classique s'installe sans accès serveur, y compris par simple dépôt du dossier en FTP.

À vérifier avant tout — ce hook n'existe que sur les versions récentes de Dolibarr. Avant de vous lancer, vérifiez sa présence sur l'installation cible : grep -i "executeHooks('beforeApiCall'" htdocs/api/index.php. Absence de résultat = hook indisponible sur cette version, repli sur les méthodes 1 ou 2.

a. Descripteur du module — déclarer le hook sur le contexte « api »

core/modules/modApiAuditLog.class.php
class modApiAuditLog extends DolibarrModules
{
    public function __construct($db)
    {
        global $langs, $conf;
        $this->db = $db;

        $this->numero = 500000; // à adapter : identifiant unique, hors plage réservée Dolibarr
        $this->rights_class = 'apiauditlog';
        $this->family = 'technic';
        $this->name = 'ApiAuditLog';
        $this->description = "Journalise chaque appel à l'API REST dans une table dédiée";
        $this->version = '1.0';
        $this->picto = 'technic';

        // Déclaration du hook sur le contexte "api" : requis pour que beforeApiCall soit
        // effectivement déclenché par htdocs/api/index.php.
        $this->module_parts = array(
            'hooks' => array('api'),
        );

        $this->tabs = array();
        $this->dirs = array();
    }
}

b. Classe de hook — capturer la clé, résoudre l'utilisateur, insérer la ligne d'audit

class/actions_apiauditlog.class.php
class ActionsApiAuditLog
{
    public $db;
    public $results = array();
    public $resprints = '';

    public function __construct($db)
    {
        $this->db = $db;
    }

    /**
     * Déclenché par htdocs/api/index.php avant le traitement de l'endpoint appelé.
     */
    public function beforeApiCall($parameters, &$object, &$action, $hookmanager)
    {
        $db = $this->db;

        // La clé peut arriver par header (recommandé) ou par paramètre GET (legacy).
        $apikey = '';
        if (!empty($_SERVER['HTTP_DOLAPIKEY'])) {
            $apikey = $_SERVER['HTTP_DOLAPIKEY'];
        } elseif (!empty($_GET['DOLAPIKEY'])) {
            $apikey = $_GET['DOLAPIKEY'];
        } elseif (!empty($_GET['api_key'])) {
            $apikey = $_GET['api_key'];
        }

        // Résolution de la clé en login utilisateur, pour ne jamais stocker la clé en clair.
        $login = '';
        if ($apikey !== '') {
            $sql = "SELECT login FROM " . MAIN_DB_PREFIX . "user WHERE api_key = '" . $db->escape($apikey) . "'";
            $resql = $db->query($sql);
            if ($resql && $db->num_rows($resql) > 0) {
                $login = $db->fetch_object($resql)->login;
            }
        }

        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "apiauditlog_log (datec, login, endpoint, method, ip)";
        $sql .= " VALUES (";
        $sql .= "'" . $db->idate(dol_now()) . "', ";
        $sql .= "'" . $db->escape($login) . "', ";
        $sql .= "'" . $db->escape($_SERVER['REQUEST_URI'] ?? '') . "', ";
        $sql .= "'" . $db->escape($_SERVER['REQUEST_METHOD'] ?? '') . "', ";
        $sql .= "'" . $db->escape($_SERVER['REMOTE_ADDR'] ?? '') . "'";
        $sql .= ")";
        $db->query($sql);

        return 0; // 0 = ne bloque pas l'appel API, la traçabilité reste transparente pour l'appelant
    }
}

c. Table dédiée

sql/llx_apiauditlog_log.sql
CREATE TABLE llx_apiauditlog_log (
    rowid    INTEGER AUTO_INCREMENT PRIMARY KEY,
    datec    DATETIME NOT NULL,
    login    VARCHAR(64),
    endpoint VARCHAR(255),
    method   VARCHAR(10),
    ip       VARCHAR(45)
) ENGINE=innodb;

Une fois le module activé, chaque appel API vient s'ajouter à llx_apiauditlog_log : date, login résolu (jamais la clé elle-même), endpoint, méthode et IP d'origine — une base directement interrogeable en SQL pour un audit ponctuel ou un tableau de bord.

6. Quelle méthode choisir ?

MéthodeAccès serveurDétail capturéDurée d'usage
Logs Nginx/ApacheRequisMéthode, URI, statut, clé — pas le corpsPonctuel ou continu
MAIN_API_DEBUGAucunURL et données de chaque appelPonctuel (à désactiver après usage)
API_ENABLE_COUNT_CALLSAucunCompteur d'appels par utilisateurContinu
Module + hook beforeApiCallAucun (dépôt FTP)Date, utilisateur, endpoint, IP, méthode — structuréContinu

7. Questions fréquentes

Peut-on tracer les appels API sans accès SSH au serveur ?

Oui — c'est justement l'intérêt des méthodes 2 et 3 : les constantes natives (MAIN_API_DEBUG, API_ENABLE_COUNT_CALLS) s'activent depuis l'interface Dolibarr, et un module basé sur le hook beforeApiCall s'installe par simple dépôt de dossier en FTP. Seule la méthode 1 (logs du serveur web) nécessite un accès à la configuration du vhost.

MAIN_API_DEBUG capture-t-il le corps des requêtes POST/PUT ?

Oui, à la différence des logs serveur web bruts : cette constante journalise l'URL et les données transmises à chaque appel API, directement depuis Dolibarr.

Le hook beforeApiCall est-il disponible sur toutes les versions de Dolibarr ?

Non, seulement sur les versions récentes. Vérifiez sa présence avec grep -i "executeHooks('beforeApiCall'" htdocs/api/index.php sur l'installation cible avant de développer un module qui en dépend.

Faut-il stocker la clé API en clair dans les logs d'audit ?

Non — l'exemple de module ci-dessus résout systématiquement la clé en login utilisateur avant insertion, pour ne jamais conserver la clé elle-même dans la table d'audit.