{
"id": "dev.cartridge.analytics.getGameAnalytics",
"defs": {
"main": {
"type": "query",
"output": {
"schema": {
"type": "object",
"required": [
"slug",
"name",
"range",
"generatedAt",
"totals",
"discovery",
"attribution",
"engagement",
"conversions"
],
"properties": {
"name": {
"type": "string"
},
"slug": {
"type": "string"
},
"range": {
"type": "string",
"knownValues": [
"7d",
"30d",
"90d"
]
},
"totals": {
"ref": "#totals",
"type": "ref"
},
"discovery": {
"ref": "#discovery",
"type": "ref"
},
"engagement": {
"ref": "#engagement",
"type": "ref"
},
"attribution": {
"ref": "#attribution",
"type": "ref"
},
"conversions": {
"ref": "#conversions",
"type": "ref"
},
"generatedAt": {
"type": "string",
"format": "datetime"
}
}
},
"encoding": "application/json"
},
"parameters": {
"type": "params",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"maxLength": 512,
"description": "Slug of the game to report on. The caller must own it."
},
"range": {
"type": "string",
"default": "30d",
"description": "Reporting window ending today (UTC).",
"knownValues": [
"7d",
"30d",
"90d"
]
}
}
},
"description": "Owner-facing analytics for a single game. Authenticates the caller, verifies they own the game, then merges ClickHouse rollups with record-creation trends from HappyView. Fractional metrics use `unknown` because atproto lexicons have no float type."
},
"funnel": {
"type": "object",
"required": [
"impressions",
"pageviews",
"actions"
],
"properties": {
"actions": {
"type": "integer"
},
"pageviews": {
"type": "integer"
},
"impressions": {
"type": "integer"
}
}
},
"totals": {
"type": "object",
"required": [
"impressions",
"clicks",
"pageviews",
"ctr",
"avgDwellMs",
"medianDwellMs",
"avgScrollPct",
"avgDailyUniques"
],
"properties": {
"ctr": {
"type": "unknown",
"description": "clicks / impressions, 0..1 (float; unknown-typed)."
},
"clicks": {
"type": "integer"
},
"pageviews": {
"type": "integer"
},
"avgDwellMs": {
"type": "unknown",
"description": "Mean dwell time in milliseconds (float; unknown-typed)."
},
"impressions": {
"type": "integer"
},
"avgScrollPct": {
"type": "unknown",
"description": "Mean scroll depth percentage (float; unknown-typed)."
},
"medianDwellMs": {
"type": "unknown",
"description": "Median dwell time in milliseconds (float; unknown-typed)."
},
"avgDailyUniques": {
"type": "unknown",
"description": "Mean of per-day unique visitors across the range (float; unknown-typed)."
}
}
},
"discovery": {
"type": "object",
"required": [
"impressionsOverTime",
"feedBreakdown",
"topSearchTerms"
],
"properties": {
"feedBreakdown": {
"type": "array",
"items": {
"ref": "#namedCount",
"type": "ref"
}
},
"topSearchTerms": {
"type": "array",
"items": {
"ref": "#namedCount",
"type": "ref"
}
},
"impressionsOverTime": {
"type": "array",
"items": {
"ref": "#impressionPoint",
"type": "ref"
}
}
}
},
"engagement": {
"type": "object",
"required": [
"dwellDistribution",
"avgScrollPct",
"tabEngagement",
"dailyUniques"
],
"properties": {
"avgScrollPct": {
"type": "unknown",
"description": "Mean scroll depth percentage (float; unknown-typed)."
},
"dailyUniques": {
"type": "array",
"items": {
"ref": "#timeseriesPoint",
"type": "ref"
}
},
"tabEngagement": {
"type": "array",
"items": {
"ref": "#namedCount",
"type": "ref"
}
},
"dwellDistribution": {
"type": "array",
"items": {
"ref": "#namedCount",
"type": "ref"
}
}
}
},
"namedCount": {
"type": "object",
"required": [
"name",
"count"
],
"properties": {
"name": {
"type": "string"
},
"count": {
"type": "integer"
}
},
"description": "A labelled count, e.g. a feed name or search term with its total."
},
"attribution": {
"type": "object",
"required": [
"trafficSources",
"topReferrerFeeds",
"ctrBySurface"
],
"properties": {
"ctrBySurface": {
"type": "array",
"items": {
"ref": "#ctrBySurface",
"type": "ref"
}
},
"trafficSources": {
"type": "array",
"items": {
"ref": "#namedCount",
"type": "ref"
}
},
"topReferrerFeeds": {
"type": "array",
"items": {
"ref": "#namedCount",
"type": "ref"
}
}
}
},
"conversions": {
"type": "object",
"required": [
"recordTrends",
"funnel"
],
"properties": {
"funnel": {
"ref": "#funnel",
"type": "ref"
},
"recordTrends": {
"type": "array",
"items": {
"ref": "#recordTrendPoint",
"type": "ref"
}
}
}
},
"ctrBySurface": {
"type": "object",
"required": [
"surface",
"impressions",
"clicks",
"ctr"
],
"properties": {
"ctr": {
"type": "unknown",
"description": "clicks / impressions for this surface, 0..1 (float; unknown-typed)."
},
"clicks": {
"type": "integer"
},
"surface": {
"type": "string"
},
"impressions": {
"type": "integer"
}
}
},
"impressionPoint": {
"type": "object",
"required": [
"date",
"search",
"feed"
],
"properties": {
"date": {
"type": "string"
},
"feed": {
"type": "integer"
},
"search": {
"type": "integer"
}
},
"description": "Impressions on one day, split by discovery surface."
},
"timeseriesPoint": {
"type": "object",
"required": [
"date",
"value"
],
"properties": {
"date": {
"type": "string"
},
"value": {
"type": "integer"
}
},
"description": "A single day's value in a time series. `date` is 'YYYY-MM-DD' (UTC)."
},
"recordTrendPoint": {
"type": "object",
"required": [
"date",
"likes",
"reviews",
"listAdds"
],
"properties": {
"date": {
"type": "string"
},
"likes": {
"type": "integer"
},
"reviews": {
"type": "integer"
},
"listAdds": {
"type": "integer"
}
},
"description": "Authoritative record-creation counts for one day."
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1
}