Aller au contenu principal
9 min de lecture

API Données en temps réel

Accédez aux comptages de visiteurs en direct et aux données d'analyse en temps réel via des points de terminaison JSON publics. Ces points de terminaison sont conçus pour afficher des statistiques en direct sur votre site Web et ne nécessitent aucune authentification.

Vue d'ensemble

Les points de terminaison en temps réel offrent :

  • Accès instantané - Aucune authentification requise
  • Mises à jour en direct - Les données s'actualisent toutes les 5 à 30 secondes
  • Faible latence - Servi depuis le réseau périphérique global de Cloudflare
  • CORS activé - Sûr à appeler directement depuis les navigateurs

URL de base

Tous les points de terminaison en temps réel sont disponibles à :

https://api.zenovay.com/e

Comptage des visiteurs en direct

Obtenez le nombre actuel de visiteurs sur votre site Web :

GET/e/live/:trackingCode

Obtenir le comptage des visiteurs en direct

RequêteBash
curl -X GET 'https://api.zenovay.com/e/live/ZV_XXXXXXXXXXX'
Réponse (200 OK)JSON
{
"liveCount": 42,
"timestamp": "2025-01-20T14:30:00Z"
}

Champs de réponse :

ChampTypeDescription
liveCountnombreVisiteurs actuellement en ligne (actifs au cours des 5 dernières minutes)
timestampchaîneTimestamp ISO 8601 des données

Analyse en temps réel

Obtenez une analyse en temps réel complète incluant les visiteurs, les vues de page et les données géographiques :

GET/e/realtime/:websiteId

Obtenir les données d'analyse en temps réel

RequêteBash
curl -X GET 'https://api.zenovay.com/e/realtime/ws_abc123'
Réponse (200 OK)JSON
{
"visitors": {
  "current": 42,
  "today": 1234,
  "change": 12.5
},
"pageViews": {
  "current": 156,
  "today": 4567,
  "change": 8.3
},
"countries": [
  { "code": "US", "name": "United States", "count": 18 },
  { "code": "GB", "name": "United Kingdom", "count": 8 },
  { "code": "DE", "name": "Germany", "count": 6 }
],
"topPages": [
  { "path": "/", "visitors": 15 },
  { "path": "/pricing", "visitors": 8 },
  { "path": "/features", "visitors": 5 }
],
"timestamp": "2025-01-20T14:30:00Z"
}

Champs de réponse :

ChampTypeDescription
visitors.currentnombreVisiteurs en ligne maintenant
visitors.todaynombreTotal des visiteurs uniques aujourd'hui
visitors.changenombrePourcentage de changement par rapport à hier
pageViews.currentnombreVues de page au cours des 5 dernières minutes
pageViews.todaynombreTotal des vues de page aujourd'hui
countriestableauPays principaux par visiteurs actuels
topPagestableauPages principales par visiteurs actuels

Statistiques des visiteurs

Obtenez des statistiques détaillées des visiteurs incluant le taux de rebond et la durée de la session :

GET/e/stats/:trackingCode

Obtenir les statistiques des visiteurs

RequêteBash
curl -X GET 'https://api.zenovay.com/e/stats/ZV_XXXXXXXXXXX'
Réponse (200 OK)JSON
{
"visitors": {
  "live": 42,
  "today": 1234,
  "week": 8765,
  "month": 34521
},
"bounceRate": 0.42,
"avgSessionDuration": 185,
"pagesPerSession": 2.9,
"newVisitorRate": 0.65,
"returningVisitorRate": 0.35,
"timestamp": "2025-01-20T14:30:00Z"
}

Champs de réponse :

ChampTypeDescription
visitors.livenombreVisiteurs actuellement en ligne
visitors.todaynombreVisiteurs uniques aujourd'hui
visitors.weeknombreVisiteurs uniques cette semaine
visitors.monthnombreVisiteurs uniques ce mois
bounceRatenombreTaux de rebond (0-1)
avgSessionDurationnombreDurée moyenne de la session en secondes
pagesPerSessionnombreMoyenne de pages par session
newVisitorRatenombrePourcentage de nouveaux visiteurs
returningVisitorRatenombrePourcentage de visiteurs récurrents

