Aller au contenu principal
15 min de lecture

API Externe

L'API Externe vous permet d'intégrer les données analytiques de Zenovay sur vos sites Web. Utilisez votre clé API pour récupérer les compteurs de visiteurs en direct, les résumés analytiques, les statistiques de pages, et bien plus.

URL de base

Toutes les requêtes vers l'API Externe doivent être adressées à :

https://api.zenovay.com/api/external/v1

Authentification

Les points de terminaison de l'API Externe nécessitent une clé API transmise dans l'en-tête de la requête :

En-tête de clé APIBash
curl -X GET 'https://api.zenovay.com/api/external/v1/websites' \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json'

Générez votre clé API à Paramètres → Sécurité → Clés API. Chaque clé peut avoir des permissions spécifiques (lecture, écriture, administrateur).

L'API Externe nécessite un plan payant. Les comptes du niveau gratuit reçoivent une réponse 403 API_PAID_PLAN_REQUIRED sur chaque point de terminaison. Passez à un plan Pro, Scale ou Enterprise pour utiliser les clés API programmatiquement.

Points de terminaison des comptes

Récupérer l'utilisation du compte

Récupérez vos statistiques d'utilisation du compte et vos limites :

GET/api/external/v1/usage

Récupérer l'utilisation du compte et les limites

RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/usage' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"usage": {
  "websites": 5,
  "pageviews_this_month": 125000,
  "events_this_month": 45000
},
"limits": {
  "websites": 10,
  "pageviews_per_month": 500000,
  "events_per_month": 100000
},
"plan": "pro",
"period": {
  "start": "2025-01-01T00:00:00Z",
  "end": "2025-01-31T23:59:59Z"
}
}

Points de terminaison des sites Web

Lister les sites Web

Récupérez tous les sites Web liés à votre compte :

GET/api/external/v1/websites

Lister tous les sites Web suivis

RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/websites' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"websites": [
  {
    "id": "ws_abc123",
    "domain": "example.com",
    "name": "Example Website",
    "tracking_code": "ZV_XXXXXXXXXXX",
    "created_at": "2025-01-01T00:00:00Z",
    "live_visitors": 42
  },
  {
    "id": "ws_def456",
    "domain": "shop.example.com",
    "name": "Example Shop",
    "tracking_code": "ZV_YYYYYYYYYYY",
    "created_at": "2025-01-10T00:00:00Z",
    "live_visitors": 18
  }
],
"total": 2
}

Récupérer les détails du site Web

Récupérez les détails d'un site Web spécifique :

GET/api/external/v1/websites/:websiteId

Récupérer les détails du site Web

RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/websites/ws_abc123' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"website": {
  "id": "ws_abc123",
  "domain": "example.com",
  "name": "Example Website",
  "tracking_code": "ZV_XXXXXXXXXXX",
  "created_at": "2025-01-01T00:00:00Z",
  "settings": {
    "track_outbound_links": true,
    "track_downloads": true,
    "session_replay": true
  }
},
"stats": {
  "live_visitors": 42,
  "today_pageviews": 1234,
  "today_visitors": 567
}
}

Points de terminaison analytiques

Récupérer le résumé analytique

Récupérez les données analytiques complètes pour un site Web :

GET/api/external/v1/analytics/:websiteId

Récupérer l'aperçu analytique

Paramètres de requête :

ParamètreTypeObligatoireDescription
timeRangestringNonPlage de temps : today, 7d, 30d, 90d (défaut : 7d)
RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/analytics/ws_abc123?timeRange=30d' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"summary": {
  "visitors": 12543,
  "pageviews": 45231,
  "sessions": 15420,
  "bounce_rate": 0.42,
  "avg_session_duration": 185,
  "pages_per_session": 2.9
},
"period": {
  "start": "2024-12-21T00:00:00Z",
  "end": "2025-01-20T23:59:59Z"
},
"live_visitors": 42
}

Récupérer les données des visiteurs

Récupérez les informations sur les visiteurs avec filtrage optionnel :

GET/api/external/v1/analytics/:websiteId/visitors

Récupérer les données des visiteurs

Paramètres de requête :

