Real-time metrics powered by Cloudflare GraphQL Analytics Engine
WAVE PULSE provides comprehensive analytics powered by Cloudflare's GraphQL Analytics Engine. Access real-time viewer counts, engagement metrics, quality of experience data, geographic distribution, and revenue tracking for all your streams.
Viewership
Concurrent, unique, segments
Engagement
Watch time, chat, reactions
Quality
Rebuffer, startup, bitrate
Geography
Country, region, city
Revenue
Ads, subs, donations
RESTful and GraphQL endpoints for analytics data
GET /api/v1/streams/:id/analyticsGet aggregated analytics for a specific stream
GET /api/v1/streams/:id/analytics/realtimeGet real-time viewer count and quality metrics
GET /api/v1/analytics/overviewGet account-wide analytics summary
GET /api/v1/streams/:id/analytics/geographyGet viewer distribution by country/region
GET /api/v1/streams/:id/analytics/qualityGet quality of experience metrics
POST /api/v1/analytics/eventsTrack custom events and user actions
GET /api/v1/analytics/funnels/:idGet conversion funnel analytics
POST /api/v1/analytics/queryExecute custom GraphQL analytics query
// Get stream analytics for the last 24 hours
import { WaveAnalytics } from '@wave/analytics';
const analytics = new WaveAnalytics({
apiKey: process.env.WAVE_API_KEY
});
// Fetch aggregated metrics
const metrics = await analytics.streams.getMetrics('stream_abc123', {
start: new Date(Date.now() - 86400000),
end: new Date(),
granularity: 'hour',
metrics: ['views', 'watch_time', 'quality', 'geography']
});
console.log('Peak viewers:', metrics.peak_concurrent);
console.log('Avg watch time:', metrics.avg_watch_time_minutes, 'minutes');
console.log('Quality score:', metrics.quality_score);
// Real-time updates via WebSocket
const realtime = analytics.streams.subscribe('stream_abc123');
realtime.on('metrics', (data) => {
console.log('Current viewers:', data.concurrent_viewers);
console.log('Bitrate:', data.avg_bitrate_kbps, 'kbps');
console.log('Buffer ratio:', data.rebuffer_rate, '%');
});
realtime.on('milestone', (milestone) => {
console.log('Milestone reached:', milestone.type, milestone.value);
// e.g., { type: 'viewers', value: 1000, label: '1K viewers!' }
});Complete reference of available analytics metrics
total_viewsTotal unique viewer sessions
peak_concurrentMaximum simultaneous viewers
average_concurrentAverage simultaneous viewers
unique_viewersDistinct viewer IDs (authenticated)
new_viewersFirst-time viewers this period
returning_viewersViewers who watched before
total_watch_time_minutesSum of all viewer watch time
avg_watch_time_minutesAverage session duration
completion_rateVOD: % who watched to end
chat_messagesTotal chat messages sent
reactionsTotal reactions (likes, emotes)
sharesStream shares to social media
rebuffer_ratePercentage of time spent buffering
startup_time_msTime to first frame (median)
bitrate_kbpsAverage delivered bitrate
error_ratePercentage of failed playback attempts
quality_scoreComposite QoE score (0-100)
frame_dropsTotal dropped frames
by_countryViews grouped by ISO country code
by_regionViews grouped by region/state
by_cityViews grouped by city (Enterprise)
by_asnViews grouped by ISP/ASN
by_edge_locationViews by WAVE edge node
total_revenueTotal revenue from stream
ad_impressionsTotal ad impressions served
ad_revenueRevenue from advertisements
subscription_revenueRevenue from subscriptions
donation_revenueRevenue from donations/tips
arpuAverage revenue per user
Track custom events beyond built-in metrics. Use for purchases, subscriptions, engagement milestones, and any business-specific events.
// Track custom events for deeper analytics
import { WaveAnalytics } from '@wave/analytics';
const analytics = new WaveAnalytics({ apiKey: process.env.WAVE_API_KEY });
// Track viewer subscription
await analytics.track({
event: 'subscription_started',
userId: 'user_xyz789',
streamId: 'stream_abc123',
properties: {
tier: 'premium',
price: 9.99,
currency: 'USD',
trial: false,
referrer: 'twitter_campaign'
}
});
// Track purchase in stream
await analytics.track({
event: 'purchase_completed',
userId: 'user_xyz789',
streamId: 'stream_abc123',
properties: {
product_id: 'merch_001',
product_name: 'Team Jersey',
price: 49.99,
quantity: 1,
category: 'merchandise'
}
});
// Track engagement milestones
await analytics.track({
event: 'engagement_milestone',
userId: 'user_xyz789',
streamId: 'stream_abc123',
properties: {
milestone: 'first_chat_message',
watch_time_minutes: 5,
session_number: 1
}
});
// Track quality issues (auto-collected, but can supplement)
await analytics.track({
event: 'quality_issue_reported',
userId: 'user_xyz789',
streamId: 'stream_abc123',
properties: {
issue_type: 'buffering',
duration_seconds: 3,
user_reported: true,
network_type: '4g'
}
});Configure real-time alerts for viewer milestones, quality issues, revenue targets, and anomaly detection.
// Configure analytics alerts
import { WaveAnalytics } from '@wave/analytics';
const analytics = new WaveAnalytics({ apiKey: process.env.WAVE_API_KEY });
// Viewer milestone alerts
await analytics.alerts.create({
name: 'Viewer Milestone',
type: 'threshold',
metric: 'concurrent_viewers',
condition: 'greater_than',
thresholds: [100, 500, 1000, 5000, 10000],
channels: ['webhook', 'email'],
webhook_url: 'https://yourapp.com/webhooks/milestones',
cooldown_minutes: 5
});
// Quality degradation alert
await analytics.alerts.create({
name: 'Quality Alert',
type: 'threshold',
metric: 'rebuffer_rate',
condition: 'greater_than',
threshold: 5.0, // 5% rebuffer rate
channels: ['webhook', 'slack'],
slack_channel: '#streaming-ops',
severity: 'warning'
});
// Revenue target alert
await analytics.alerts.create({
name: 'Revenue Goal',
type: 'cumulative',
metric: 'total_revenue',
condition: 'greater_than',
threshold: 10000, // $10,000
period: 'day',
channels: ['email'],
recipients: ['[email protected]']
});
// Anomaly detection (ML-powered)
await analytics.alerts.create({
name: 'Traffic Anomaly',
type: 'anomaly',
metric: 'concurrent_viewers',
sensitivity: 'medium', // low, medium, high
channels: ['webhook', 'pagerduty'],
severity: 'critical'
});Export analytics data to your data warehouse for advanced analysis, ML training, and integration with your existing BI tools.
// Export analytics to data warehouses
import { WaveAnalytics } from '@wave/analytics';
const analytics = new WaveAnalytics({ apiKey: process.env.WAVE_API_KEY });
// Configure BigQuery export
await analytics.exports.configure({
destination: 'bigquery',
project_id: 'your-gcp-project',
dataset: 'wave_analytics',
credentials: process.env.GCP_SERVICE_ACCOUNT_KEY,
tables: {
events: 'stream_events',
metrics: 'stream_metrics',
sessions: 'viewer_sessions'
},
schedule: 'hourly', // hourly, daily, realtime
partitioning: {
field: 'timestamp',
type: 'DAY'
}
});
// Configure Snowflake export
await analytics.exports.configure({
destination: 'snowflake',
account: 'your-account.us-east-1',
warehouse: 'WAVE_WH',
database: 'ANALYTICS',
schema: 'STREAMING',
credentials: {
user: process.env.SNOWFLAKE_USER,
private_key: process.env.SNOWFLAKE_PRIVATE_KEY
},
schedule: 'daily'
});
// S3 export for custom processing
await analytics.exports.configure({
destination: 's3',
bucket: 'your-analytics-bucket',
prefix: 'wave-analytics/',
format: 'parquet', // parquet, json, csv
compression: 'snappy',
partition_by: ['date', 'stream_id'],
schedule: 'hourly'
});
// Webhook for real-time streaming
await analytics.exports.configure({
destination: 'webhook',
url: 'https://your-pipeline.com/ingest',
format: 'json',
batch_size: 100,
batch_timeout_ms: 5000,
headers: {
'Authorization': 'Bearer YOUR_PIPELINE_TOKEN'
}
});Track user journeys from first view to conversion. Analyze drop-off points and optimize your streaming experience for better conversion rates.
// Create and analyze conversion funnels
import { WaveAnalytics } from '@wave/analytics';
const analytics = new WaveAnalytics({ apiKey: process.env.WAVE_API_KEY });
// Define a subscription conversion funnel
const funnel = await analytics.funnels.create({
name: 'Subscription Conversion',
steps: [
{ event: 'stream_viewed', label: 'Watched Stream' },
{ event: 'signup_started', label: 'Started Signup' },
{ event: 'signup_completed', label: 'Completed Signup' },
{ event: 'trial_started', label: 'Started Trial' },
{ event: 'subscription_started', label: 'Subscribed' }
],
window_days: 7, // 7-day conversion window
breakdown_by: ['country', 'device', 'referrer']
});
// Get funnel analytics
const funnelData = await analytics.funnels.get(funnel.id, {
start: new Date(Date.now() - 30 * 86400000), // Last 30 days
end: new Date(),
breakdown: 'referrer'
});
console.log('Funnel Analysis:');
funnelData.steps.forEach((step, i) => {
const conversionRate = i > 0
? ((step.count / funnelData.steps[i-1].count) * 100).toFixed(1)
: '100.0';
console.log(`${step.label}: ${step.count.toLocaleString()} (${conversionRate}%)`);
});
console.log('\nBreakdown by Referrer:');
funnelData.breakdown.forEach(segment => {
console.log(`${segment.value}: ${segment.conversion_rate.toFixed(1)}% conversion`);
});| Tier | Rate Limit | Retention | Min Granularity | Exports |
|---|---|---|---|---|
| Free | 100/minute | 7 days | hour | CSV only |
| Pro | 500/minute | 30 days | minute | CSV, JSON |
| Business | 2000/minute | 90 days | minute | All formats |
| Enterprise | 10000/minute | 365 days | second | All + Streaming |
Use minute granularity for real-time dashboards, hourly for daily reports, daily for long-term trends.
Historical analytics are immutable. Cache aggressively for past periods.
For live dashboards, use the WebSocket endpoint instead of polling.
Request multiple streams in a single call when possible.
Let the API aggregate data instead of fetching raw events.
Use consistent event names and property schemas for queryability.
Building real-time dashboards for 50+ concurrent live sports events with viewer counts updating every second
WebSocket-based analytics with edge aggregation for sub-second updates across global CDN
"WAVE's analytics infrastructure handles our biggest events without breaking a sweat. Super Bowl data flows as smoothly as a regular Tuesday game.
Predicting subscriber churn using viewing behavior patterns to enable proactive retention
Custom event tracking with BigQuery export feeding ML models for real-time churn scores
"The granularity of WAVE analytics data transformed our ML models. We can now predict churn 14 days in advance with high confidence.
Optimizing mid-roll ad placement to maximize revenue without impacting viewer engagement
Engagement analytics with A/B testing framework to find optimal ad insertion points
"Data-driven ad placement using WAVE analytics increased our streaming ad revenue by 3x in six months.