Statut du site Web

Vérifiez si le suivi est actif pour un site Web :

GET/e/:trackingCode/status

Vérifier le statut du suivi

RequêteBash
curl -X GET 'https://api.zenovay.com/e/ZV_XXXXXXXXXXX/status'
Réponse (200 OK)JSON
{
"active": true,
"tracking_code": "ZV_XXXXXXXXXXX",
"domain": "example.com",
"last_event": "2025-01-20T14:29:55Z"
}

Intégration JavaScript

Compteur de visiteurs en direct basique

Afficher le comptage des visiteurs en direct sur votre site Web :

Live Visitor CounterJavaScript
class LiveVisitorCounter {
constructor(trackingCode, elementId) {
  this.trackingCode = trackingCode;
  this.element = document.getElementById(elementId);
  this.intervalId = null;
}

async fetchCount() {
  try {
    const response = await fetch(
      `https://api.zenovay.com/e/live/${this.trackingCode}`
    );
    const data = await response.json();
    this.updateDisplay(data.liveCount);
  } catch (error) {
    console.error('Failed to fetch visitor count:', error);
  }
}

updateDisplay(count) {
  if (this.element) {
    this.element.textContent = count.toLocaleString();
    this.element.classList.add('updated');
    setTimeout(() => this.element.classList.remove('updated'), 300);
  }
}

start(intervalMs = 30000) {
  this.fetchCount();
  this.intervalId = setInterval(() => this.fetchCount(), intervalMs);
}

stop() {
  if (this.intervalId) {
    clearInterval(this.intervalId);
  }
}
}

// Usage
const counter = new LiveVisitorCounter('ZV_XXXXXXXXXXX', 'visitor-count');
counter.start();

Tableau de bord en temps réel

Créer un mini tableau de bord d'analyse :

Real-Time DashboardJavaScript
async function updateDashboard(websiteId) {
try {
  const response = await fetch(
    `https://api.zenovay.com/e/realtime/${websiteId}`
  );
  const data = await response.json();

  // Update visitor counts
  document.getElementById('live-visitors').textContent = data.visitors.current;
  document.getElementById('today-visitors').textContent = data.visitors.today.toLocaleString();

  // Update pageviews
  document.getElementById('live-pageviews').textContent = data.pageViews.current;

  // Update top countries
  const countriesList = document.getElementById('top-countries');
  countriesList.innerHTML = data.countries
    .slice(0, 5)
    .map(c => `<li>${c.name}: ${c.count}</li>`)
    .join('');

  // Update top pages
  const pagesList = document.getElementById('top-pages');
  pagesList.innerHTML = data.topPages
    .slice(0, 5)
    .map(p => `<li>${p.path}: ${p.visitors}</li>`)
    .join('');

} catch (error) {
  console.error('Dashboard update failed:', error);
}
}

// Update every 30 seconds
setInterval(() => updateDashboard('ws_abc123'), 30000);
updateDashboard('ws_abc123');

Hook React

Hook React personnalisé pour les données en temps réel :

useRealtimeAnalytics HookTSX
import { useState, useEffect, useCallback } from 'react';

interface RealtimeData {
visitors: {
  current: number;
  today: number;
  change: number;
};
pageViews: {
  current: number;
  today: number;
  change: number;
};
countries: Array<{ code: string; name: string; count: number }>;
topPages: Array<{ path: string; visitors: number }>;
timestamp: string;
}

function useRealtimeAnalytics(websiteId: string, refreshInterval = 30000) {
const [data, setData] = useState<RealtimeData | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);

const fetchData = useCallback(async () => {
  try {
    const response = await fetch(
      `https://api.zenovay.com/e/realtime/${websiteId}`
    );
    if (!response.ok) throw new Error('Failed to fetch');
    const json = await response.json();
    setData(json);
    setError(null);
  } catch (err) {
    setError(err instanceof Error ? err : new Error('Unknown error'));
  } finally {
    setLoading(false);
  }
}, [websiteId]);

