Skip to main content

Analytics

Analytics API

Monitor your video performance with comprehensive analytics and usage metrics. HesedVid’s Analytics API provides detailed insights into video delivery, storage usage, resolution distribution, and viewer engagement to help you optimize your video strategy and make data-driven decisions.

Tip

Analytics data is updated in real-time and provides insights into how your videos are being consumed across different devices and network conditions.

Why Analytics Matter

Video analytics help you:

  • Optimize Performance: Understand which resolutions are most popular and adjust encoding strategies
  • Control Costs: Monitor storage usage and delivery patterns to optimize spending
  • Improve User Experience: Identify performance bottlenecks and optimize video delivery
  • Make Data-Driven Decisions: Track trends and patterns to inform content strategy
  • Monitor Health: Detect issues early through usage pattern analysis

Analytics Overview

The Analytics API provides five key endpoints for comprehensive video insights:

📊 Account Usage

Overall usage statistics and trends for your organization

GET /{orgID}/analytics/usage

📅 Daily Usage

Day-by-day breakdown of video delivery metrics

GET /{orgID}/analytics/daily

💾 Storage Usage

Storage consumption and video duration analytics

GET /{orgID}/analytics/storage

🎥 Video Resolution

Individual video performance and resolution data

GET /{orgID}/videos/{publicID}/analytics/resolution

📈 Resolution Distribution

Account-wide resolution usage patterns and trends

GET /{orgID}/analytics/resolution-distribution

Key Metrics Explained

Segments vs Views

HesedVid tracks segments served rather than traditional “views” for more accurate analytics:

  • Segment: A 6-second chunk of video data delivered to a player
  • View: Typically calculated as segments_served ÷ (video_duration_seconds ÷ 6)
  • Why Segments: More accurate than page views, accounts for seeking, buffering, and partial views

Resolution Categories

CategoryResolutionDescription
HD1080p+High definition segments
SD720pStandard definition segments
LD480p and belowLow definition segments

Quality Tiers

TierDescriptionUse Case
UltraHighest quality encodingPremium content, large screens
HighHigh quality encodingStandard content, most use cases
StandardBaseline quality encodingMobile, low bandwidth

Account Usage Analytics

/{orgID}/analytics/usage

Get comprehensive usage statistics for your organization or specific environment. This endpoint provides high-level metrics about your video library, delivery performance, and growth trends.

When to Use

  • Dashboard Overview: Display key metrics on your admin dashboard
  • Growth Tracking: Monitor video uploads and delivery trends over time
  • Account Health: Check if your account is actively serving content
  • Billing Insights: Understand usage patterns for cost optimization

Path Parameters

ParameterTypeRequiredDescription
orgIDstringYesYour organization’s unique identifier

Query Parameters

ParameterTypeRequiredDefaultDescription
periodDaysintNo30Number of days to look back for statistics (1-365)

Tip

Use shorter periods (7-14 days) for recent activity analysis, and longer periods (90-365 days) for trend analysis and growth tracking.

Response Fields Explained

FieldTypeDescriptionBusiness Value
totalVideosint64Total videos in your accountLibrary size, content volume
totalVideoDurationSecondsfloat64Total duration of all videosStorage usage, content hours
totalSegmentsServedint64All-time segments deliveredTotal engagement, platform usage
videosUploadedInPeriodint64New videos in specified periodContent growth rate, upload activity
segmentsServedInPeriodint64Segments served in specified periodRecent engagement, delivery volume
firstVideoUploadedstringTimestamp of first uploadAccount age, platform adoption
lastSegmentServedstringMost recent deliveryAccount activity, content freshness

Response Example

{
"body": {
"usage": [
{
"workosOrgId": "org_123456789",
"envId": "env_prod_123456789",
"totalVideos": 150,
"totalVideoDurationSeconds": 45000.5,
"totalSegmentsServed": 125000,
"videosUploadedInPeriod": 25,
"segmentsServedInPeriod": 15000,
"firstVideoUploaded": "2024-01-01T10:00:00Z",
"firstVideoUploadedValid": true,
"lastSegmentServed": "2024-01-15T14:30:00Z",
"lastSegmentServedValid": true
}
]
}
}

Calculating Key Metrics

// Calculate views from segments
const calculateViews = (segmentsServed, videoDurationSeconds) => {
return Math.round(segmentsServed / (videoDurationSeconds / 6));
};
// Calculate average video length
const avgVideoLength = totalVideoDurationSeconds / totalVideos;
// Calculate engagement rate
const engagementRate = segmentsServedInPeriod / videosUploadedInPeriod;

Example Request

Daily Usage Analytics

/{orgID}/analytics/daily

Get day-by-day breakdown of video delivery metrics for trend analysis. This endpoint provides granular daily data to identify patterns, peak usage times, and quality distribution trends.

When to Use

  • Trend Analysis: Identify daily, weekly, or monthly patterns in video consumption
  • Performance Monitoring: Track delivery performance over time
  • Quality Optimization: Understand resolution preferences by day
  • Capacity Planning: Predict future bandwidth and storage needs
  • Business Intelligence: Correlate video usage with business events

Path Parameters

ParameterTypeRequiredDescription
orgIDstringYesYour organization’s unique identifier

Query Parameters

ParameterTypeRequiredDefaultDescription
startDatestringNo30 days agoStart date in YYYY-MM-DD format
endDatestringNoTodayEnd date in YYYY-MM-DD format

Tip

For trend analysis, use 30-90 day periods. For detailed analysis, use 7-14 day periods. Maximum range is 365 days.

Response Fields Explained

