Access real-time analytics data from Zenovay to build custom dashboards and monitoring tools.
Real-Time Options
| Use Case | Best Approach |
|---|---|
| Live visitor count | Public live endpoint (no API key needed) |
| Custom dashboard | External API polling |
| Historical data | External API with time range filters |
| In-app real-time | Zenovay dashboard (uses Supabase real-time internally) |
Live Visitor Count
The live endpoint is public and does not require an API key. It returns the current number of active visitors:
GET https://api.zenovay.com/live/YOUR_TRACKING_CODE
Example
async function getLiveVisitors(trackingCode) {
const response = await fetch(`https://api.zenovay.com/live/${trackingCode}`);
const data = await response.json();
return data;
}
// Display live count
const data = await getLiveVisitors('YOUR_TRACKING_CODE');
console.log(`Active visitors: ${data.count}`);
Polling for Live Updates
function startLivePolling(trackingCode, callback, interval = 10000) {
async function poll() {
try {
const response = await fetch(`https://api.zenovay.com/live/${trackingCode}`);
const data = await response.json();
callback(data);
} catch (error) {
console.error('Live polling error:', error);
}
}
// Initial fetch
poll();
// Poll at interval (default: every 10 seconds)
return setInterval(poll, interval);
}
// Usage
const pollId = startLivePolling('YOUR_TRACKING_CODE', (data) => {
document.getElementById('visitor-count').textContent = data.count;
});
// Stop polling when done
// clearInterval(pollId);
External API Polling
For more detailed analytics data, use the External API with your API key:
Recent Analytics
const API_KEY = process.env.ZENOVAY_API_KEY;
const WEBSITE_ID = 'your-website-id';
async function getRecentAnalytics() {
const response = await fetch(
`https://api.zenovay.com/api/external/v1/analytics/${WEBSITE_ID}?timeRange=24h`,
{
headers: { 'X-API-Key': API_KEY }
}
);
return await response.json();
}
Visitor Data
async function getVisitors() {
const response = await fetch(
`https://api.zenovay.com/api/external/v1/analytics/${WEBSITE_ID}/visitors`,
{
headers: { 'X-API-Key': API_KEY }
}
);
return await response.json();
}
Building a Custom Dashboard
React Example
import { useState, useEffect } from 'react';
function LiveDashboard({ trackingCode, websiteId, apiKey }) {
const [liveCount, setLiveCount] = useState(0);
const [analytics, setAnalytics] = useState(null);
// Poll live visitor count every 10 seconds
useEffect(() => {
async function fetchLive() {
try {
const response = await fetch(`https://api.zenovay.com/live/${trackingCode}`);
const data = await response.json();
setLiveCount(data.count);
} catch (error) {
console.error('Live fetch error:', error);
}
}
fetchLive();
const interval = setInterval(fetchLive, 10000);
return () => clearInterval(interval);
}, [trackingCode]);
// Fetch analytics summary every 5 minutes
useEffect(() => {
async function fetchAnalytics() {
try {
const response = await fetch(
`https://api.zenovay.com/api/external/v1/analytics/${websiteId}?timeRange=24h`,
{
headers: { 'X-API-Key': apiKey }
}
);
const data = await response.json();
setAnalytics(data);
} catch (error) {
console.error('Analytics fetch error:', error);
}
}
fetchAnalytics();
const interval = setInterval(fetchAnalytics, 5 * 60 * 1000);
return () => clearInterval(interval);
}, [websiteId, apiKey]);
return (
<div>
<h2>Live Visitors: {liveCount}</h2>
{analytics && (
<div>
<p>Today's Visitors: {analytics.totalVisitors}</p>
<p>Page Views: {analytics.totalPageViews}</p>
<p>Bounce Rate: {analytics.bounceRate}%</p>
</div>
)}
</div>
);
}
Rate Limit Considerations
When polling the External API, be mindful of rate limits:
| Plan | Requests/Minute | Recommended Poll Interval |
|---|---|---|
| Free | 10 | Every 10 minutes |
| Pro | 30 | Every 5 minutes |
| Scale | 60 | Every 2 minutes |
| Enterprise | 120 | Every minute |
The public live endpoint (/live/TRACKING_CODE) has separate rate limits and can be polled more frequently (every 10 seconds is reasonable).
Best Practices
- Use the public
/live/endpoint for visitor counts (no API key needed, more frequent polling OK) - Use the External API for detailed analytics (respect per-plan rate limits)
- Cache responses locally between polls
- Implement error handling with exponential backoff