10 min de lectureTutoriels

API d'analyse des liens : récupérer les statistiques de clics avec une clé API

Guide d'une API d'analyse des liens : quels rapports de clics une clé API peut lire, les paramètres de requête, les formats de réponse JSON, la pagination par curseur et un script de rapport Slack quotidien.

Marius Voß
DevRel · edge infra
Illustration de couverture de l'API d'analyse des liens : une requête curl avec une clé API d'espace de travail renvoie une série temporelle de clics, une répartition et un résumé JSON à côté d'un graphique en barres

L'API d'analyse des liens d'Elido est un point d'accès unique, GET /v1/workspaces/{workspace_id}/analytics/{report}, sur https://api.elido.app, authentifié avec une clé API d'espace de travail. Elle fournit 15 rapports : série temporelle des clics, résumé de l'engagement, liens principaux, flux paginé par curseur des clics récents et répartitions par pays, référent, appareil, navigateur, hôte et destination. Les dates couvrent par défaut les 30 derniers jours, link_id limite n'importe quel rapport à un seul lien court, et l'export CSV, les entonnoirs, les cohortes et la LTV restent dans le tableau de bord.

C'est toute la réponse si vous aviez seulement besoin de l'URL. La suite de ce guide contient ce que j'aurais aimé trouver au début de chaque page d'API d'analyse des clics : les paramètres exacts, le JSON renvoyé, le point où la plage de dates fonctionne discrètement autrement que prévu et un script de 30 lignes qui publie chaque matin les chiffres de la veille dans Slack.

La plupart des personnes qui extraient des données de clics ferment une boucle qui commence par le marquage des campagnes. Si vos liens ne portent pas encore des UTM cohérents, corrigez cela d'abord avec le suivi UTM de bout en bout. Des données d'entrée propres rendent les statistiques utiles.

Ce que renvoie l'API d'analyse des liens

Chaque rapport utilise le même chemin, et le nom du rapport constitue le dernier segment. Les noms contenant une barre oblique (links/top, clicks/recent, breakdown/country) doivent être transmis sans encodage. Si vous demandez autre chose que les rapports autorisés, vous obtenez une 404 avec unknown analytics report.

RapportFormat de réponseUtile pour
timeseries{items: [{ts, count}]}Graphiques, comparaisons jour après jour
summaryobjet plat de cinq statistiquesRécapitulatifs quotidiens, indicateurs KPI
links/top{items: [{link_id, slug, count}]}"Quels liens ont porté la semaine"
clicks/recent{items: [click rows], next_cursor}Flux presque en temps réel, stockage personnalisé
breakdown/country, /referrer, /device, /browser, /host, /destination{items: [{key, count}]}Graphiques circulaires, répartition des canaux
top-countries, top-referrers, top-destinations{items: [{key, count}]}Mêmes données, noms plus simples
top-regions, top-cities{points: [{country, region or city, count}]}Exploration géographique sous le niveau du pays

Remarquez la dernière ligne. Les rapports de régions et de villes regroupent leurs lignes dans points, et non dans items, car chaque ligne contient un pays ainsi qu'une région ou une ville au lieu d'une seule clé. J'ai vu un analyseur générique échouer exactement une fois sur ce point. Une fois suffit.

La même interface alimente les API et SDK, l'outil d'analyse du serveur MCP et l'opération Get Analytics du nœud n8n. Ce que vous apprenez ici est donc réutilisable.

S'authentifier avec une clé API d'espace de travail

Les clés API commencent par elido_ et appartiennent à un seul espace de travail. Envoyez la clé comme jeton bearer :

curl -s "https://api.elido.app/v1/workspaces/4821/analytics/summary" \
  -H "Authorization: Bearer $ELIDO_API_KEY"

Le routeur vérifie deux éléments avant toute exécution de requête : la clé appartient à l'espace de travail 4821 et elle possède analytics.view. Tous les rôles intégrés disposent de cette autorisation, y compris Viewer. Créez donc une clé Viewer pour les tâches de rapport. Un cron de rapport n'a aucune raison de pouvoir supprimer des liens, et une clé Viewer ne le peut pas. Une clé sans accès reçoit une 403.

link_id n'élargit pas non plus l'accès. L'identifiant de l'espace de travail dans le chemin est celui qui a été vérifié : un identifiant de lien emprunté à un autre espace de travail correspond à zéro ligne et renvoie une liste vide. C'est le bon comportement en cas d'échec : sans surprise, et sans fuite.

Paramètres de requête pour les statistiques de clics : dates, fuseau horaire et filtres

