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
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
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>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.
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.
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 »
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 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
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éthode | Accès serveur | Détail capturé | Durée d'usage |
|---|---|---|---|
| Logs Nginx/Apache | Requis | Méthode, URI, statut, clé — pas le corps | Ponctuel ou continu |
| MAIN_API_DEBUG | Aucun | URL et données de chaque appel | Ponctuel (à désactiver après usage) |
| API_ENABLE_COUNT_CALLS | Aucun | Compteur d'appels par utilisateur | Continu |
| Module + hook beforeApiCall | Aucun (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.