FieldTypeDescriptionBusiness Value
deliveryDatestringDate of delivery (UTC)Time-based analysis, trend identification
segmentsServedint64Total segments deliveredDaily engagement volume
uniqueVideosServedint64Number of unique videosContent diversity, catalog utilization
hdSegmentsint64High definition segmentsPremium content consumption
sdSegmentsint64Standard definition segmentsStandard content consumption
ldSegmentsint64Low definition segmentsMobile/low-bandwidth consumption

Response Example

{
"body": {
"dailyUsage": [
{
"deliveryDate": "2024-01-15T00:00:00Z",
"segmentsServed": 1250,
"uniqueVideosServed": 45,
"hdSegments": 800,
"sdSegments": 350,
"ldSegments": 100
},
{
"deliveryDate": "2024-01-14T00:00:00Z",
"segmentsServed": 980,
"uniqueVideosServed": 32,
"hdSegments": 650,
"sdSegments": 250,
"ldSegments": 80
}
]
}
}
// Calculate quality distribution percentages
const analyzeQualityDistribution = (dailyData) => {
return dailyData.map(day => {
const total = day.segmentsServed;
return {
date: day.deliveryDate,
total: total,
hdPercentage: (day.hdSegments / total) * 100,
sdPercentage: (day.sdSegments / total) * 100,
ldPercentage: (day.ldSegments / total) * 100
};
});
};
// Find peak usage days
const findPeakDays = (dailyData) => {
return dailyData
.sort((a, b) => b.segmentsServed - a.segmentsServed)
.slice(0, 5);
};
// Calculate weekly averages
const calculateWeeklyAverage = (dailyData) => {
const totalSegments = dailyData.reduce((sum, day) => sum + day.segmentsServed, 0);
return totalSegments / dailyData.length;
};

Example Request

Storage Usage Analytics

/{orgID}/analytics/storage

Get detailed storage consumption and video duration analytics. This endpoint helps you understand your storage footprint, optimize encoding strategies, and plan for storage costs.

When to Use

  • Storage Optimization: Understand which quality tiers consume the most storage
  • Cost Management: Calculate storage costs and identify optimization opportunities
  • Content Strategy: Analyze video length patterns to inform content creation
  • Capacity Planning: Plan for future storage needs based on current usage
  • Quality Decisions: Balance quality vs. storage costs

Path Parameters

ParameterTypeRequiredDescription
orgIDstringYesYour organization’s unique identifier

Response Fields Explained

FieldTypeDescriptionBusiness Value
totalVideosint64Total number of videos storedLibrary size, content count
totalDurationSecondsfloat64Total duration of all videosStorage baseline, content hours
avgVideoDurationfloat64Average video lengthContent strategy insights
ultraQualityDurationfloat64Duration of ultra quality videosPremium content storage
highQualityDurationfloat64Duration of high quality videosStandard content storage
standardQualityDurationfloat64Duration of standard quality videosBaseline content storage

Response Example

{
"body": {
"storage": {
"totalVideos": 150,
"totalDurationSeconds": 45000.5,
"avgVideoDuration": 300.0,
"ultraQualityDuration": 15000.2,
"highQualityDuration": 20000.1,
"standardQualityDuration": 10000.2
}
}
}

Storage Analysis Examples

// Calculate storage distribution percentages
const analyzeStorageDistribution = (storageData) => {
const total = storageData.totalDurationSeconds;
return {
ultraPercentage: (storageData.ultraQualityDuration / total) * 100,
highPercentage: (storageData.highQualityDuration / total) * 100,
standardPercentage: (storageData.standardQualityDuration / total) * 100,
totalHours: total / 3600,
avgMinutes: storageData.avgVideoDuration / 60
};
};
// Estimate storage costs (example rates)
const estimateStorageCosts = (storageData, costPerHour = 0.01) => {
const totalHours = storageData.totalDurationSeconds / 3600;
return {
monthlyCost: totalHours * costPerHour,
ultraCost: (storageData.ultraQualityDuration / 3600) * costPerHour,
highCost: (storageData.highQualityDuration / 3600) * costPerHour,
standardCost: (storageData.standardQualityDuration / 3600) * costPerHour
};
};
// Identify optimization opportunities
const findOptimizationOpportunities = (storageData) => {
const ultraRatio = storageData.ultraQualityDuration / storageData.totalDurationSeconds;
const highRatio = storageData.highQualityDuration / storageData.totalDurationSeconds;
return {
ultraOptimization: ultraRatio > 0.5 ? "Consider reducing ultra quality usage" : "Ultra quality usage is reasonable",
highOptimization: highRatio > 0.7 ? "High quality dominates - consider standard for some content" : "Good quality distribution",
avgLengthOptimization: storageData.avgVideoDuration > 600 ? "Consider shorter videos" : "Video length is appropriate"
};
};

Example Request

Video Resolution Analytics

/{orgID}/videos/{publicID}/analytics/resolution

Get detailed resolution analytics for a specific video. This endpoint provides insights into how individual videos are consumed across different resolutions and devices.

When to Use

  • Content Performance: Understand which resolutions are most popular for specific videos
  • Quality Optimization: Identify if certain videos need different encoding strategies
  • Device Analysis: Understand viewer device capabilities and preferences
  • Content Strategy: Optimize video content based on actual consumption patterns
  • A/B Testing: Compare performance across different video versions

Path Parameters

ParameterTypeRequiredDescription
orgIDstringYesYour organization’s unique identifier
publicIDstringYesThe public ID of the video asset

Query Parameters

ParameterTypeRequiredDescription
startDatestringNoStart date in YYYY-MM-DD format (optional)
endDatestringNoEnd date in YYYY-MM-DD format (optional)

