Analytics
Retrieve performance metrics for your delivered accounts, including follower counts, views, engagement rates, and per-video statistics. Analytics data is sourced from platform scraping and can be refreshed on demand.
Get Account Analytics
GET /accounts/:id/analytics
Returns aggregated analytics for an account.
curl -X GET https://app.tokportal.com/api/ext/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c/analytics \
-H "X-API-Key: tok_live_xxx"
Response:
{
"data": {
"account_id": "9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c",
"followers_count": 12400,
"following_count": 340,
"total_videos_tracked": 15,
"total_views": 580000,
"total_likes": 42000,
"total_comments": 3200,
"total_shares": 8500,
"total_bookmarks": 4100,
"average_engagement_rate": 7.24,
"average_video_views": 38667,
"weekly_post_average": 2.5,
"scraped_at": "2026-02-10T09:15:00Z"
}
}
Account Analytics Fields
| Field | Type | Description |
|---|---|---|
account_id | string (UUID) | The account identifier. |
followers_count | integer | Current follower count. |
following_count | integer | Number of accounts followed. |
total_videos_tracked | integer | Number of videos being tracked. |
total_views | integer | Sum of views across all tracked videos. |
total_likes | integer | Sum of likes across all tracked videos. |
total_comments | integer | Sum of comments across all tracked videos. |
total_shares | integer | Sum of shares across all tracked videos. |
total_bookmarks | integer | Sum of bookmarks across all tracked videos. |
average_engagement_rate | float | Overall engagement rate (percentage). |
average_video_views | float | Average views per video. |
weekly_post_average | float | Average posts per week. |
scraped_at | string | ISO 8601 timestamp of the most recent data scrape. |
No Analytics Available
If no analytics data exists for the account, the API returns an error (not an empty 200):
{
"error": {
"code": "ANALYTICS_NOT_FOUND",
"message": "No analytics data found for this account. Try calling the refresh endpoint first."
}
}
Hint: Call the refresh endpoint first to trigger a scrape, then retry after a few moments.
Refresh Analytics
POST /accounts/:id/analytics/refresh
Triggers a fresh scrape of the account's analytics from the platform. Refreshes are subject to a cooldown per account and a monthly quota across your organization.
curl -X POST https://app.tokportal.com/api/ext/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c/analytics/refresh \
-H "X-API-Key: tok_live_xxx"
Response:
{
"data": {
"account_id": "9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c",
"status": "scrape_queued",
"note": "Analytics scrape has been queued. Data will be available shortly."
}
}
The status field will be one of:
| Status | Description |
|---|---|
scrape_queued | A new scrape has been queued. |
refreshed | Data was already fresh and has been returned. |
Error — cooldown active:
{
"error": {
"code": "ANALYTICS_COOLDOWN",
"message": "Analytics were refreshed recently. Please wait before refreshing again.",
"details": {
"next_refresh_at": "2026-02-12T09:15:00Z",
"hours_remaining": 12
}
}
}
Error — monthly quota exceeded:
{
"error": {
"code": "ANALYTICS_QUOTA_EXCEEDED",
"message": "Monthly analytics refresh quota reached.",
"details": {
"monthly_quota": {
"limit": 500,
"used": 500
}
}
}
}
Check Refresh Availability
GET /accounts/:id/analytics/can-refresh
Check whether an analytics refresh is currently available for this account without triggering one.
curl -X GET https://app.tokportal.com/api/ext/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c/analytics/can-refresh \
-H "X-API-Key: tok_live_xxx"
Response — available:
{
"data": {
"account_id": "9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c",
"can_refresh": true,
"next_refresh_at": null,
"hours_remaining": 0,
"monthly_quota": {
"limit": 500,
"used": 123
}
}
}
Response — cooldown active:
{
"data": {
"account_id": "9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c",
"can_refresh": false,
"next_refresh_at": "2026-02-12T09:15:00Z",
"hours_remaining": 12,
"monthly_quota": {
"limit": 500,
"used": 124
}
}
}
Can-Refresh Fields
| Field | Type | Description |
|---|---|---|
account_id | string (UUID) | The account identifier. |
can_refresh | boolean | Whether a refresh is currently allowed. |
next_refresh_at | string | null | ISO 8601 timestamp of when the next refresh will be available. null if available now. |
hours_remaining | number | Hours until the next refresh is available. 0 if available now. |
monthly_quota.limit | integer | Total monthly refresh quota. |
monthly_quota.used | integer | Refreshes used this month. |
Get Single Video Analytics
GET /videos/:id/analytics
Returns analytics for a single video by its analytics record ID. This is a convenience endpoint — the data comes from the same scrape triggered via POST /accounts/:id/analytics/refresh.
Note: The
:idhere is theidfield from the video analytics records (returned byGET /accounts/:id/analytics/videos), not a platform video ID.
curl -X GET https://app.tokportal.com/api/ext/videos/va_001/analytics \
-H "X-API-Key: tok_live_xxx"
Response:
{
"data": {
"id": "va_001",
"video_id": "vid_abc123",
"url": "https://www.tiktok.com/@coolcreator99/video/7123456789",
"description": "Unboxing the new product line",
"thumbnail_url": "https://pub-xxx.r2.dev/thumbnails/thumb_001.jpg",
"upload_date": "2026-01-20T12:00:00Z",
"duration_seconds": 45,
"views": 145000,
"likes": 9800,
"comments": 420,
"shares": 1200,
"bookmarks": 890,
"engagement_rate": 7.87,
"platform": "tiktok",
"content_type": "video",
"scraped_at": "2026-02-10T09:15:00Z"
}
}
Error — video not found:
{
"error": {
"code": "VIDEO_ANALYTICS_NOT_FOUND",
"message": "No analytics data found for this video ID."
}
}
Tip: To get a video's analytics ID, first list all videos for the account with
GET /accounts/:id/analytics/videos, then use theidfield from the response.
Get Video-Level Analytics (by Account)
GET /accounts/:id/analytics/videos
Returns per-video performance metrics for all videos published on the account. Results are paginated.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
sort_by | string | upload_date | Sort field: views, likes, engagement_rate, upload_date. |
sort_order | string | desc | asc or desc. |
page | integer | 1 | Page number. |
per_page | integer | 20 | Results per page (max: 100). |
curl -X GET "https://app.tokportal.com/api/ext/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c/analytics/videos?sort_by=views&sort_order=desc&page=1&per_page=10" \
-H "X-API-Key: tok_live_xxx"
Response:
{
"data": [
{
"id": "va_001",
"video_id": "vid_abc123",
"url": "https://www.tiktok.com/@coolcreator99/video/7123456789",
"description": "Unboxing the new product line",
"thumbnail_url": "https://pub-xxx.r2.dev/thumbnails/thumb_001.jpg",
"upload_date": "2026-01-20T12:00:00Z",
"duration_seconds": 45,
"views": 145000,
"likes": 9800,
"comments": 420,
"shares": 1200,
"bookmarks": 890,
"engagement_rate": 7.87,
"platform": "tiktok",
"content_type": "video",
"scraped_at": "2026-02-10T09:15:00Z"
},
{
"id": "va_002",
"video_id": "vid_def456",
"url": "https://www.tiktok.com/@coolcreator99/video/7234567890",
"description": "Day in my life using the product",
"thumbnail_url": "https://pub-xxx.r2.dev/thumbnails/thumb_002.jpg",
"upload_date": "2026-01-25T14:00:00Z",
"duration_seconds": 60,
"views": 89000,
"likes": 6200,
"comments": 310,
"shares": 780,
"bookmarks": 540,
"engagement_rate": 8.19,
"platform": "tiktok",
"content_type": "video",
"scraped_at": "2026-02-10T09:15:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 10,
"total": 15,
"total_pages": 2
}
}
Video Analytics Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique analytics record ID. |
video_id | string | The TokPortal video ID. |
url | string | Direct URL to the video on the platform. |
description | string | Video caption / description. |
thumbnail_url | string | URL to the video thumbnail. |
upload_date | string | ISO 8601 timestamp of when the video was uploaded / published. |
duration_seconds | integer | Video duration in seconds. |
views | integer | Total view count. |
likes | integer | Total like count. |
comments | integer | Total comment count. |
shares | integer | Total share count. |
bookmarks | integer | Total bookmark / save count. |
engagement_rate | float | Engagement rate: (likes + comments + shares + bookmarks) / views * 100. |
platform | string | Platform the video was published on. |
content_type | string | Content type (e.g., video, carousel). |
scraped_at | string | ISO 8601 timestamp of when the data was last scraped. |