Six paramètres couvrent presque tous les appels à une API de statistiques de liens courts :

  • from et to, au format YYYY-MM-DD. Si vous omettez les deux, vous obtenez les 30 jours précédant la date actuelle. Si vous définissez seulement to, from est défini à 30 jours auparavant.
  • link_id pour limiter n'importe quel rapport à un lien, et host pour le limiter à un domaine de redirection, pratique quand un espace de travail utilise plusieurs domaines personnalisés.
  • interval pour timeseries, soit hour, soit day (valeur par défaut). Toute autre valeur fait échouer la requête.
  • limit pour les répartitions et les listes principales, de 1 à 200, avec 50 par défaut. links/top est l'exception : il renvoie 10 éléments sauf si vous en demandez davantage.

Voici le détail qui piège facilement. Les deux dates sont lues à minuit UTC, et la fenêtre inclut from mais s'arrête avant to. Pour toute la journée du 21 septembre, envoyez from=2026-09-21&to=2026-09-22. Envoyez to=2026-09-21 et vous n'obtiendrez aucun résultat de cette journée.

Le fuseau horaire est l'autre point important. Transmettez tz comme nom de fuseau horaire IANA, ou définissez un en-tête X-User-TZ, et timeseries découpe ses intervalles horaires ou quotidiens selon l'heure locale. Seuls les intervalles changent. La fenêtre from/to reste en UTC : un "hier" à Berlin nécessite donc une fenêtre légèrement plus large, ce que le script ci-dessous prend en charge. Une faute comme Europe/Berln renvoie une 400 avec unknown IANA timezone, ce qui vaut mieux qu'un graphique discrètement faux.

curl -s -G "https://api.elido.app/v1/workspaces/4821/analytics/timeseries" \
  -H "Authorization: Bearer $ELIDO_API_KEY" \
  --data-urlencode "from=2026-09-01" \
  --data-urlencode "to=2026-09-22" \
  --data-urlencode "interval=day" \
  --data-urlencode "tz=Europe/Berlin" \
  --data-urlencode "link_id=918273"

Formats de réponse utilisables dans votre code

Un point de série temporelle contient ts, un horodatage RFC 3339 indiquant le début de l'intervalle, et count. Les intervalles sans clics sont simplement absents. Comblez vous-même les trous avant de créer le graphique, sinon un dimanche calme disparaîtra de l'axe des abscisses.

{
  "items": [
    { "ts": "2026-09-19T00:00:00Z", "count": 412 },
    { "ts": "2026-09-21T00:00:00Z", "count": 388 }
  ]
}

Les répartitions renvoient {"items": [{"key": "DE", "count": 1204}, ...]}, triées par nombre. Le résumé est un objet plat :

{
  "total_clicks": 5310,
  "unique_visitors": 3987,
  "returning_visitors": 611,
  "avg_clicks_per_visitor": 1.33,
  "bounce_rate": 0.85
}

Deux définitions sont importantes. Les visiteurs uniques sont comptés par adresse IP distincte dans la fenêtre, donc un bureau derrière une même connexion ne compte qu'une fois. Et bounce_rate est une fraction, pas un pourcentage : la part des visiteurs uniques qui n'ont cliqué qu'une fois pendant la fenêtre. Cette valeur ne dit rien de ce qui s'est passé sur votre page d'arrivée, raison pour laquelle ces chiffres ne correspondent jamais aux sessions GA4 (l'article sur les clics et les sessions GA4 explique cet écart). Chaque donnée est filtrée des robots avant de vous parvenir, avec les mêmes nombres que ceux visibles dans les statistiques de liens Elido.

Parcourir les clics récents avec un curseur

clicks/recent est le rapport de l'API de suivi des liens qui renvoie les clics individuels, du plus récent au plus ancien. Chaque ligne contient ts, link_id, slug, host, referer, country_code, device, browser, destination, user_agent et ip. La taille d'une page va de 1 à 500, avec 100 par défaut.

Lorsqu'une page est complète, la réponse contient un next_cursor. Transmettez-le avec ?cursor= pour obtenir la page suivante, plus ancienne ; null signifie que vous avez atteint la fin de la fenêtre.

Pagination par curseur du rapport clicks/recent de l'API d'analyse des liens : la première requête renvoie la page de clics la plus récente avec next_cursor, le client le renvoie avec ?cursor= pour obtenir la page plus ancienne suivante, et un next_cursor null termine la boucle