useEffect(() => {
  fetchData();
  const interval = setInterval(fetchData, refreshInterval);
  return () => clearInterval(interval);
}, [fetchData, refreshInterval]);

return { data, loading, error, refetch: fetchData };
}

// Usage in component
function AnalyticsDashboard({ websiteId }: { websiteId: string }) {
const { data, loading, error } = useRealtimeAnalytics(websiteId);

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!data) return null;

return (
  <div className="dashboard">
    <div className="stat">
      <span className="label">Live Visitors</span>
      <span className="value">{data.visitors.current}</span>
    </div>
    <div className="stat">
      <span className="label">Today</span>
      <span className="value">{data.visitors.today.toLocaleString()}</span>
    </div>
  </div>
);
}

Composable Vue

Composable Vue 3 pour les données en temps réel :

useRealtimeAnalytics ComposableTypeScript
import { ref, onMounted, onUnmounted } from 'vue';

interface RealtimeData {
visitors: { current: number; today: number; change: number };
pageViews: { current: number; today: number; change: number };
countries: Array<{ code: string; name: string; count: number }>;
topPages: Array<{ path: string; visitors: number }>;
}

export function useRealtimeAnalytics(websiteId: string, refreshInterval = 30000) {
const data = ref<RealtimeData | null>(null);
const loading = ref(true);
const error = ref<Error | null>(null);
let intervalId: number | null = null;

async function fetchData() {
  try {
    const response = await fetch(
      `https://api.zenovay.com/e/realtime/${websiteId}`
    );
    if (!response.ok) throw new Error('Failed to fetch');
    data.value = await response.json();
    error.value = null;
  } catch (err) {
    error.value = err instanceof Error ? err : new Error('Unknown error');
  } finally {
    loading.value = false;
  }
}

onMounted(() => {
  fetchData();
  intervalId = window.setInterval(fetchData, refreshInterval);
});

onUnmounted(() => {
  if (intervalId) clearInterval(intervalId);
});

return { data, loading, error, refetch: fetchData };
}

Limites de débit

Les points de terminaison en temps réel ont les limites de débit suivantes :

Point de terminaisonLimite de débitCache TTL
/e/live/:trackingCode1000 req/min5 secondes
/e/realtime/:websiteId500 req/min10 secondes
/e/stats/:trackingCode500 req/min30 secondes
/e/:trackingCode/status100 req/min60 secondes

Les données sont mises en cache à la périphérie. Plusieurs demandes dans le TTL du cache recevront les mêmes données, ce qui les rend sûres pour interroger fréquemment depuis du code côté client.

Configuration CORS

Tous les points de terminaison en temps réel supportent CORS et peuvent être appelés directement depuis les navigateurs :

CORS HeadersTEXT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Content-Type

Gestion des erreurs

Error Handling ExampleJavaScript
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
  try {
    const response = await fetch(url);

    if (response.status === 429) {
      // Rate limited - wait and retry
      const retryAfter = response.headers.get('Retry-After') || '60';
      await new Promise(r => setTimeout(r, parseInt(retryAfter) * 1000));
      continue;
    }

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }

    return await response.json();
  } catch (error) {
    if (i === maxRetries - 1) throw error;
    // Exponential backoff
    await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
  }
}
}

// Usage
try {
const data = await fetchWithRetry('https://api.zenovay.com/e/live/ZV_XXXXXXXXXXX');
console.log('Live visitors:', data.liveCount);
} catch (error) {
console.error('Failed after retries:', error);
}

Meilleures pratiques

  1. Mettre en cache localement - Stocker les données en mémoire pour éviter les demandes inutiles lors des mises à jour rapides de l'interface utilisateur
  2. Limiter le débit des mises à jour - Ne pas déclencher les mises à jour de l'interface utilisateur plus vite que le TTL du cache
  3. Gérer le mode hors ligne - Afficher les anciennes données avec un timestamp lorsque le réseau est indisponible
  4. Animer les changements - Les transitions fluides lorsque les comptages changent rendent l'interface utilisateur plus réactive
  5. Afficher les états de chargement - Afficher les chargeurs squelettes lors de la récupération initiale

Étapes suivantes

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