Skip to content

API: Analytics

Controller: admin-analytics.controllers.ts. Mount admin/analytics.

All endpoints require analytics:read.

Query: dateFrom, dateTo, market.

Response:

{
"dau": 12345,
"wau": 45678,
"mau": 98765,
"installsToday": 543,
"registrationsToday": 421,
"payingUsersToday": 89,
"arpu30d": 0.42,
"arppu30d": 5.10,
"retentionCohorts": [
{
"installWeek": "2026-06-01",
"cohortSize": 8765,
"d1": 0.48,
"d7": 0.24,
"d30": 0.12
}
]
}

Query: dateFrom, dateTo, rails[], countries[], kind.

Response:

{
"period": { "start": "...", "end": "..." },
"grossCents": 12345678,
"netCents": 10234567,
"refundsCents": 234567,
"byDay": [
{ "day": "2026-07-01", "gross": 45678, "net": 40234, "refunds": 1200 }
],
"byRail": [
{ "rail": "apple", "gross": 5000000, "net": 3500000 }
],
"byCountry": [
{ "country": "PH", "gross": 3000000, "net": 2600000 }
],
"arpu": 0.42,
"arppu": 5.10,
"refundRate": 0.019
}

Query: dateFrom, dateTo, market, genreSlug, sort, order, cursor, limit.

Response: paginated series list with per-series metrics (starts, completes, completion %, unlocks, coins burned, watch seconds).

GET /v1/admin/analytics/content/series/:id

Section titled “GET /v1/admin/analytics/content/series/:id”

Query: dateFrom, dateTo, market.

Response: per-episode drop-off curve + unlock conversion for the series.

{
"seriesId": "...",
"period": {},
"episodes": [
{
"episodeNumber": 1,
"starts": 10000,
"completes": 8500,
"paywallHits": 0,
"unlocks": 0,
"cliffhangerScore": 65
},
{
"episodeNumber": 4,
"starts": 3200,
"completes": 2100,
"paywallHits": 5000,
"unlocks": 850,
"cliffhangerScore": 80
}
]
}

Query: dateFrom, dateTo, market, installCohort.

Response:

{
"steps": [
{ "name": "preview_view", "count": 100000, "conversionFromPrev": 1.0, "conversionFromTop": 1.0 },
{ "name": "ep1_start", "count": 40000, "conversionFromPrev": 0.40, "conversionFromTop": 0.40 },
{ "name": "paywall_hit", "count": 12000, "conversionFromPrev": 0.30, "conversionFromTop": 0.12 },
{ "name": "unlock", "count": 1800, "conversionFromPrev": 0.15, "conversionFromTop": 0.018 },
{ "name": "repeat_unlock", "count": 1080, "conversionFromPrev": 0.60, "conversionFromTop": 0.0108 }
]
}

Permission: analytics:read (also system:write in some builds).

Manual trigger of the hourly rollup cron. Use for local testing; production relies on the cron.

  • All dashboards read from rollup tables (rollup_revenue_daily, rollup_series_daily, rollup_funnel_daily).
  • Rollups are built by the rollups-hourly cron (Cron jobs).
  • Retention cohorts are computed on the fly from analytics_event (30-day cap for drill-down).