Le curseur pointe vers l'horodatage et l'identifiant du lien de la dernière ligne. Deux clics sur le même lien à la même milliseconde peuvent être à égalité à la limite d'une page ; dans le pire des cas, vous aurez une ligne en double, jamais une ligne manquante. Dédupliquez sur la ligne complète lors du stockage. C'est rare, mais dix lignes de code à l'insertion valent mieux que d'expliquer une erreur d'une unité (off-by-one) au service financier.

Ces lignes comprennent des adresses IP et des agents utilisateur : ce sont donc des données personnelles. Si vous les copiez dans un entrepôt, gardez-les dans l'UE et définissez une durée de conservation ; le guide sur la résidence des données dans l'UE pour les équipes marketing explique le raisonnement. Pour la plupart des rapports, vous n'avez pas du tout besoin des lignes brutes, et un agrégat quotidien est plus respectueux pour tout le monde.

Un script de rapport quotidien des clics pour Slack ou une feuille

Voici la tâche que la plupart des personnes veulent vraiment : publier chaque matin dans un canal les clics de la veille et les cinq liens principaux. Elle utilise uniquement la bibliothèque standard Python et un webhook entrant Slack.

import datetime as dt, json, os, urllib.parse, urllib.request
from zoneinfo import ZoneInfo

BASE = "https://api.elido.app/v1/workspaces/{ws}/analytics/{report}"
WS, KEY = os.environ["ELIDO_WORKSPACE_ID"], os.environ["ELIDO_API_KEY"]
TZ = ZoneInfo("Europe/Berlin")

def report(name, **params):
    url = BASE.format(ws=WS, report=name) + "?" + urllib.parse.urlencode(params)
    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {KEY}"})
    with urllib.request.urlopen(req, timeout=20) as r:
        return json.load(r)

day = dt.datetime.now(TZ).date() - dt.timedelta(days=1)
# UTC window one day wider on each side, then keep only local hours of `day`
window = {"from": day - dt.timedelta(days=1), "to": day + dt.timedelta(days=2)}
hours = report("timeseries", interval="hour", tz="Europe/Berlin", **window)["items"]
total = sum(p["count"] for p in hours
            if dt.datetime.fromisoformat(p["ts"]).astimezone(TZ).date() == day)

top = report("links/top", limit=5, **{"from": day, "to": day + dt.timedelta(days=1)})
lines = [f"• {l['slug']}: {l['count']}" for l in top["items"]]
text = f"Clicks on {day} (Berlin): {total}\nTop links (UTC day):\n" + "\n".join(lines)

body = json.dumps({"text": text}).encode()
urllib.request.urlopen(urllib.request.Request(
    os.environ["SLACK_WEBHOOK_URL"], data=body,
    headers={"Content-Type": "application/json"}))

Exécutez-le avec cron à 07:00, heure locale. L'astuce des intervalles horaires transforme le total en véritable journée berlinoise plutôt qu'en journée UTC ; links/top n'a pas de tz, son classement reste donc basé sur la journée UTC, et le message le précise.

Vous préférez une feuille ? Les deux mêmes appels fonctionnent depuis Google Apps Script avec UrlFetchApp et un déclencheur quotidien, en ajoutant une ligne par jour. C'est aussi le chemin le moins coûteux vers un tableau de bord Looker Studio.

Si vous recopiez encore des chiffres depuis des captures d'écran chaque lundi, donnez une clé Viewer à un script et récupérez vos matinées.

Ce qui reste réservé au tableau de bord

L'interface accessible avec une clé API est en lecture seule et volontairement plus limitée que le tableau de bord. Ces éléments ne sont pas accessibles avec une clé :

  • L'export CSV des clics (clicks.csv). Le bouton Télécharger le CSV du tableau de bord est la voie prévue pour les fichiers volumineux.
  • Les entonnoirs, les cohortes, le rapport LTV, les cartes thermiques temporelles et géographiques et la vue de qualité du trafic.

Si un fichier déposé quelque part selon un calendrier vous suffit, les rapports envoyés par e-mail selon une programmation depuis le tableau de bord font cela sans code. Pour une extraction complète, comme lors d'un changement de fournisseur, voyez ce que vous pouvez exporter depuis un compte de liens courts et comment vérifier qu'elle est complète. Et il n'existe pas encore d'appel combiné "tout pour un lien", donc le tableau de bord par lien nécessite une requête par rapport. Le guide de démarrage rapide des SDK explique comment les exécuter en parallèle et réduire la cadence lorsque vous atteignez les limites de débit.

Interroger l'API d'analyse des clics ou utiliser des webhooks en temps réel

