PRIV ProtocolPRIV Docs
API Reference

Analytics API

Query and analyze your tracking data with the PRIV Protocol Analytics API.

Query and analyze your tracking data with filtering and aggregation.

Query Analytics

GET/api/v1/analytics

Retrieve aggregated analytics data with filtering by date range, event type, and grouping options.

Query Parameters

ParameterTypeRequiredDescription
start_datestringYesStart date (YYYY-MM-DD format)
end_datestringYesEnd date (YYYY-MM-DD format)
event_typestringNoFilter by event type: track, page_view, identify, or all
group_bystringNoGroup results by: event_type or page

Response

{
  "success": true,
  "data": {
    "total_events": 15000,
    "unique_users": 2500,
    "events_by_type": {
      "track": 8000,
      "page_view": 6500,
      "identify": 500
    },
    "events_by_day": [
      { "date": "2024-01-01", "count": 500 },
      { "date": "2024-01-02", "count": 750 },
      { "date": "2024-01-03", "count": 620 }
    ],
    "top_pages": [
      { "page_url": "https://example.com/", "views": 3200 },
      { "page_url": "https://example.com/pricing", "views": 1800 },
      { "page_url": "https://example.com/features", "views": 1200 }
    ]
  }
}

Response Fields

FieldTypeDescription
total_eventsnumberTotal events in the date range
unique_usersnumberCount of distinct users (by user_id or anonymous_id)
events_by_typeobjectEvent counts grouped by event type
events_by_dayarrayDaily event counts sorted chronologically
top_pagesarrayTop 10 pages by view count (page_view events only)

Grouping Behavior

When using the group_by parameter:

  • group_by=event_type: Omits the events_by_day array, focuses on type breakdown
  • group_by=page: Omits the events_by_type object, focuses on page-level metrics

Example: Basic Query

curl "https://api.priv.io/v1/analytics?start_date=2024-01-01&end_date=2024-01-31" \
  -H "Authorization: Bearer pk_live_xxx"

Example: Filter by Event Type

curl "https://api.priv.io/v1/analytics?start_date=2024-01-01&end_date=2024-01-31&event_type=track" \
  -H "Authorization: Bearer pk_live_xxx"

Example: Group by Page

curl "https://api.priv.io/v1/analytics?start_date=2024-01-01&end_date=2024-01-31&group_by=page" \
  -H "Authorization: Bearer pk_live_xxx"

Example: JavaScript

async function getAnalytics(startDate: string, endDate: string) {
  const params = new URLSearchParams({
    start_date: startDate,
    end_date: endDate,
  });

  const response = await fetch(
    `https://api.priv.io/v1/analytics?${params}`,
    {
      headers: {
        'Authorization': 'Bearer pk_live_xxx',
      },
    }
  );

  const data = await response.json();

  if (data.success) {
    console.log(`Total events: ${data.data.total_events}`);
    console.log(`Unique users: ${data.data.unique_users}`);

    // Process daily data
    for (const day of data.data.events_by_day) {
      console.log(`${day.date}: ${day.count} events`);
    }
  }

  return data;
}

// Get last 30 days
const endDate = new Date().toISOString().split('T')[0];
const startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
  .toISOString()
  .split('T')[0];

getAnalytics(startDate, endDate);

Use Cases

Dashboard Metrics

Fetch key metrics for a dashboard overview:

const analytics = await getAnalytics('2024-01-01', '2024-01-31');

const metrics = {
  totalEvents: analytics.data.total_events,
  uniqueUsers: analytics.data.unique_users,
  avgEventsPerUser: Math.round(
    analytics.data.total_events / analytics.data.unique_users
  ),
  topEventType: Object.entries(analytics.data.events_by_type)
    .sort(([, a], [, b]) => b - a)[0][0],
};

Trend Analysis

Analyze event trends over time:

const dailyData = analytics.data.events_by_day;

// Calculate growth rate
const firstWeek = dailyData.slice(0, 7).reduce((sum, d) => sum + d.count, 0);
const lastWeek = dailyData.slice(-7).reduce((sum, d) => sum + d.count, 0);
const growthRate = ((lastWeek - firstWeek) / firstWeek) * 100;

console.log(`Week-over-week growth: ${growthRate.toFixed(1)}%`);

Page Performance

Identify your most popular pages:

const response = await fetch(
  'https://api.priv.io/v1/analytics?start_date=2024-01-01&end_date=2024-01-31&group_by=page',
  { headers: { 'Authorization': 'Bearer pk_live_xxx' } }
);

const data = await response.json();
const topPages = data.data.top_pages;

console.log('Top 5 pages:');
topPages.slice(0, 5).forEach((page, i) => {
  console.log(`${i + 1}. ${page.page_url}: ${page.views} views`);
});

Best Practices

Date Range Selection

  • Use reasonable date ranges (30-90 days) for optimal performance
  • For real-time dashboards, query the last 24 hours

Caching

Cache analytics responses on your server to reduce API calls:

import { cache } from 'react';

// Cache for 5 minutes
export const getAnalytics = cache(async (startDate: string, endDate: string) => {
  const response = await fetch(
    `https://api.priv.io/v1/analytics?start_date=${startDate}&end_date=${endDate}`,
    {
      headers: { 'Authorization': `Bearer ${process.env.PRIV_API_KEY}` },
      next: { revalidate: 300 }, // 5 minutes
    }
  );
  return response.json();
});

Error Handling

Always handle potential errors:

try {
  const response = await fetch(analyticsUrl, { headers });

  if (!response.ok) {
    if (response.status === 429) {
      // Rate limited - wait and retry
      await new Promise(resolve => setTimeout(resolve, 1000));
      return getAnalytics(startDate, endDate);
    }
    throw new Error(`Analytics API error: ${response.status}`);
  }

  return await response.json();
} catch (error) {
  console.error('Failed to fetch analytics:', error);
  return null;
}

For more advanced analytics queries including cohort analysis and funnel tracking, use the PRIV Dashboard or contact us about Enterprise features.