Tip

Use date ranges to analyze specific campaigns, events, or time periods. Leave empty for all-time data.

Response Fields Explained

Summary Fields

FieldTypeDescriptionBusiness Value
totalSegmentsServedint64Total segments deliveredVideo popularity, engagement
totalDaysServedint64Days the video was actively servedContent longevity, sustained interest
mostPopularResolutionint32Most requested resolutionDevice preferences, quality optimization
availableResolutionsint32Number of resolution variantsEncoding completeness

Resolution Fields

FieldTypeDescriptionBusiness Value
resolutionHeightint32Video resolution heightDevice capability analysis
timesServedint64Segments served at this resolutionResolution popularity
daysServedint64Days this resolution was activeResolution longevity

Response Example

{
"body": {
"summary": {
"vidId": "vid_123456789abcdef",
"vidPublicId": "pubvid_AbCdEf",
"vidName": "My Video",
"vidNameValid": true,
"vidLengthSeconds": 300.5,
"availableResolutions": 3,
"totalSegmentsServed": 1500,
"totalDaysServed": 15,
"firstServed": "2024-01-01T10:00:00Z",
"firstServedValid": true,
"lastServed": "2024-01-15T14:30:00Z",
"lastServedValid": true,
"mostPopularResolution": 1080,
"mostPopularResolutionValid": true
},
"resolutions": [
{
"vidId": "vid_123456789abcdef",
"vidPublicId": "pubvid_AbCdEf",
"vidName": "My Video",
"vidNameValid": true,
"resolutionHeight": 1080,
"timesServed": 800,
"firstServed": "2024-01-01T10:00:00Z",
"firstServedValid": true,
"lastServed": "2024-01-15T14:30:00Z",
"lastServedValid": true,
"daysServed": 15
},
{
"vidId": "vid_123456789abcdef",
"vidPublicId": "pubvid_AbCdEf",
"vidName": "My Video",
"vidNameValid": true,
"resolutionHeight": 720,
"timesServed": 500,
"firstServed": "2024-01-01T10:00:00Z",
"firstServedValid": true,
"lastServed": "2024-01-15T14:30:00Z",
"lastServedValid": true,
"daysServed": 12
}
]
}
}

Video Performance Analysis

// Calculate resolution distribution
const analyzeVideoResolutions = (videoData) => {
const totalSegments = videoData.summary.totalSegmentsServed;
return videoData.resolutions.map(res => ({
resolution: res.resolutionHeight,
segments: res.timesServed,
percentage: (res.timesServed / totalSegments) * 100,
daysActive: res.daysServed,
avgSegmentsPerDay: res.timesServed / res.daysServed
}));
};
// Calculate estimated views
const calculateVideoViews = (videoData) => {
const videoLength = videoData.summary.vidLengthSeconds;
const segmentsPerView = videoLength / 6; // 6 seconds per segment
return Math.round(videoData.summary.totalSegmentsServed / segmentsPerView);
};
// Identify optimization opportunities
const findVideoOptimizations = (videoData) => {
const resolutions = videoData.resolutions.sort((a, b) => b.timesServed - a.timesServed);
const topResolution = resolutions[0];
const topPercentage = (topResolution.timesServed / videoData.summary.totalSegmentsServed) * 100;
return {
dominantResolution: topResolution.resolutionHeight,
dominantPercentage: topPercentage,
optimization: topPercentage > 80 ?
`Consider focusing on ${topResolution.resolutionHeight}p encoding` :
"Good resolution distribution",
engagement: videoData.summary.totalDaysServed > 30 ?
"High engagement - evergreen content" :
"Consider content refresh"
};
};

Example Request

Resolution Distribution Analytics

/{orgID}/analytics/resolution-distribution

Get account-wide resolution usage patterns and distribution. This endpoint provides insights into how your entire video library is consumed across different resolutions and helps optimize your encoding strategy.

When to Use

  • Encoding Strategy: Understand which resolutions to prioritize in your encoding pipeline
  • Device Analysis: Identify your audience’s device capabilities and preferences
  • Cost Optimization: Balance quality vs. bandwidth costs based on actual usage
  • Content Planning: Plan content strategy based on resolution preferences
  • Infrastructure Planning: Optimize CDN and bandwidth allocation

Path Parameters

ParameterTypeRequiredDescription
orgIDstringYesYour organization’s unique identifier

Query Parameters

ParameterTypeRequiredDescription
startDatestringNoStart date in YYYY-MM-DD format (optional)
endDatestringNoEnd date in YYYY-MM-DD format (optional)

Response Fields Explained

FieldTypeDescriptionBusiness Value
resolutionHeightint32Video resolution heightDevice capability analysis
segmentsServedint64Total segments served at this resolutionResolution popularity
uniqueVideosint64Number of unique videos served at this resolutionContent diversity
daysActiveint64Days this resolution was actively servedResolution longevity

Response Example

{
"body": {
"distribution": [
{
"resolutionHeight": 1080,
"segmentsServed": 50000,
"uniqueVideos": 45,
"daysActive": 30,
"firstServed": "2024-01-01T10:00:00Z",
"firstServedValid": true,
"lastServed": "2024-01-15T14:30:00Z",
"lastServedValid": true
},
{
"resolutionHeight": 720,
"segmentsServed": 35000,
"uniqueVideos": 38,
"daysActive": 28,
"firstServed": "2024-01-01T10:00:00Z",
"firstServedValid": true,
"lastServed": "2024-01-15T14:30:00Z",
"lastServedValid": true
},
{
"resolutionHeight": 480,
"segmentsServed": 15000,
"uniqueVideos": 25,
"daysActive": 20,
"firstServed": "2024-01-01T10:00:00Z",
"firstServedValid": true,
"lastServed": "2024-01-15T14:30:00Z",
"lastServedValid": true
}
]
}
}

