
Project-level aggregate endpoints for leaderboards, heatmaps, histograms, scatter charts, and membership overlap.
The aggregate analytics endpoints return pre-computed project-level summaries that power the Analytics section (Video, Creator, and Campaign sub-tabs). They differ from the unified /api/v1/analytics endpoint in that they aggregate across all entities in a project rather than for a single entity.
All endpoints:
{ data, error, meta } envelopeproject_idBase path: /api/v1/analytics/aggregate
/aggregate/video-leaderboardReturns a ranked list of tracked videos in the project for the given date range.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
project_id | UUID | required | Project to query |
from | YYYY-MM-DD | — | Period start (inclusive) |
to | YYYY-MM-DD | — | Period end (inclusive) |
order | enum | view_count | Sort column: view_count, like_count, comment_count, share_count, save_count, posted_at |
limit | int |
Response data array — each item:
{
"video_id": "uuid",
"title": "string | null",
"thumbnail_url": "string | null",
"url": "string | null",
"view_count": 12345,
"like_count": 678,
"comment_count": 45,
"share_count": 12,
"save_count": 89,
"posted_at": "2026-04-01T12:00:00Z"
total_count is the total matching rows (before limit/offset).
/aggregate/posting-heatmapReturns a DOW × hour grid of post counts and average view counts, bucketed in the org's timezone.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
project_id | UUID | required | |
from | YYYY-MM-DD | required | |
to | YYYY-MM-DD | required | |
tz | IANA string | org timezone | Override timezone |
Response data array — each item:
{ "dow": 1, "hour": 14, "post_count": 5, "avg_views": 12430.50 }dow: 0=Sunday … 6=Saturday. Only cells with at least one post are returned; missing cells = 0.
/aggregate/view-distributionReturns a histogram of video view counts with percentile markers.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
project_id | UUID | required | |
from | YYYY-MM-DD | required | |
to | YYYY-MM-DD | required | |
bin_count | int | 20 | Number of histogram bins (5–50) |
Response data object:
{
"total": 87,
"min": 100,
"max": 5200000,
"p50": 12000,
"p75": 48000,
"p90": 210000,
"p99": 1800000,
"bins": [
{ "bin_index": 0, "bin_lower": 100, "bin_upper"
/aggregate/outliersReturns videos that outperform their creator's median view count by at least min_x_multiple, sorted by x_multiple descending.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
project_id | UUID | required | |
from | YYYY-MM-DD | — | Optional period filter |
to | YYYY-MM-DD | — | Optional period filter |
min_x_multiple | number | 1.5 | Minimum outperformance ratio |
limit | int |
Response data array — each item includes video_id, creator_id, view_count, median_views, x_multiple, posted_at, plus enriched title, thumbnail_url, url, tiktok_handle, display_name, avatar_url.
/aggregate/creator-leaderboardReturns creators in the project ranked by views in the period, with follower delta and engagement metrics.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
project_id | UUID | required | |
from | YYYY-MM-DD | — | |
to | YYYY-MM-DD | — | |
limit | int | 100 | Max rows (1–200) |
offset | int | 0 |
Response data array — each item:
{
"creator_id": "uuid",
"tiktok_handle": "string",
"display_name": "string | null",
"avatar_url": "string | null",
"current_followers": 45000,
"follower_delta": 1200,
"total_views": 980000,
"posts_in_period": 14,
"posts_per_week": 1.0,
"engagement_rate":
follower_delta = follower count at end of period minus start of period (from creator_stats_history). Zero when no snapshots in range.
engagement_rate = (likes + comments + shares) ÷ views × 100 for videos posted in the period.
/aggregate/posting-consistencyReturns per-creator, per-day post counts for building a punch-card matrix.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
project_id | UUID | required | |
from | YYYY-MM-DD | required | |
to | YYYY-MM-DD | required | |
tz | IANA string | org timezone |
Response data array — sparse (only days with posts):
{ "creator_id": "uuid", "day": "2026-04-05", "post_count": 2 }/aggregate/creator-scatterReturns per-creator (follower change, engagement rate) pairs for scatter chart rendering.
Query parameters: project_id, optional from/to.
Response data array:
{
"creator_id": "uuid",
"tiktok_handle": "string",
"follower_delta": 1200,
"engagement_rate": 3.45,
"posts_count": 14
}Only creators with at least one tracked post in the period are included.
/aggregate/goal-complianceReturns a project-wide roll-up of creator goal statuses. Capped at 50 creators with active goals.
Query parameters: project_id.
Response data object:
{
"on_track": 3,
"at_risk": 1,
"missed": 1,
"total_goals": 5,
"creators_with_goals": 5
}on_track includes completed statuses. at_risk includes behind_pace. The cap of 50 matches the existing dashboard behavior.
/aggregate/campaign-leaderboardReturns campaigns in the project sorted by views, with prior-period delta comparison.
Query parameters: project_id, from, to (all required).
Response data array:
{
"campaign_id": "uuid",
"name": "string",
"total_views": 1200000,
"total_likes": 45000,
"video_count": 32,
"creator_count": 5,
"preview_thumbnail_url": "string | null",
"prior_views": 980000,
"views_delta": 220000,
"views_delta_pct":
Prior period is automatically computed as the same duration immediately preceding from.
/aggregate/member-overlapReturns entities (creators or videos) that appear as direct members in campaigns, with the list of campaigns each belongs to. Capped at 50 rows.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
project_id | UUID | required | |
dimension | creator | video | creator | Entity type to list |
Response data array:
{
"entity_id": "uuid",
"entity_label": "tiktok_handle or title",
"entity_avatar": "string | null",
"campaign_ids": ["uuid", "uuid"],
"campaign_names": ["Campaign A", "Campaign B"],
"campaign_count": 2
}Only direct membership (via campaign_items) is considered, not recursive resolution through nested campaigns.
| 100 |
| Max rows (1–200) |
offset | int | 0 | Pagination offset |
| 50 |
| Max rows (1–100) |