Analytics API – Analytics v2
Retrieve TokPortal Analytics v2 data via API, including connected BundleSocial analytics, public fallback metrics, post intelligence, comments, exports, and raw provider payloads.
Analytics
TokPortal Analytics v2 exposes account, portfolio, post-level, time-series, comment, export, and raw provider analytics for delivered accounts.
Data is owner-scoped by API key and can come from multiple sources:
- connected account analytics when the account is connected through TokPortal's supported social integrations
- public fallback analytics when connected analytics are unavailable
- TokPortal historical cache and post metadata
All examples use the public API base URL:
https://app.tokportal.com/api/ext
Access Levels
Analytics responses are plan-aware:
| Level | Access |
|---|---|
| Starter | Basic totals and limited post/account visibility. |
| Creator | Core performance, time series, CSV export, and web reports. |
| Marketer/Farmer+ | Full analytics, raw provider payloads, demographics, comments, and advanced post intelligence where available. |
Every Analytics v2 response includes contract metadata or the X-TokPortal-Analytics-Contract header.
Portfolio Dashboard
GET /analytics
Returns the Analytics v2 dashboard for the API key owner: totals, accounts, top posts, audience summary, facets, access metadata, and the current data contract.
Optional filters:
| Query | Description |
|---|---|
workspace | Workspace ID. |
platform | Repeatable platform filter, e.g. platform=tiktok&platform=instagram. |
country | Repeatable country filter. |
account | Repeatable saved account ID filter. |
from | Start date or ISO timestamp. |
to | End date or ISO timestamp. |
curl -X GET "https://app.tokportal.com/api/ext/analytics?platform=tiktok" \
-H "X-API-Key: sk_xxx"
Response shape:
{
"tier": "full",
"access": {
"level": "full",
"planTier": "farmer",
"reason": "full_access"
},
"totals": {
"account_count": 99,
"views": 648356,
"impressions": 619676,
"tracked_posts": 4876,
"post_views": 2181245,
"avg_fyp_pct": null
},
"accounts": [],
"top_posts": [],
"audience": {
"age": [],
"gender": [],
"country": [],
"city": [],
"unit": "unknown"
},
"contract": {
"name": "tokportal.analytics.v2",
"version": "2026-05-04.1",
"accessLevel": "full"
}
}
Account Drilldown
GET /analytics/accounts/:id
Returns one account's Analytics v2 drilldown: account header, latest account snapshot, posts, daily series, demographics, derived stats, intelligence, and contract metadata.
curl -X GET https://app.tokportal.com/api/ext/analytics/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c \
-H "X-API-Key: sk_xxx"
Important fields:
| Field | Description |
|---|---|
latest | Latest account-level metrics. |
posts | Tracked post list with latest post snapshot metrics. |
daily_series | Stored daily points for charts. |
demographics | Parsed account or post audience demographics when available. |
derived_stats | Derived lifetime stats from tracked posts. |
intelligence | Cached content/account intelligence when available. |
Time Series
GET /analytics/series
Returns stored chart points. This endpoint does not live-refresh data.
Query parameters:
| Query | Description |
|---|---|
metric | views, likes, comments, shares, or followers. Default: views. |
granularity | day or week. Default: day. |
mode | cumulative, gained, or snapshot. Default: cumulative. |
account | Repeatable saved account ID. |
from | Start date or ISO timestamp. |
to | End date or ISO timestamp. |
curl -X GET "https://app.tokportal.com/api/ext/analytics/series?metric=views&granularity=day&mode=cumulative&account=9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c&from=2026-05-01&to=2026-05-10" \
-H "X-API-Key: sk_xxx"
Account Compatibility Endpoint
GET /accounts/:id/analytics
This older public path now uses Analytics v2. It keeps legacy-shaped fields for existing integrations and also exposes the full v2 payload under data.analytics_v2.
curl -X GET https://app.tokportal.com/api/ext/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c/analytics \
-H "X-API-Key: sk_xxx"
Response:
{
"data": {
"account_id": "9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c",
"followers_count": 12400,
"total_videos_tracked": 48,
"total_views": 580000,
"total_likes": 42000,
"average_engagement_rate": 7.24,
"analytics_version": "v2",
"analytics_v2": {
"account": {},
"latest": {},
"posts": []
}
}
}
Post Analytics by Account
GET /accounts/:id/analytics/videos
Returns Analytics v2 tracked posts in the older paginated list shape.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
sort_by | string | upload_date | views, likes, engagement_rate, or upload_date. |
sort_order | string | desc | asc or desc. |
page | integer | 1 | Page number. |
per_page | integer | 50 | 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" \
-H "X-API-Key: sk_xxx"
Rows include tracked_post_id, analytics_version: "v2", and the full v2 row under analytics_v2.
Single Post Analytics
GET /videos/:id/analytics
Pass an Analytics v2 tracked_post_id when available. For older integrations, this endpoint can still fall back to a legacy video_analytics.id.
curl -X GET https://app.tokportal.com/api/ext/videos/8c2d0f2e-.../analytics \
-H "X-API-Key: sk_xxx"
Response fields include normalized post metrics, analytics_version, and for v2 records an analytics_v2 object with the tracked post and latest snapshot.
Comment Pulse
GET /analytics/comments
Returns a dashboard-level comment pulse across top posts in the selected scope. Full-tier only. The endpoint serves cached comments and cached semantic analysis, hydrating comments only when the cache is empty or stale.
Query parameters:
| Parameter | Description |
|---|---|
limit | Total comments to return, 1..40. Default: 24. |
postLimit | Number of top posts to sample, 1..10. Default: 6. |
commentsPerPost | Comments to hydrate per post when needed, 1..12. Default: 8. |
post | Repeatable tracked post ID to force a specific sample. |
workspace | Workspace ID. |
account | Repeatable saved account ID. |
platform | Repeatable platform filter. |
country | Repeatable country filter. |
from | Start date or ISO timestamp. |
to | End date or ISO timestamp. |
curl -X GET "https://app.tokportal.com/api/ext/analytics/comments?platform=tiktok&limit=24" \
-H "X-API-Key: sk_xxx"
The response echoes the scope it actually sampled under applied_filters. When you pass post, it forces that specific sample and overrides the dashboard filters (workspace, account, platform, country, from, to) — the response states when that happened, so read applied_filters instead of assuming your filter set was honoured.
Post Comments
GET /analytics/accounts/:id/comments
Returns cached comments for one tracked post. Full-tier only.
Query parameters:
| Parameter | Description |
|---|---|
trackedPostId | Analytics v2 tracked post ID. |
postId | Connected provider post ID fallback. |
limit | Number of comments, max 50. |
curl -X GET "https://app.tokportal.com/api/ext/analytics/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c/comments?trackedPostId=8c2d0f2e-..." \
-H "X-API-Key: sk_xxx"
CSV Export
GET /analytics/export/videos
Returns text/csv for all videos in scope. The exported columns are plan-aware.
Optional filters:
| Query | Description |
|---|---|
workspace | Workspace ID. |
account | Repeatable saved account ID. |
platform | Repeatable platform filter. |
country | Repeatable country filter. |
q | Search text over account, post text, URLs, and platform IDs. |
from | Start date or ISO timestamp. |
to | End date or ISO timestamp. |
curl -X GET "https://app.tokportal.com/api/ext/analytics/export/videos?account=9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c" \
-H "X-API-Key: sk_xxx"
HTML Reports
POST /analytics/export/reports
POST /analytics/export/reports/html
POST /analytics/export/reports creates a shareable Analytics v2 web report; the response includes a report token and public url. POST /analytics/export/reports/html takes the same body and returns a standalone downloadable HTML document. Creator and full-tier plans can generate reports. Custom branding is available for full/farmer plans.
Do not send Idempotency-Key to analytics report creation or HTML report export. These responses can contain a private report token or artifact, so TokPortal rejects the header before execution with 400 IDEMPOTENCY_KEY_NOT_ALLOWED_FOR_SENSITIVE_RESPONSE. If the request outcome is uncertain, list or reconcile the workspace's reports before creating another one. Never include report tokens in support logs.
curl -X POST https://app.tokportal.com/api/ext/analytics/export/reports \
-H "X-API-Key: sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"title": "April performance report",
"template": "executive",
"accountIds": ["9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c"],
"from": "2026-04-01",
"to": "2026-04-30"
}'
Request Body
| Field | Type | Description |
|---|---|---|
title | string | null | Report title. Max 120 characters. |
template | string | null | Layout: executive, agency, creator, minimal, growth, or board. |
brandName | string | null | White-label brand name. Max 80 characters. |
brandAccent | string | null | White-label accent colour, #rrggbb. |
accountIds | string[] | Saved account IDs to include. |
workspaceId | string | null | Workspace ID. |
platforms | string[] | Repeatable platform filter: tiktok, instagram. |
countries | string[] | Country codes. |
query | string | null | Free-text filter over accounts, post text, URLs, and platform IDs. Max 120 characters. |
from | string | null | Inclusive start date, YYYY-MM-DD. |
to | string | null | Inclusive end date, YYYY-MM-DD. |
Validation
Both routes validate this body rather than coercing it.
template— any value outside the six listed above is rejected withINVALID_FIELD. It is not replaced byexecutive.from/to— must beYYYY-MM-DD. A full ISO timestamp is accepted and truncated to its date; anything else is rejected withINVALID_FIELDrather than being treated as no filter at all, which used to widen the report to the account's entire history.frommust not be afterto.brandAccent—#rrggbb, or a#rgbshort form which is expanded to six digits. Named colours (red),rgb()notation, and 8-digit hex are rejected withINVALID_FIELD.- Lengths —
title120,brandName80,query120 characters.
Reading back what was applied
The settings that actually took effect are echoed, so you never have to inspect the rendered report to find out what the server used.
On POST /analytics/export/reports they come back on the JSON response under applied:
| Field | Description |
|---|---|
applied.template | The layout actually used. |
applied.brand_name | The brand name actually rendered. |
applied.brand_accent | The accent colour actually used. |
applied.filters.from | The start date actually applied. |
applied.filters.to | The end date actually applied. |
On POST /analytics/export/reports/html the same information comes back as X-TokPortal-Report-* response headers (for example X-TokPortal-Report-Template).
INFO: White-labelling is plan-gated
brandNameandbrandAccentare only applied on the full analytics tier with a Farmer plan. On every other plan the brand is reset to TokPortal, andapplied.brand_nametogether withcanBrandsay so — read them before promising a client a white-labelled document.
Raw Provider Payloads
Full-tier clients can retrieve stored raw provider payloads. These endpoints are useful when you need fields that TokPortal has stored but has not yet normalized into product UI fields.
Account Raw Snapshots
GET /analytics/accounts/:id/raw
Returns rows from account_analytics_snapshots, including normalized metrics and the stored raw JSON payload.
curl -X GET "https://app.tokportal.com/api/ext/analytics/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c/raw?source=bundle_social&limit=3" \
-H "X-API-Key: sk_xxx"
Post Raw Snapshots
GET /analytics/posts/:tracked_post_id/raw
Returns rows from post_analytics_snapshots, including normalized metrics, raw per-post analytics, and tracked post metadata.
curl -X GET "https://app.tokportal.com/api/ext/analytics/posts/8c2d0f2e-.../raw?source=bundle_social&limit=3" \
-H "X-API-Key: sk_xxx"
Raw endpoint filters:
| Query | Description |
|---|---|
source | bundle_social, apify, or manual. |
limit | 1..30, default 5. |
from | Start date or ISO timestamp. |
to | End date or ISO timestamp. |
Refresh Analytics
POST /accounts/:id/analytics/refresh
Triggers a targeted Analytics v2 refresh for one account. Background sync is the primary refresh path; use this endpoint for targeted repair or bootstrap flows.
Body:
{
"includePosts": true,
"includeComments": true,
"postLimit": 20,
"force": true,
"forcePosts": false,
"bootstrapPosts": false
}
WARNING:
includeCommentsrequiresforceComment hydration only takes effect whenforceistrue,includePostsis notfalse, and the workspace holds the full analytics tier. SendingincludeComments: truewithoutforceis refused for strict callers (MCP by default) and reported back inappliedfor the rest — it is no longer dropped without a word.
The server dedupes repeated requests:
| Source | Dedupe window |
|---|---|
| Connected analytics | 6 hours |
| Public fallback analytics | 24 hours |
Response:
{
"data": {
"account_id": "9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c",
"platform": "tiktok",
"status": "refreshed",
"analytics_version": "v2"
}
}
Check Refresh Availability
GET /accounts/:id/analytics/can-refresh
Returns whether targeted refresh is currently available for an account under the Analytics v2 dedupe policy.
curl -X GET https://app.tokportal.com/api/ext/accounts/9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c/analytics/can-refresh \
-H "X-API-Key: sk_xxx"
Response:
{
"data": {
"account_id": "9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c",
"can_refresh": true,
"next_refresh_at": null,
"hours_remaining": 0,
"source": "connected",
"analytics_version": "v2"
}
}
Contract
GET /analytics/contract
Returns the global Analytics v2 contract, the current API key's access payload, metric semantics, endpoint metadata, freshness targets, and redaction rules.