Pular para o conteúdo principal
9 min de leitura

API de Dados em Tempo Real

Acesse contagens de visitantes ao vivo e dados de análises em tempo real através de endpoints JSON públicos. Estes endpoints são projetados para exibir estatísticas ao vivo em seu site e não requerem autenticação.

Visão Geral

Os endpoints de tempo real fornecem:

  • Acesso instantâneo - Nenhuma autenticação necessária
  • Atualizações ao vivo - Dados são atualizados a cada 5-30 segundos
  • Baixa latência - Servido pela rede global de servidores da Cloudflare
  • CORS habilitado - Seguro para chamar diretamente de navegadores

URL Base

Todos os endpoints de tempo real estão disponíveis em:

https://api.zenovay.com/e

Contagem de Visitantes ao Vivo

Obtenha o número atual de visitantes em seu site:

GET/e/live/:trackingCode

Obter contagem de visitantes ao vivo

RequisiçãoBash
curl -X GET 'https://api.zenovay.com/e/live/ZV_XXXXXXXXXXX'
Resposta (200 OK)JSON
{
"liveCount": 42,
"timestamp": "2025-01-20T14:30:00Z"
}

Campos da Resposta:

CampoTipoDescrição
liveCountnumberVisitantes atuais online (ativos nos últimos 5 minutos)
timestampstringTimestamp ISO 8601 dos dados

Análises em Tempo Real

Obtenha análises abrangentes em tempo real, incluindo visitantes, visualizações de página e dados geográficos:

GET/e/realtime/:websiteId

Obter dados de análises em tempo real

RequisiçãoBash
curl -X GET 'https://api.zenovay.com/e/realtime/ws_abc123'
Resposta (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"
}

Campos da Resposta:

CampoTipoDescrição
visitors.currentnumberVisitantes online agora
visitors.todaynumberTotal de visitantes únicos hoje
visitors.changenumberMudança percentual em relação a ontem
pageViews.currentnumberVisualizações de página nos últimos 5 minutos
pageViews.todaynumberTotal de visualizações de página hoje
countriesarrayPaíses principais por visitantes atuais
topPagesarrayPáginas principais por visitantes atuais

Estatísticas de Visitantes

Obtenha estatísticas detalhadas de visitantes, incluindo taxa de rejeição e duração da sessão:

GET/e/stats/:trackingCode

Obter estatísticas de visitantes

RequisiçãoBash
curl -X GET 'https://api.zenovay.com/e/stats/ZV_XXXXXXXXXXX'
Resposta (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"
}

Campos da Resposta:

CampoTipoDescrição
visitors.livenumberVisitantes atuais online
visitors.todaynumberVisitantes únicos hoje
visitors.weeknumberVisitantes únicos esta semana
visitors.monthnumberVisitantes únicos este mês
bounceRatenumberTaxa de rejeição (0-1)
avgSessionDurationnumberDuração média da sessão em segundos
pagesPerSessionnumberMédia de páginas por sessão
newVisitorRatenumberPercentual de visitantes novos
returningVisitorRatenumberPercentual de visitantes recorrentes

Status do Site

Verifique se o rastreamento está ativo para um site:

GET/e/:trackingCode/status

Verificar status do rastreamento

RequisiçãoBash
curl -X GET 'https://api.zenovay.com/e/ZV_XXXXXXXXXXX/status'
Resposta (200 OK)JSON
{
"active": true,
"tracking_code": "ZV_XXXXXXXXXXX",
"domain": "example.com",
"last_event": "2025-01-20T14:29:55Z"
}

Integração com JavaScript

Contador de Visitantes ao Vivo

Exiba a contagem de visitantes ao vivo em seu site:

Contador de Visitantes ao VivoJavaScript
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);
  }
}
}

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

Painel de Análises em Tempo Real

Crie um painel de análises compacto:

Painel de Análises em Tempo RealJavaScript
async function updateDashboard(websiteId) {
try {
  const response = await fetch(
    `https://api.zenovay.com/e/realtime/${websiteId}`
  );
  const data = await response.json();

  // Atualizar contagens de visitantes
  document.getElementById('live-visitors').textContent = data.visitors.current;
  document.getElementById('today-visitors').textContent = data.visitors.today.toLocaleString();

  // Atualizar visualizações de página
  document.getElementById('live-pageviews').textContent = data.pageViews.current;

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

  // Atualizar páginas principais
  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);
}
}

// Atualizar a cada 30 segundos
setInterval(() => updateDashboard('ws_abc123'), 30000);
updateDashboard('ws_abc123');

Hook React

Hook React personalizado para dados em tempo real:

Hook useRealtimeAnalyticsTSX
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 };
}

// Uso em componente
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 para dados em tempo real:

Composable useRealtimeAnalyticsTypeScript
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 Taxa

Os endpoints de tempo real têm os seguintes limites de taxa:

EndpointLimite de TaxaTTL do Cache
/e/live/:trackingCode1000 req/min5 segundos
/e/realtime/:websiteId500 req/min10 segundos
/e/stats/:trackingCode500 req/min30 segundos
/e/:trackingCode/status100 req/min60 segundos

Os dados são armazenados em cache na borda. Múltiplas requisições dentro do TTL do cache receberão os mesmos dados, tornando seguro fazer polling com frequência a partir do código no lado do cliente.

Configuração de CORS

Todos os endpoints de tempo real suportam CORS e podem ser chamados diretamente de navegadores:

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

Tratamento de Erros

Exemplo de Tratamento de ErrosJavaScript
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
  try {
    const response = await fetch(url);

    if (response.status === 429) {
      // Taxa limitada - aguarde e tente novamente
      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;
    // Backoff exponencial
    await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
  }
}
}

// Uso
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);
}

Melhores Práticas

  1. Cache local - Armazene dados em memória para evitar requisições desnecessárias durante atualizações rápidas da IU
  2. Debounce de atualizações - Não dispare atualizações de IU mais rápido que o TTL do cache
  3. Lidar com offline - Mostre dados antigos com um timestamp quando a rede não estiver disponível
  4. Animar mudanças - Transições suaves quando contagens mudam fazem a IU parecer mais responsiva
  5. Mostrar estados de carregamento - Exiba carregadores de esqueleto durante busca inicial

Próximos Passos

Esta página foi útil?