Le connecteur Matomo de Claude ne sait appliquer qu’un segment déjà enregistré dans Matomo. Pour suivre une série de pages, le plus rapide est de créer les segments par l’API avec un script, puis de tester chaque définition sur les visites brutes avant de s’en servir.
Le problème
Je voulais savoir combien de visites entraient sur chacune de mes 13 pages piliers, et lesquelles venaient des moteurs de recherche. Le MCP lit les rapports, mais il refuse un segment qu’on lui passe à la volée : il faut qu’il existe dans l’interface. Les créer à la main, un par un, avec leurs conditions, c’est long et l’on se trompe.
Le hack : SegmentEditor.add
L’API de Matomo permet d’enregistrer un segment par un simple appel POST. Le script ci-dessous crée un segment « toutes les pages piliers », un segment « via les moteurs » et un segment par page :
import os, requests, urllib.parse as up
URL, TOKEN, ID_SITE = os.environ["MATOMO_URL"].rstrip("/"), os.environ["MATOMO_TOKEN_AUTH"], 1
def api(method, **params):
params.update(module="API", method=method, format="json", token_auth=TOKEN)
return requests.post(f"{URL}/index.php", data=params, timeout=60).json()
# Valeur doublement encodée, comme dans les segments créés depuis l'interface
enc = lambda s: up.quote(up.quote(s, safe=""), safe="")
pages = ["email-marketing", "sms-marketing", "delivrabilite-email"]
cond = lambda p: f"entryPageUrl=^{enc('https://monsite.com/' + p + '/')}"
toutes = ",".join(cond(p) for p in pages)
existants = {s["name"] for s in api("SegmentEditor.getAll", idSite=ID_SITE)}
segments = [("SEO | Entrée pillar pages (toutes)", toutes),
("SEO | Entrée pillar pages via moteurs", toutes + ";referrerType==search")]
segments += [(f"SEO | Entrée pillar {p}", cond(p)) for p in pages]
for nom, definition in segments:
if nom in existants:
continue
print(nom, api("SegmentEditor.add", name=nom, definition=definition,
idSite=ID_SITE, autoArchive=1, enabledAllUsers=1))
Trois points comptent :
- Le POST est obligatoire. Avec un GET, l’appel est refusé.
- Le double encodage. Les valeurs d’URL sont encodées deux fois (
%253Apour un deux-points), comme dans les segments de l’interface. Sans cela, le segment ne reconnaît rien. autoArchive=1demande à Matomo de pré-calculer les rapports du segment, ce qui est la condition pour que le MCP puisse les lire.
Le jeton d’API vient d’une variable d’environnement, pas du script ni de la conversation avec Claude.
Tester une définition avant de s’y fier
Un segment mal écrit ne renvoie pas d’erreur, il renvoie zéro. Avant de l’utiliser, je le teste sur les visites brutes, qui, elles, acceptent n’importe quelle définition :
visites = api("Live.getLastVisitsDetails", idSite=ID_SITE, period="range",
date="2026-09-01,2026-10-07", segment=definition, filter_limit=500)
print(len(visites), "visites")
Sur mes 15 segments, le test m’a donné en un coup d’œil les entrées par page depuis le 1er septembre : 31 visites au total sur les pages piliers, dont 12 depuis les moteurs, et zéro pour trois d’entre elles. Un segment qui renvoie zéro à ce test n’est pas forcément faux, mais il mérite un second regard.
Les limites
- Pour une période passée, c’est l’API des visites brutes qui m’a donné les chiffres : les rapports d’un segment ne couvrent que ce que Matomo a archivé.
- Les visites refusées au bandeau cookies n’existent pas pour Matomo : les chiffres sont une partie du trafic réel.
- Trop de segments alourdissent l’archivage. Gardez ceux dont vous vous servez.
À retenir
Quand l’outil de lecture exige des segments enregistrés, créez-les par l’API, testez-les sur les visites brutes, et rangez-les avec un préfixe de nom (« SEO | ») pour les retrouver. Un script de quinze lignes remplace une heure de clics.