ParamètreTypeObligatoireDescription
timeRangestringNonPlage de temps : today, 7d, 30d, 90d
limitintegerNonNombre maximum de résultats (défaut : 50, max : 100)
offsetintegerNonDécalage de pagination
RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/analytics/ws_abc123/visitors?timeRange=7d&limit=10' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"visitors": [
  {
    "visitor_id": "vis_abc123",
    "first_seen": "2025-01-15T10:00:00Z",
    "last_seen": "2025-01-20T14:30:00Z",
    "total_sessions": 8,
    "total_pageviews": 45,
    "value_score": 87,
    "country": "US",
    "device": "desktop"
  }
],
"total": 1234,
"limit": 10,
"offset": 0
}

Récupérer les analyses de pages

Récupérez les statistiques au niveau des pages :

GET/api/external/v1/analytics/:websiteId/pages

Récupérer les pages principales

Paramètres de requête :

ParamètreTypeObligatoireDescription
timeRangestringNonPlage de temps : today, 7d, 30d, 90d
limitintegerNonNombre maximum de résultats (défaut : 20)
RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/analytics/ws_abc123/pages?timeRange=7d&limit=10' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"pages": [
  {
    "path": "/",
    "title": "Home",
    "views": 5423,
    "unique_visitors": 3241,
    "avg_time_on_page": 125,
    "bounce_rate": 0.35
  },
  {
    "path": "/pricing",
    "title": "Pricing",
    "views": 2134,
    "unique_visitors": 1876,
    "avg_time_on_page": 210,
    "bounce_rate": 0.28
  }
]
}

Récupérer les données géographiques

Récupérez les données des visiteurs par pays :

GET/api/external/v1/analytics/:websiteId/countries

Récupérer la répartition géographique

Paramètres de requête :

ParamètreTypeObligatoireDescription
timeRangestringNonPlage de temps : today, 7d, 30d, 90d
RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/analytics/ws_abc123/countries?timeRange=30d' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"countries": [
  {
    "code": "US",
    "name": "United States",
    "visitors": 4521,
    "percentage": 36.1
  },
  {
    "code": "GB",
    "name": "United Kingdom",
    "visitors": 1823,
    "percentage": 14.5
  },
  {
    "code": "DE",
    "name": "Germany",
    "visitors": 1456,
    "percentage": 11.6
  }
]
}

Récupérer la répartition technologique

Récupérez les statistiques des appareils, des navigateurs et des systèmes d'exploitation :

GET/api/external/v1/analytics/:websiteId/technology

Récupérer la répartition technologique

Paramètres de requête :

ParamètreTypeObligatoireDescription
timeRangestringNonPlage de temps : today, 7d, 30d, 90d
RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/analytics/ws_abc123/technology?timeRange=7d' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"devices": [
  { "type": "desktop", "visitors": 7234, "percentage": 57.7 },
  { "type": "mobile", "visitors": 4521, "percentage": 36.1 },
  { "type": "tablet", "visitors": 788, "percentage": 6.3 }
],
"browsers": [
  { "name": "Chrome", "visitors": 6543, "percentage": 52.2 },
  { "name": "Safari", "visitors": 3421, "percentage": 27.3 },
  { "name": "Firefox", "visitors": 1234, "percentage": 9.8 }
],
"operating_systems": [
  { "name": "Windows", "visitors": 4521, "percentage": 36.1 },
  { "name": "macOS", "visitors": 3234, "percentage": 25.8 },
  { "name": "iOS", "visitors": 2876, "percentage": 22.9 }
]
}

Points de terminaison avancés

Récupérer les pages de la carte thermique

Listez les pages avec des données de carte thermique :

GET/api/external/v1/heatmaps/:websiteId/pages

Lister les pages de la carte thermique

RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/heatmaps/ws_abc123/pages' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"pages": [
  {
    "url": "/",
    "title": "Home",
    "total_clicks": 12543,
    "total_sessions": 4521,
    "last_updated": "2025-01-20T14:30:00Z"
  },
  {
    "url": "/pricing",
    "title": "Pricing",
    "total_clicks": 8765,
    "total_sessions": 2134,
    "last_updated": "2025-01-20T14:25:00Z"
  }
]
}

Récupérer les rediffusions de session

Listez les sessions enregistrées :

GET/api/external/v1/replays/:websiteId/sessions

Lister les rediffusions de session

RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/replays/ws_abc123/sessions' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"sessions": [
  {
    "session_id": "sess_abc123",
    "visitor_id": "vis_xyz789",
    "started_at": "2025-01-20T14:00:00Z",
    "duration": 245,
    "pages_visited": 5,
    "country": "US",
    "device": "desktop"
  }
],
"total": 156
}

Récupérer les groupes d'erreurs

Listez les groupes d'erreurs JavaScript :

GET/api/external/v1/errors/:websiteId/groups

Lister les groupes d'erreurs

RequêteBash
curl -X GET 'https://api.zenovay.com/api/external/v1/errors/ws_abc123/groups' \
-H 'X-API-Key: YOUR_API_KEY'
Réponse (200 OK)JSON
{
"groups": [
  {
    "fingerprint": "err_abc123",
    "message": "Cannot read property 'length' of undefined",
    "type": "TypeError",
    "occurrences": 45,
    "affected_users": 23,
    "first_seen": "2025-01-15T10:00:00Z",
    "last_seen": "2025-01-20T14:30:00Z"
  }
],
"total": 12
}

API Stats (parité Plausible, Pro+)

L'API Stats expose trois points de terminaison compatibles avec Plausible pour les requêtes analytiques programmatiques. Utilisez-les pour construire des tableaux de bord personnalisés, intégrer des métriques en direct dans les outils de BI ou migrer depuis Plausible avec un minimum de modifications de code.

Plan requis : Pro, Scale ou Enterprise. Comme pour le reste de l'API Externe, les comptes du niveau gratuit reçoivent une réponse 403 API_PAID_PLAN_REQUIRED.

Points de terminaison

Point de terminaisonObjectif
GET /stats/aggregateMétriques en nombre unique sur une période (totaux, taux, durées).
GET /stats/timeseriesSérie temporelle à buckets (une ligne par jour, heure ou mois).
GET /stats/breakdownMétriques groupées (pages principales, pays principaux, navigateurs principaux, …).

Spec OpenAPI : /api/external/v1/openapi.json (en direct, public, aucune authentification requise pour la spec elle-même).

Paramètres courants

