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:
/e/live/:trackingCodeObter contagem de visitantes ao vivo
curl -X GET 'https://api.zenovay.com/e/live/ZV_XXXXXXXXXXX'{
"liveCount": 42,
"timestamp": "2025-01-20T14:30:00Z"
}Campos da Resposta:
| Campo | Tipo | Descrição |
|---|---|---|
liveCount | number | Visitantes atuais online (ativos nos últimos 5 minutos) |
timestamp | string | Timestamp 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:
/e/realtime/:websiteIdObter dados de análises em tempo real
curl -X GET 'https://api.zenovay.com/e/realtime/ws_abc123'{
"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:
| Campo | Tipo | Descrição |
|---|---|---|
visitors.current | number | Visitantes online agora |
visitors.today | number | Total de visitantes únicos hoje |
visitors.change | number | Mudança percentual em relação a ontem |
pageViews.current | number | Visualizações de página nos últimos 5 minutos |
pageViews.today | number | Total de visualizações de página hoje |
countries | array | Países principais por visitantes atuais |
topPages | array | Pá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:
/e/stats/:trackingCodeObter estatísticas de visitantes
curl -X GET 'https://api.zenovay.com/e/stats/ZV_XXXXXXXXXXX'{
"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:
| Campo | Tipo | Descrição |
|---|---|---|
visitors.live | number | Visitantes atuais online |
visitors.today | number | Visitantes únicos hoje |
visitors.week | number | Visitantes únicos esta semana |
visitors.month | number | Visitantes únicos este mês |
bounceRate | number | Taxa de rejeição (0-1) |
avgSessionDuration | number | Duração média da sessão em segundos |
pagesPerSession | number | Média de páginas por sessão |
newVisitorRate | number | Percentual de visitantes novos |
returningVisitorRate | number | Percentual de visitantes recorrentes |
Status do Site
Verifique se o rastreamento está ativo para um site:
/e/:trackingCode/statusVerificar status do rastreamento
curl -X GET 'https://api.zenovay.com/e/ZV_XXXXXXXXXXX/status'{
"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:
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:
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:
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:
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:
| Endpoint | Limite de Taxa | TTL do Cache |
|---|---|---|
/e/live/:trackingCode | 1000 req/min | 5 segundos |
/e/realtime/:websiteId | 500 req/min | 10 segundos |
/e/stats/:trackingCode | 500 req/min | 30 segundos |
/e/:trackingCode/status | 100 req/min | 60 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:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Content-TypeTratamento de Erros
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
- Cache local - Armazene dados em memória para evitar requisições desnecessárias durante atualizações rápidas da IU
- Debounce de atualizações - Não dispare atualizações de IU mais rápido que o TTL do cache
- Lidar com offline - Mostre dados antigos com um timestamp quando a rede não estiver disponível
- Animar mudanças - Transições suaves quando contagens mudam fazem a IU parecer mais responsiva
- Mostrar estados de carregamento - Exiba carregadores de esqueleto durante busca inicial
Próximos Passos
- Widgets - Widgets incorporáveis pré-construídos
- API Externa - API completa com autenticação
- Eventos Personalizados - Rastreie ações de usuários personalizadas