API de lecture

Récupérez vos statistiques par programme : tableaux de bord internes, rapports, exports. Réservée aux plans Pro et Agence (et à l'essai actif).

Authentification

Créez un jeton dans Espace membre → Jetons API, puis passez-le en Bearer :

curl -H "Authorization: Bearer VOTRE_JETON" \
  "https://quietmetrics.dev/api/v1/stats/qm_pub_XXXXXXXXXXXXXXXXX/summary?period=30d"

Toutes les routes sont préfixées par /api/v1/stats/{clé_publique_du_site}. Un jeton ne donne accès qu'aux sites de votre compte ; un site qui ne vous appartient pas répond 404 (aucune fuite d'existence).

Endpoints

Endpoint Contenu
GET /summary KPIs de la période + période précédente (comparaison)
GET /timeseries Série temporelle, un point par jour (courbe)
GET /breakdown Top valeurs d'une dimension ({label, value})
GET /realtime Visiteurs actifs sur les 5 dernières minutes ({"visitors": N})

Paramètres communs

period : les préréglages du dashboard, soit today, yesterday, 7d, 30d (défaut), month, last_month, 12m. Les dates sont calculées dans le fuseau du site. Un préréglage inconnu retombe sur 30d.

filters reprend les filtres des clics du dashboard, au format dimension:valeur, séparés par ; :

?filters=country:FR;device:mobile
?filters=page:/tarifs
?filters=channel:organic;browser:Firefox

dimension (breakdown) : page, entry (pages d'entrée), referrer, channel, campaign, country, region, browser, os, device, lang, event. Dimension inconnue → 422.

limit (breakdown) : nombre de lignes, 10 par défaut, 1 000 maximum.

Exemples de réponse

GET /summary?period=30d :

{
    "site": "monsite.fr",
    "period": { "preset": "30d", "from": "2026-06-16", "to": "2026-07-16" },
    "filters": {},
    "kpis": { "visitors": 4210, "pageviews": 9873, "bounce_rate": 0.47, "avg_duration": 74 },
    "previous": { "visitors": 3877, "pageviews": 9145, "bounce_rate": 0.49, "avg_duration": 71 }
}

GET /breakdown?dimension=page&limit=3 :

{
    "dimension": "page",
    "period": { "from": "2026-06-16", "to": "2026-07-16" },
    "data": [
        { "label": "/", "value": 3120 },
        { "label": "/tarifs", "value": 1284 },
        { "label": "/docs", "value": 977 }
    ],
    "capped": {
        "any": true,
        "dimensions": [
            { "dimension": "page", "days": 2, "days_repaired": 2, "folded_values": 2812, "cap": 2000 },
            { "dimension": "referrer", "days": 1, "days_repaired": 0, "folded_values": null, "cap": 500 }
        ]
    }
}

Plafond de cardinalité (capped)

Chaque site mesure un nombre borné de valeurs distinctes par jour et par dimension. Au-delà, les valeurs suivantes sont comptées ensemble sous un libellé unique : le détail est regroupé, aucune visite n'est perdue et les totaux restent exacts. breakdown annonce cet état dans la clé capped :

  • any est toujours présent et dimensions toujours une liste : le schéma ne varie pas selon l'état du site, aucun branchement n'est nécessaire pour le lire.
  • dimension est la dimension plafonnée, pas celle que vous avez demandée. entry et exit sont regroupés par le plafond page ; source et medium sont regroupés par le plafond campaign.
  • days compte les journées locales plafonnées sur la période ; cap est le seuil le plus haut réellement appliqué (il peut varier si un relèvement est posé en cours de période).
  • folded_values: null ne signifie PAS zéro. Le nombre de valeurs regroupées n'est connu qu'après la reconstruction de nuit, qui ne traite une journée qu'à J+2. null veut dire « plafond atteint, nombre encore inconnu » ; 0 veut dire « journée reconstruite, aucune valeur regroupée ». Afficher 0 à la place de null annoncerait à vos utilisateurs qu'ils ne perdent aucun détail, ce qui est faux.
  • days_repaired dit sur combien des days journées le compte est connu. Si days_repaired < days, folded_values est une somme partielle.

summary et timeseries ne portent pas cette clé : elles ne lisent aucune dimension et sont insensibles au plafonnement.

L'export CSV du dashboard porte le même indicateur, mais dans l'en-tête HTTP X-Cardinality-Capped plutôt que dans le corps du fichier : {"capped":false}, ou {"capped":true,"dimension":"page","days":1,"days_repaired":1,"folded_values":2812,"cap":2000} cadré sur la seule dimension exportée. Le corps du CSV reste une donnée machine pure, sans ligne de métadonnée : aucune ligne synthétique ne peut ainsi fausser un total ni faire échouer un analyseur à nombre de colonnes fixe.

Ce plafond peut être relevé pour votre site : écrivez au support.

Exemple PHP

$response = json_decode(file_get_contents(
    'https://quietmetrics.dev/api/v1/stats/qm_pub_XXXX/summary?period=7d',
    false,
    stream_context_create(['http' => ['header' => "Authorization: Bearer VOTRE_JETON\r\nAccept: application/json"]])
), true);

echo $response['kpis']['visitors'];

Erreurs

Code Signification
401 Jeton absent, invalide ou révoqué
403 Le site est à vous mais votre plan n'ouvre pas l'API (ou l'essai a expiré)
404 Site inconnu, ou appartenant à un autre compte
422 Dimension de breakdown inconnue

Bonnes pratiques

  • Mettez en cache côté client : interroger toutes les heures suffit largement. Attention toutefois, une journée close n'est pas définitivement figée : la reconstruction de nuit repasse sur les journées plafonnées et peut en recalculer les agrégats jusqu'à deux jours après. Prévoyez donc, sur les deux derniers jours, un cache court ou une réinterrogation ; au-delà, les valeurs ne bougent plus.
  • Un jeton par usage (un pour le dashboard interne, un pour le rapport mensuel) : la révocation reste chirurgicale.
  • Pour un export ponctuel, chaque vue du dashboard s'exporte aussi en CSV depuis l'espace membre : pas besoin d'écrire du code.

Vous ne trouvez pas votre réponse ?

Le support répond en français, les jours ouvrés.