ParamObligatoireDescription
site_idouiUUID du site Web. Trouvez-le dans l'URL de votre tableau de bord ou via GET /websites.
periodouiday, 7d, 30d, month, 6mo, 12mo, ou custom:YYYY-MM-DD,YYYY-MM-DD (max 366 jours).
datenonAncre ISO 8601 pour la période (défaut = aujourd'hui).
metricsouiSéparé par des virgules. Autorisé : visitors, pageviews, visit_duration, bounce_rate, events.
filtersnonStyle Plausible : country==US;browser==Chrome;page!=/admin. Voir Filtres ci-dessous.

GET /stats/aggregate

Retourne les valeurs en nombre unique pour chaque métrique demandée sur une période.

GET/api/external/v1/stats/aggregate

Agréguer les métriques sur une période

Requête — visiteurs et pages vues sur les 7 derniers joursBash
curl -G 'https://api.zenovay.com/api/external/v1/stats/aggregate' \
-H 'X-API-Key: YOUR_API_KEY' \
--data-urlencode 'site_id=00000000-0000-0000-0000-000000000001' \
--data-urlencode 'period=7d' \
--data-urlencode 'metrics=visitors,pageviews,bounce_rate'
Réponse (200 OK)JSON
{
"success": true,
"data": {
  "results": {
    "visitors":    { "value": 12453 },
    "pageviews":   { "value": 38219 },
    "bounce_rate": { "value": 42.1 }
  },
  "meta": {
    "period": "7d",
    "period_start": "2026-05-07T00:00:00.000Z",
    "period_end":   "2026-05-13T23:59:59.999Z",
    "filters_applied": []
  }
},
"timestamp": "2026-05-14T08:30:00.000Z"
}

GET /stats/timeseries

Retourne une ligne par bucket sur la période. L'intervalle par défaut est day ; interval=hour nécessite period=day ; interval=month nécessite une period de 6mo, 12mo, month, ou custom.

GET/api/external/v1/stats/timeseries

Série temporelle à buckets

Requête — visiteurs quotidiens sur les 30 derniers joursBash
curl -G 'https://api.zenovay.com/api/external/v1/stats/timeseries' \
-H 'X-API-Key: YOUR_API_KEY' \
--data-urlencode 'site_id=00000000-0000-0000-0000-000000000001' \
--data-urlencode 'period=30d' \
--data-urlencode 'metrics=visitors,pageviews' \
--data-urlencode 'interval=day'
Réponse (200 OK)JSON
{
"success": true,
"data": {
  "results": [
    { "date": "2026-04-14", "visitors": 1820, "pageviews": 5640 },
    { "date": "2026-04-15", "visitors": 1933, "pageviews": 5921 }
  ],
  "meta": {
    "period": "30d",
    "interval": "day",
    "period_start": "2026-04-14T00:00:00.000Z",
    "period_end":   "2026-05-13T23:59:59.999Z",
    "filters_applied": []
  }
},
"timestamp": "2026-05-14T08:30:00.000Z"
}

La réponse est dense — les jours sans trafic apparaissent quand même avec visitors: 0. Cela garde les bibliothèques de graphiques heureuses sans remplissage d'écarts côté client.

GET /stats/breakdown

Retourne les métriques groupées par une dimension, triées par visiteurs décroissants.

GET/api/external/v1/stats/breakdown

Métriques groupées (pages principales, pays principaux, …)

Requête — 10 pages principales par visiteurs sur les 7 derniers joursBash
curl -G 'https://api.zenovay.com/api/external/v1/stats/breakdown' \
-H 'X-API-Key: YOUR_API_KEY' \
--data-urlencode 'site_id=00000000-0000-0000-0000-000000000001' \
--data-urlencode 'period=7d' \
--data-urlencode 'property=event:page' \
--data-urlencode 'metrics=visitors,pageviews' \
--data-urlencode 'limit=10'
Réponse (200 OK)JSON
{
"success": true,
"data": {
  "results": [
    { "page": "/pricing",      "visitors": 4421, "pageviews": 4421 },
    { "page": "/blog/launch",  "visitors": 2018, "pageviews": 2018 }
  ],
  "meta": {
    "period": "7d",
    "property": "event:page",
    "pagination": { "page": 1, "limit": 10, "total": 47, "has_more": true }
  }
},
"timestamp": "2026-05-14T08:30:00.000Z"
}

Valeurs property autorisées : event:page, visit:country, visit:browser, visit:device, visit:os, visit:source.

Pagination : limit est 1–1000 (défaut 100) ; page est indexé à partir de 1 (défaut 1).

Filtres

Clauses de filtre de style Plausible, jointes avec ; :

  • country==US — égal à
  • country==US,CA,GB — égal à l'un de
  • browser!=Safari — non égal à

Clés autorisées : country, browser, device, os, source, utm_source, utm_medium, utm_campaign, page.

Limitation V1 : Lorsque filters est fourni, seule la métrique visitors est calculée ; les autres métriques retournent null avec un drapeau meta.note. Le support complet des filtres sur toutes les métriques sera disponible dans V2.

Exemple JavaScript

Récupérer les métriques agrégées avec fetch()JavaScript
async function getAggregate(siteId, period = '7d', metrics = ['visitors', 'pageviews']) {
const url = new URL('https://api.zenovay.com/api/external/v1/stats/aggregate');
url.searchParams.set('site_id', siteId);
url.searchParams.set('period', period);
url.searchParams.set('metrics', metrics.join(','));

const res = await fetch(url, {
  headers: { 'X-API-Key': process.env.ZENOVAY_API_KEY }
});
if (!res.ok) {
  const err = await res.json();
  throw new Error(`${err.error.code}: ${err.error.message}`);
}
return res.json();
}

const data = await getAggregate('00000000-0000-0000-0000-000000000001', '7d');
console.log(`Visitors: ${data.data.results.visitors.value}`);

Codes d'erreur

L'API Stats retourne des codes sur lesquels vous pouvez baser votre UX de dégradation :

CodeHTTPQuand
MISSING_SITE_ID400Le paramètre de requête site_id est obligatoire.
MISSING_METRICS400Le paramètre de requête metrics est obligatoire.
MISSING_PERIOD400Le paramètre de requête period est obligatoire.
MISSING_PROPERTY400/stats/breakdown nécessite property.
INVALID_METRIC400L'une des métriques séparées par des virgules ne figure pas dans la liste autorisée.
INVALID_PROPERTY400La propriété de répartition n'est pas autorisée.
INVALID_PERIOD400La période n'est pas day/7d/30d/month/6mo/12mo/custom:....
INVALID_CUSTOM_PERIOD400Syntaxe custom: mal formée ou date(s) invalide(s).
PERIOD_TOO_LONG400Période personnalisée > 366 jours.
INTERVAL_PERIOD_MISMATCH400Par exemple interval=hour avec period=7d.
UNKNOWN_FILTER_KEY400La clé de filtre ne figure pas dans la liste autorisée.
EMPTY_FILTER_VALUE400La clause de filtre n'a pas de valeur.
FORBIDDEN403Compte du niveau gratuit (l'API Externe nécessite un plan payant), ou site_id hors de la portée de la clé API.
NOT_FOUND404Le site n'existe pas ou est caché pour cette clé.
(limite de débit)429Limite de débit par plan dépassée. L'en-tête Retry-After indique le temps d'attente.

Migration depuis Plausible

La forme des paramètres est intentionnellement compatible avec Plausible :

PlausibleZenovayRemarques
site_idsite_idPlausible utilise une chaîne de domaine ; Zenovay utilise un UUID. Mappez domain → site_id une fois via GET /websites.
period, dateperiod, dateMême liste autorisée + custom:YYYY-MM-DD,YYYY-MM-DD.
metricsmetricsvisitors, pageviews, bounce_rate, visit_duration de Plausible mappent tous 1:1. events est approximé en V1 comme pageviews.
propertypropertyMême forme : event:page, visit:country, etc.
filters (string v1)filtersMême forme key==value;key!=value. Les filtres de tableau JSON v2 arrivent dans Zenovay V2.

Exemple JavaScript

Intégrez les données analytiques sur votre site Web en utilisant JavaScript :

Récupérer et afficher les analysesJavaScript
// Récupérer les données analytiques depuis votre backend
async function fetchAnalytics() {
const response = await fetch('/api/analytics', {
  headers: {
    'X-API-Key': 'YOUR_API_KEY' // Utilisez un proxy côté serveur pour protéger votre clé
  }
});

const data = await response.json();

// Mettez à jour votre interface utilisateur
document.getElementById('live-visitors').textContent = data.live_visitors;
document.getElementById('total-pageviews').textContent = data.summary.pageviews.toLocaleString();
document.getElementById('bounce-rate').textContent = (data.summary.bounce_rate * 100).toFixed(1) + '%';
}

// Actualiser toutes les 30 secondes
fetchAnalytics();
setInterval(fetchAnalytics, 30000);

Note de sécurité : N'exposez jamais votre clé API dans le code côté client. Créez un point de terminaison proxy côté serveur qui appelle l'API Zenovay avec votre clé, puis ayez votre frontend qui appelle votre proxy.

Limites de débit

Limites de débit de l'API Externe par plan :

PlanRequêtes/minute (cible)Limite mensuelle (cap dur)
GratuitN/A (API non disponible)N/A
Pro3010 000
Scale60100 000
Enterprise1201 000 000

Comment la limitation de débit est appliquée. Le nombre par minute est une cible, pas un plafond dur. Nous utilisons la limitation de débit d'arête de Cloudflare, qui est par centre de données avec une petite allocation de rafales — un client soutenu peut temporairement voir 1,5–3× le nombre affiché avant d'être limité, surtout lorsque les requêtes se déploient sur les régions. Le cap dur est le quota mensuel, appliqué atomiquement contre votre compte indépendamment du POP d'arête qui traite la requête. Planifiez les charges de travail sensibles à la capacité par rapport au quota mensuel ; traitez la cible par minute comme un signal de lissage.

Réponses d'erreur

Code de statutDescription
200Succès
400Mauvaise requête - Paramètres invalides
401Non autorisé - Clé API invalide ou manquante
403Interdit - Permissions insuffisantes
404Non trouvé - Site Web non trouvé
429Trop de requêtes - Limite de débit dépassée
500Erreur interne du serveur
Exemple de réponse d'erreurJSON
{
"error": {
  "code": "unauthorized",
  "message": "Invalid API key provided"
}
}

Prochaines étapes

Cette page vous a-t-elle été utile ?