Resolution Distribution Analysis

// Calculate resolution market share
const calculateResolutionShare = (distributionData) => {
const totalSegments = distributionData.reduce((sum, res) => sum + res.segmentsServed, 0);
return distributionData.map(res => ({
resolution: res.resolutionHeight,
segments: res.segmentsServed,
percentage: (res.segmentsServed / totalSegments) * 100,
videos: res.uniqueVideos,
avgSegmentsPerVideo: res.segmentsServed / res.uniqueVideos
}));
};
// Identify encoding priorities
const identifyEncodingPriorities = (distributionData) => {
const sorted = distributionData.sort((a, b) => b.segmentsServed - a.segmentsServed);
const totalSegments = distributionData.reduce((sum, res) => sum + res.segmentsServed, 0);
return {
primaryResolution: sorted[0].resolutionHeight,
primaryPercentage: (sorted[0].segmentsServed / totalSegments) * 100,
recommendations: sorted.slice(0, 3).map(res => ({
resolution: res.resolutionHeight,
priority: sorted.indexOf(res) + 1,
segments: res.segmentsServed,
percentage: (res.segmentsServed / totalSegments) * 100
}))
};
};
// Analyze device preferences
const analyzeDevicePreferences = (distributionData) => {
const hdSegments = distributionData.filter(r => r.resolutionHeight >= 1080)
.reduce((sum, r) => sum + r.segmentsServed, 0);
const sdSegments = distributionData.filter(r => r.resolutionHeight === 720)
.reduce((sum, r) => sum + r.segmentsServed, 0);
const ldSegments = distributionData.filter(r => r.resolutionHeight <= 480)
.reduce((sum, r) => sum + r.segmentsServed, 0);
const total = hdSegments + sdSegments + ldSegments;
return {
highEndDevices: (hdSegments / total) * 100,
standardDevices: (sdSegments / total) * 100,
mobileDevices: (ldSegments / total) * 100,
recommendation: hdSegments > total * 0.6 ?
"Focus on high-quality encoding" :
"Balanced encoding strategy recommended"
};
};

Example Request

Environment-Specific Analytics

All analytics endpoints support environment-specific filtering by including the environment ID in the path:

  • /{orgID}/environments/{envID}/analytics/usage
  • /{orgID}/environments/{envID}/analytics/daily
  • /{orgID}/environments/{envID}/analytics/storage
  • /{orgID}/environments/{envID}/analytics/resolution-distribution

Example: Environment-Specific Usage

Terminal window
# Get usage for specific environment
curl -X GET "https://api.hesedvid.com/v1/api/org_123456789/environments/env_prod_123456789/analytics/usage" \
-H "X-Api-Key: hv_live_123456789abcdefghijklmnopqrstuvwxyz"

Analytics Data Types

Account Usage Metrics

FieldTypeDescription
totalVideosint64Total number of videos in account
totalVideoDurationSecondsfloat64Total duration of all videos in seconds
totalSegmentsServedint64Total video segments delivered
videosUploadedInPeriodint64Videos uploaded in the specified period
segmentsServedInPeriodint64Segments served in the specified period
firstVideoUploadedstringTimestamp of first video upload
lastSegmentServedstringTimestamp of most recent segment delivery

Daily Usage Metrics

FieldTypeDescription
deliveryDatestringDate of delivery (YYYY-MM-DD)
segmentsServedint64Total segments served on this date
uniqueVideosServedint64Number of unique videos served
hdSegmentsint64High definition segments served
sdSegmentsint64Standard definition segments served
ldSegmentsint64Low definition segments served

Storage Metrics

FieldTypeDescription
totalVideosint64Total number of videos stored
totalDurationSecondsfloat64Total duration of all videos
avgVideoDurationfloat64Average video duration
ultraQualityDurationfloat64Duration of ultra quality videos
highQualityDurationfloat64Duration of high quality videos
standardQualityDurationfloat64Duration of standard quality videos

Video Resolution Metrics

FieldTypeDescription
resolutionHeightint32Video resolution height in pixels
timesServedint64Number of times this resolution was served
daysServedint64Number of days this resolution was active
firstServedstringFirst time this resolution was served
lastServedstringMost recent time this resolution was served

Advanced Analytics Use Cases

Comprehensive Dashboard Analytics