La version honnête : aujourd'hui, les données de clics sont accessibles uniquement par interrogation. Les webhooks Elido transmettent les événements de liens et de domaines, avec signature et nouvelles tentatives, mais un événement click.created par clic est prévu dans la feuille de route et n'est pas encore émis. Tout ce qui concerne les clics en temps réel passe par l'interrogation de clicks/recent.

Comparaison entre l'interrogation de l'API d'analyse des liens et les webhooks pour les données de clics : interroger clicks/recent avec un curseur conservé fonctionne aujourd'hui, tandis que les webhooks couvrent les événements de liens et de domaines et que l'événement click.created par clic est prévu mais pas encore émis

C'est moins pénible qu'il n'y paraît. Interrogez l'API toutes les minutes ou toutes les deux minutes, arrêtez-vous dès que vous atteignez une ligne déjà stockée et la charge reste minime, car une minute calme correspond à une petite page. Lorsque click.created sera disponible, le gestionnaire qui traite une ligne ne se souciera pas de savoir si elle provient d'une page ou d'un envoi push. Les compromis généraux sont présentés dans webhooks ou interrogation pour le suivi des clics et, si vous décidez lesquels de ces chiffres méritent vraiment un rapport, quoi mesurer dans les statistiques de liens courts est la lecture la plus concise.

Mon avis : commencez par le résumé quotidien. Presque toutes les équipes qui me demandent des clics en temps réel se satisfont des chiffres de la veille livrés avant le café.

Lire l'article de référence → Comment suivre des campagnes UTM de bout en bout

À lire sur le blog

Questions fréquentes

Elido propose-t-il une API d'analyse des clics sur les liens courts ?

Oui. Une clé API d'espace de travail peut appeler GET /v1/workspaces/{workspace_id}/analytics/{report} sur api.elido.app et lire 15 rapports : série temporelle, résumé, liens principaux, clics récents, six répartitions et cinq listes principales. La clé doit disposer de l'autorisation analytics.view, que tous les rôles intégrés, y compris Viewer, possèdent déjà.

Comment obtenir les statistiques de clics d'un lien court via l'API ?

Ajoutez link_id à la chaîne de requête de n'importe quel rapport. L'identifiant numérique du lien limite les séries temporelles, résumés, répartitions et clics récents à ce seul lien. L'espace de travail dans le chemin détermine toujours l'accès : un identifiant de lien provenant d'un autre espace de travail renvoie simplement zéro ligne, sans fuite de données.

Puis-je exporter les données de clics en CSV via l'API ?

Pas avec une clé API. L'export CSV des clics, les entonnoirs, les cohortes et le rapport LTV sont réservés au tableau de bord. Pour alimenter un flux automatisé, parcourez le rapport clicks/recent avec son curseur et écrivez vous-même les lignes, ou programmez un rapport par e-mail depuis le tableau de bord si un fichier dans une boîte de réception vous suffit.

Quel fuseau horaire l'API d'analyse des liens utilise-t-elle ?

Les dates from et to sont interprétées comme des jours calendaires UTC. Pour le rapport timeseries, vous pouvez transmettre tz avec un nom IANA tel que Europe/Berlin, ou envoyer un en-tête X-User-TZ, et les intervalles horaires ou quotidiens sont découpés dans ce fuseau. Un nom de fuseau inconnu renvoie une erreur 400.

Puis-je recevoir un webhook pour chaque clic sur un lien court ?

Pas encore. Un webhook click.created par clic est prévu dans la feuille de route, mais n'est pas émis aujourd'hui : les webhooks couvrent actuellement uniquement les événements de liens et de domaines. Pour obtenir des données de clics presque en temps réel, interrogez régulièrement le rapport clicks/recent et conservez le dernier curseur entre les exécutions.

Quel rôle de clé API peut lire les statistiques de clics ?

N'importe quel rôle intégré. La lecture des statistiques nécessite analytics.view, et le rôle Viewer l'a déjà. Le choix le plus sûr pour un script de rapport est donc une clé Viewer. Elle peut lire tous les rapports autorisés, mais ne peut pas créer, modifier ou supprimer des liens si la clé fuit un jour d'une machine exécutant cron.

Essayer Elido

Collez une URL, obtenez un lien court

Sans inscription. Lien actif 30 jours. Inscrivez-vous pour le garder pour toujours.

Gratuit, sans inscription · 2 par jour

Essayer Elido

Raccourcisseur d'URL hébergé en UE : domaines personnalisés, analyses approfondies et API ouverte. Forfait gratuit - sans carte bancaire.

Tags
link analytics api
click analytics api
short link stats api
url shortener analytics api
link tracking api
click data export

Lire la suite