// Build comprehensive analytics dashboard
const buildAnalyticsDashboard = async (orgId, periodDays = 30) => {
const endDate = new Date().toISOString().split('T')[0];
const startDate = new Date(Date.now() - periodDays * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
// Example: Fetch all analytics data in parallel
const [accountUsage, dailyUsage, storageUsage, resolutionDistribution] = await Promise.all([
fetch(`/v1/api/${orgId}/analytics/usage?periodDays=${periodDays}`),
fetch(`/v1/api/${orgId}/analytics/daily?startDate=${startDate}&endDate=${endDate}`),
fetch(`/v1/api/${orgId}/analytics/storage`),
fetch(`/v1/api/${orgId}/analytics/resolution-distribution?startDate=${startDate}&endDate=${endDate}`)
]);
// Calculate key metrics
const totalSegments = dailyUsage.body.dailyUsage.reduce((sum, day) => sum + day.segmentsServed, 0);
const avgDailySegments = totalSegments / periodDays;
const peakDay = dailyUsage.body.dailyUsage.reduce((max, day) =>
day.segmentsServed > max.segmentsServed ? day : max
);
return {
overview: {
totalVideos: accountUsage.body.usage[0].totalVideos,
totalSegments: accountUsage.body.usage[0].totalSegmentsServed,
newVideosInPeriod: accountUsage.body.usage[0].videosUploadedInPeriod,
segmentsInPeriod: accountUsage.body.usage[0].segmentsServedInPeriod
},
trends: {
dailyAverage: avgDailySegments,
peakDay: peakDay.deliveryDate,
peakSegments: peakDay.segmentsServed,
growthRate: calculateGrowthRate(dailyUsage.body.dailyUsage)
},
storage: {
totalHours: storageUsage.body.storage.totalDurationSeconds / 3600,
avgVideoLength: storageUsage.body.storage.avgVideoDuration / 60,
qualityDistribution: {
ultra: (storageUsage.body.storage.ultraQualityDuration / storageUsage.body.storage.totalDurationSeconds) * 100,
high: (storageUsage.body.storage.highQualityDuration / storageUsage.body.storage.totalDurationSeconds) * 100,
standard: (storageUsage.body.storage.standardQualityDuration / storageUsage.body.storage.totalDurationSeconds) * 100
}
},
resolutionBreakdown: resolutionDistribution.body.distribution.map(d => ({
resolution: d.resolutionHeight,
segments: d.segmentsServed,
percentage: (d.segmentsServed / totalSegments) * 100,
videos: d.uniqueVideos
}))
};
};
// Calculate week-over-week growth rate
const calculateGrowthRate = (dailyData) => {
if (dailyData.length < 14) return 0;
const firstWeek = dailyData.slice(0, 7).reduce((sum, day) => sum + day.segmentsServed, 0);
const secondWeek = dailyData.slice(7, 14).reduce((sum, day) => sum + day.segmentsServed, 0);
return ((secondWeek - firstWeek) / firstWeek) * 100;
};

Performance Monitoring & Alerting

// Monitor video performance trends with alerting
const monitorVideoPerformance = async (videoId, orgId) => {
const response = await fetch(`/v1/api/${orgId}/videos/${videoId}/analytics/resolution`);
const analytics = await response.json();
const performance = {
videoId: videoId,
totalViews: calculateVideoViews(analytics.body.summary),
mostPopularResolution: analytics.body.summary.mostPopularResolution,
activeDays: analytics.body.summary.totalDaysServed,
resolutionBreakdown: analytics.body.resolutions.map(r => ({
resolution: r.resolutionHeight,
segments: r.timesServed,
percentage: (r.timesServed / analytics.body.summary.totalSegmentsServed) * 100,
avgSegmentsPerDay: r.timesServed / r.daysServed
})),
health: {
engagement: analytics.body.summary.totalDaysServed > 30 ? 'high' : 'low',
qualityDistribution: analyzeQualityDistribution(analytics.body.resolutions),
recommendations: generateVideoRecommendations(analytics.body)
}
};
// Check for performance alerts
if (performance.totalViews < 100 && performance.activeDays > 7) {
console.warn(`Low engagement alert for video ${videoId}: ${performance.totalViews} views over ${performance.activeDays} days`);
}
return performance;
};
// Analyze quality distribution health
const analyzeQualityDistribution = (resolutions) => {
const totalSegments = resolutions.reduce((sum, r) => sum + r.timesServed, 0);
const hdSegments = resolutions.filter(r => r.resolutionHeight >= 1080).reduce((sum, r) => sum + r.timesServed, 0);
const hdPercentage = (hdSegments / totalSegments) * 100;
return {
hdPercentage: hdPercentage,
status: hdPercentage > 60 ? 'high-quality-focused' : hdPercentage > 30 ? 'balanced' : 'mobile-focused',
recommendation: hdPercentage > 80 ? 'Consider optimizing for mobile' : 'Good quality distribution'
};
};

Cost Optimization Analysis

// Comprehensive cost optimization analysis
const analyzeStorageCosts = async (orgId) => {
const endDate = new Date().toISOString().split('T')[0];
const startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
const [storage, resolutionDistribution, dailyUsage] = await Promise.all([
fetch(`/v1/api/${orgId}/analytics/storage`),
fetch(`/v1/api/${orgId}/analytics/resolution-distribution`),
fetch(`/v1/api/${orgId}/analytics/daily?startDate=${startDate}&endDate=${endDate}`)
]);
const storageData = storage.body.storage;
const totalHours = storageData.totalDurationSeconds / 3600;
const avgVideoLength = storageData.avgVideoDuration / 60;
// Calculate estimated costs (example rates)
const storageCostPerHour = 0.01; // $0.01 per hour per month
const deliveryCostPerSegment = 0.0001; // $0.0001 per segment
const totalDeliverySegments = dailyUsage.body.dailyUsage.reduce((sum, day) => sum + day.segmentsServed, 0);
const analysis = {
storage: {
totalHours: totalHours,
monthlyStorageCost: totalHours * storageCostPerHour,
avgVideoLength: avgVideoLength,
qualityBreakdown: {
ultra: {
hours: storageData.ultraQualityDuration / 3600,
cost: (storageData.ultraQualityDuration / 3600) * storageCostPerHour,
percentage: (storageData.ultraQualityDuration / storageData.totalDurationSeconds) * 100
},
high: {
hours: storageData.highQualityDuration / 3600,
cost: (storageData.highQualityDuration / 3600) * storageCostPerHour,
percentage: (storageData.highQualityDuration / storageData.totalDurationSeconds) * 100
},
standard: {
hours: storageData.standardQualityDuration / 3600,
cost: (storageData.standardQualityDuration / 3600) * storageCostPerHour,
percentage: (storageData.standardQualityDuration / storageData.totalDurationSeconds) * 100
}
}
},
delivery: {
totalSegments: totalDeliverySegments,
monthlyDeliveryCost: totalDeliverySegments * deliveryCostPerSegment,
avgSegmentsPerDay: totalDeliverySegments / 30
},
optimization: {
recommendations: generateOptimizationRecommendations(storageData, resolutionDistribution.body.distribution),
potentialSavings: calculatePotentialSavings(storageData, resolutionDistribution.body.distribution)
}
};
return analysis;
};
// Generate optimization recommendations
const generateOptimizationRecommendations = (storageData, resolutionDistribution) => {
const recommendations = [];
const ultraRatio = storageData.ultraQualityDuration / storageData.totalDurationSeconds;
if (ultraRatio > 0.5) {
recommendations.push({
type: 'storage',
priority: 'high',
message: 'High ultra-quality usage detected. Consider reducing ultra quality for non-premium content.',
potentialSavings: `${Math.round(ultraRatio * 100)}% of storage costs`
});
}
const avgLength = storageData.avgVideoDuration;
if (avgLength > 600) { // 10 minutes
recommendations.push({
type: 'content',
priority: 'medium',
message: 'Long average video length. Consider creating shorter, more focused content.',
potentialSavings: 'Reduced storage and processing costs'
});
}
return recommendations;
};

Business Intelligence & Reporting

// Generate comprehensive business intelligence report
const generateBusinessIntelligenceReport = async (orgId, periodDays = 90) => {
const endDate = new Date().toISOString().split('T')[0];
const startDate = new Date(Date.now() - periodDays * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
const [accountUsage, dailyUsage, storageUsage, resolutionDistribution] = await Promise.all([
fetch(`/v1/api/${orgId}/analytics/usage?periodDays=${periodDays}`),
fetch(`/v1/api/${orgId}/analytics/daily?startDate=${startDate}&endDate=${endDate}`),
fetch(`/v1/api/${orgId}/analytics/storage`),
fetch(`/v1/api/${orgId}/analytics/resolution-distribution?startDate=${startDate}&endDate=${endDate}`)
]);
const report = {
executiveSummary: {
period: `${startDate} to ${endDate}`,
totalVideos: accountUsage.body.usage[0].totalVideos,
totalViews: calculateTotalViews(dailyUsage.body.dailyUsage),
growthRate: calculateGrowthRate(dailyUsage.body.dailyUsage),
avgEngagement: calculateAverageEngagement(dailyUsage.body.dailyUsage)
},
contentPerformance: {
topPerformingDays: findTopPerformingDays(dailyUsage.body.dailyUsage, 5),
qualityPreferences: analyzeQualityPreferences(resolutionDistribution.body.distribution),
contentStrategy: generateContentStrategyRecommendations(storageUsage.body.storage, dailyUsage.body.dailyUsage)
},
technicalInsights: {
deviceAnalysis: analyzeDeviceCapabilities(resolutionDistribution.body.distribution),
bandwidthOptimization: analyzeBandwidthUsage(dailyUsage.body.dailyUsage),
storageEfficiency: analyzeStorageEfficiency(storageUsage.body.storage)
},
recommendations: {
shortTerm: generateShortTermRecommendations(dailyUsage.body.dailyUsage),
longTerm: generateLongTermRecommendations(accountUsage.body.usage[0], storageUsage.body.storage)
}
};
return report;
};
// Calculate total estimated views
const calculateTotalViews = (dailyData) => {
const totalSegments = dailyData.reduce((sum, day) => sum + day.segmentsServed, 0);
const avgSegmentsPerView = 50; // Estimated based on average video length
return Math.round(totalSegments / avgSegmentsPerView);
};
// Find top performing days
const findTopPerformingDays = (dailyData, count = 5) => {
return dailyData
.sort((a, b) => b.segmentsServed - a.segmentsServed)
.slice(0, count)
.map(day => ({
date: day.deliveryDate,
segments: day.segmentsServed,
videos: day.uniqueVideosServed,
qualityBreakdown: {
hd: day.hdSegments,
sd: day.sdSegments,
ld: day.ldSegments
}
}));
};

Best Practices

Data Collection Strategy

  • Start with Overview: Begin with account usage analytics to understand your baseline metrics

  • Monitor Trends: Use daily usage analytics to identify patterns and anomalies

  • Optimize Storage: Regularly review storage analytics to control costs

  • Analyze Performance: Use video resolution analytics to optimize individual content

  • Plan Strategy: Use resolution distribution to inform encoding and content decisions

  • Performance Optimization

    Caching Strategy

    // Implement intelligent caching for analytics data
    class AnalyticsCache {
    constructor() {
    this.cache = new Map();
    this.cacheExpiry = {
    accountUsage: 5 * 60 * 1000, // 5 minutes
    dailyUsage: 15 * 60 * 1000, // 15 minutes
    storageUsage: 30 * 60 * 1000, // 30 minutes
    videoResolution: 10 * 60 * 1000, // 10 minutes
    resolutionDistribution: 20 * 60 * 1000 // 20 minutes
    };
    }
    async getCachedData(endpoint, params) {
    const key = `${endpoint}_${JSON.stringify(params)}`;
    const cached = this.cache.get(key);
    if (cached && Date.now() - cached.timestamp < this.cacheExpiry[endpoint]) {
    return cached.data;
    }
    return null;
    }
    setCachedData(endpoint, params, data) {
    const key = `${endpoint}_${JSON.stringify(params)}`;
    this.cache.set(key, {
    data: data,
    timestamp: Date.now()
    });
    }
    }

    Batch Processing

    // Batch multiple analytics requests for efficiency
    const batchAnalyticsRequests = async (orgId, requests) => {
    const results = await Promise.allSettled(requests.map(req => {
    switch(req.type) {
    case 'accountUsage':
    return fetch(`/v1/api/${orgId}/analytics/usage?periodDays=${req.periodDays}`);
    case 'dailyUsage':
    return fetch(`/v1/api/${orgId}/analytics/daily?startDate=${req.startDate}&endDate=${req.endDate}`);
    case 'storageUsage':
    return fetch(`/v1/api/${orgId}/analytics/storage`);
    case 'videoResolution':
    return fetch(`/v1/api/${orgId}/videos/${req.videoId}/analytics/resolution?startDate=${req.startDate}&endDate=${req.endDate}`);
    case 'resolutionDistribution':
    return fetch(`/v1/api/${orgId}/analytics/resolution-distribution?startDate=${req.startDate}&endDate=${req.endDate}`);
    default:
    throw new Error(`Unknown request type: ${req.type}`);
    }
    }));
    return results.map((result, index) => ({
    request: requests[index],
    success: result.status === 'fulfilled',
    data: result.status === 'fulfilled' ? result.value : null,
    error: result.status === 'rejected' ? result.reason : null
    }));
    };

    Dashboard Implementation

    Real-time Updates

    // Implement real-time analytics dashboard
    class AnalyticsDashboard {
    constructor(orgId, updateInterval = 300000) { // 5 minutes
    this.orgId = orgId;
    this.updateInterval = updateInterval;
    this.subscribers = [];
    this.isRunning = false;
    }
    subscribe(callback) {
    this.subscribers.push(callback);
    if (!this.isRunning) {
    this.start();
    }
    }
    unsubscribe(callback) {
    this.subscribers = this.subscribers.filter(sub => sub !== callback);
    if (this.subscribers.length === 0) {
    this.stop();
    }
    }
    async start() {
    this.isRunning = true;
    this.updateLoop();
    }
    stop() {
    this.isRunning = false;
    if (this.updateTimer) {
    clearTimeout(this.updateTimer);
    }
    }
    async updateLoop() {
    if (!this.isRunning) return;
    try {
    const data = await this.fetchDashboardData();
    this.subscribers.forEach(callback => callback(data));
    } catch (error) {
    console.error('Dashboard update failed:', error);
    }
    this.updateTimer = setTimeout(() => this.updateLoop(), this.updateInterval);
    }
    async fetchDashboardData() {
    const endDate = new Date().toISOString().split('T')[0];
    const startDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
    const [accountUsage, dailyUsage, storageUsage] = await Promise.all([
    fetch(`/v1/api/${this.orgId}/analytics/usage?periodDays=7`),
    fetch(`/v1/api/${this.orgId}/analytics/daily?startDate=${startDate}&endDate=${endDate}`),
    fetch(`/v1/api/${this.orgId}/analytics/storage`)
    ]);
    return {
    timestamp: new Date().toISOString(),
    accountUsage: accountUsage.body.usage[0],
    dailyUsage: dailyUsage.body.dailyUsage,
    storageUsage: storageUsage.body.storage
    };
    }
    }

    Error Handling & Resilience

    Retry Logic

    // Implement retry logic for analytics requests
    const fetchWithRetry = async (fetchFn, maxRetries = 3, delay = 1000) => {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
    return await fetchFn();
    } catch (error) {
    if (attempt === maxRetries) {
    throw error;
    }
    // Exponential backoff
    const waitTime = delay * Math.pow(2, attempt - 1);
    await new Promise(resolve => setTimeout(resolve, waitTime));
    }
    }
    };
    // Usage example
    const getAccountUsageWithRetry = (orgId, periodDays) => {
    return fetchWithRetry(() => fetch(`/v1/api/${orgId}/analytics/usage?periodDays=${periodDays}`));
    };

    Error Monitoring

    // Monitor analytics API health
    class AnalyticsHealthMonitor {
    constructor(orgId) {
    this.orgId = orgId;
    this.healthStatus = 'unknown';
    this.lastCheck = null;
    this.errorCount = 0;
    }
    async checkHealth() {
    try {
    const startTime = Date.now();
    await fetch(`/v1/api/${this.orgId}/analytics/usage?periodDays=1`);
    const responseTime = Date.now() - startTime;
    this.healthStatus = 'healthy';
    this.errorCount = 0;
    this.lastCheck = new Date();
    return {
    status: 'healthy',
    responseTime: responseTime,
    lastCheck: this.lastCheck
    };
    } catch (error) {
    this.errorCount++;
    this.healthStatus = this.errorCount > 3 ? 'unhealthy' : 'degraded';
    return {
    status: this.healthStatus,
    error: error.message,
    errorCount: this.errorCount,
    lastCheck: this.lastCheck
    };
    }
    }
    }

    Error Handling

    Common Errors

    Status CodeErrorDescriptionSolution
    400Bad RequestInvalid date formatUse YYYY-MM-DD format for dates
    401UnauthorizedInvalid API keyVerify API key is correct and active
    403ForbiddenVideo doesn’t belong to organizationEnsure video belongs to your organization
    404Not FoundVideo not foundVerify video public ID is correct
    422Unprocessable EntityInvalid date rangeEnsure start date is before end date
    429Too Many RequestsRate limit exceededWait before making more requests

    Error Response Example

    {
    "title": "Bad Request",
    "status": 400,
    "detail": "Invalid date format",
    "errors": [
    {
    "message": "Invalid start date format, use YYYY-MM-DD",
    "location": "query.startDate",
    "value": "2024/01/01"
    }
    ]
    }

    Rate Limits

    OperationLimitWindow
    Analytics queries100 requests1 hour
    Account usage50 requests1 hour
    Daily usage100 requests1 hour
    Storage analytics50 requests1 hour
    Video resolution200 requests1 hour
    Resolution distribution100 requests1 hour

    Tip

    Analytics data is updated in real-time. Use appropriate date ranges to avoid large response payloads and consider caching results for dashboard applications.

    Caution

    Large date ranges may result in significant response sizes. Consider pagination or shorter time periods for better performance.

    Integration Examples

    React Dashboard Component

    import React, { useState, useEffect } from 'react';
    const AnalyticsDashboard = ({ orgId }) => {
    const [analytics, setAnalytics] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    useEffect(() => {
    const fetchAnalytics = async () => {
    try {
    setLoading(true);
    const data = await buildAnalyticsDashboard(orgId, 30);
    setAnalytics(data);
    } catch (err) {
    setError(err.message);
    } finally {
    setLoading(false);
    }
    };
    fetchAnalytics();
    // Refresh every 5 minutes
    const interval = setInterval(fetchAnalytics, 5 * 60 * 1000);
    return () => clearInterval(interval);
    }, [orgId]);
    if (loading) return <div>Loading analytics...</div>;
    if (error) return <div>Error: {error}</div>;
    if (!analytics) return <div>No data available</div>;
    return (
    <div className="analytics-dashboard">
    <h2>Analytics Overview</h2>
    <div className="metrics-grid">
    <div className="metric-card">
    <h3>Total Videos</h3>
    <p>{analytics.overview.totalVideos}</p>
    </div>
    <div className="metric-card">
    <h3>Total Views</h3>
    <p>{analytics.overview.totalSegments}</p>
    </div>
    <div className="metric-card">
    <h3>Daily Average</h3>
    <p>{Math.round(analytics.trends.dailyAverage)}</p>
    </div>
    <div className="metric-card">
    <h3>Growth Rate</h3>
    <p>{analytics.trends.growthRate.toFixed(1)}%</p>
    </div>
    </div>
    <div className="resolution-breakdown">
    <h3>Resolution Distribution</h3>
    {analytics.resolutionBreakdown.map(res => (
    <div key={res.resolution} className="resolution-bar">
    <span>{res.resolution}p</span>
    <div className="bar" style={{ width: `${res.percentage}%` }}>
    {res.percentage.toFixed(1)}%
    </div>
    </div>
    ))}
    </div>
    </div>
    );
    };

    Python Analytics Script

    import requests
    import pandas as pd
    from datetime import datetime, timedelta
    import matplotlib.pyplot as plt
    class HesedVidAnalytics:
    def __init__(self, api_key, org_id):
    self.api_key = api_key
    self.org_id = org_id
    self.base_url = "https://api.hesedvid.com/v1/api"
    self.headers = {"X-Api-Key": api_key}
    def get_daily_usage(self, start_date, end_date):
    url = f"{self.base_url}/{self.org_id}/analytics/daily"
    params = {"startDate": start_date, "endDate": end_date}
    response = requests.get(url, headers=self.headers, params=params)
    response.raise_for_status()
    return response.json()["body"]["dailyUsage"]
    def analyze_trends(self, days=30):
    end_date = datetime.now().strftime("%Y-%m-%d")
    start_date = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
    daily_data = self.get_daily_usage(start_date, end_date)
    df = pd.DataFrame(daily_data)
    # Convert delivery date to datetime
    df['deliveryDate'] = pd.to_datetime(df['deliveryDate'])
    # Calculate trends
    trends = {
    'total_segments': df['segmentsServed'].sum(),
    'avg_daily_segments': df['segmentsServed'].mean(),
    'peak_day': df.loc[df['segmentsServed'].idxmax()]['deliveryDate'],
    'peak_segments': df['segmentsServed'].max(),
    'quality_distribution': {
    'hd': df['hdSegments'].sum(),
    'sd': df['sdSegments'].sum(),
    'ld': df['ldSegments'].sum()
    }
    }
    return trends, df
    def plot_usage_trends(self, df):
    plt.figure(figsize=(12, 6))
    plt.plot(df['deliveryDate'], df['segmentsServed'], marker='o')
    plt.title('Daily Video Usage Trends')
    plt.xlabel('Date')
    plt.ylabel('Segments Served')
    plt.xticks(rotation=45)
    plt.tight_layout()
    plt.show()
    def generate_report(self, days=30):
    trends, df = self.analyze_trends(days)
    print(f"HesedVid Analytics Report - Last {days} days")
    print("=" * 50)
    print(f"Total Segments Served: {trends['total_segments']:,}")
    print(f"Average Daily Segments: {trends['avg_daily_segments']:,.0f}")
    print(f"Peak Day: {trends['peak_day'].strftime('%Y-%m-%d')}")
    print(f"Peak Segments: {trends['peak_segments']:,}")
    print("\nQuality Distribution:")
    total_quality = sum(trends['quality_distribution'].values())
    for quality, segments in trends['quality_distribution'].items():
    percentage = (segments / total_quality) * 100
    print(f" {quality.upper()}: {segments:,} ({percentage:.1f}%)")
    return trends, df
    # Usage example
    analytics = HesedVidAnalytics("your_api_key", "your_org_id")
    trends, df = analytics.generate_report(30)
    analytics.plot_usage_trends(df)