Analytics

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:

LevelAccess
StarterBasic totals and limited post/account visibility.
CreatorCore 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:

QueryDescription
workspaceWorkspace ID.
platformRepeatable platform filter, e.g. platform=tiktok&platform=instagram.
countryRepeatable country filter.
accountRepeatable saved account ID filter.
fromStart date or ISO timestamp.
toEnd 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:

FieldDescription
latestLatest account-level metrics.
postsTracked post list with latest post snapshot metrics.
daily_seriesStored daily points for charts.
demographicsParsed account or post audience demographics when available.
derived_statsDerived lifetime stats from tracked posts.
intelligenceCached content/account intelligence when available.

Time Series

GET /analytics/series

Returns stored chart points. This endpoint does not live-refresh data.

Query parameters:

QueryDescription
metricviews, likes, comments, shares, or followers. Default: views.
granularityday or week. Default: day.
modecumulative, gained, or snapshot. Default: cumulative.
accountRepeatable saved account ID.
fromStart date or ISO timestamp.
toEnd 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:

ParameterTypeDefaultDescription
sort_bystringupload_dateviews, likes, engagement_rate, or upload_date.
sort_orderstringdescasc or desc.
pageinteger1Page number.
per_pageinteger50Results 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:

ParameterDescription
limitTotal comments to return, 1..40. Default: 24.
postLimitNumber of top posts to sample, 1..10. Default: 6.
commentsPerPostComments to hydrate per post when needed, 1..12. Default: 8.
postRepeatable tracked post ID to force a specific sample.
workspaceWorkspace ID.
accountRepeatable saved account ID.
platformRepeatable platform filter.
countryRepeatable country filter.
fromStart date or ISO timestamp.
toEnd 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:

ParameterDescription
trackedPostIdAnalytics v2 tracked post ID.
postIdConnected provider post ID fallback.
limitNumber 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:

QueryDescription
workspaceWorkspace ID.
accountRepeatable saved account ID.
platformRepeatable platform filter.
countryRepeatable country filter.
qSearch text over account, post text, URLs, and platform IDs.
fromStart date or ISO timestamp.
toEnd 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

FieldTypeDescription
titlestring | nullReport title. Max 120 characters.
templatestring | nullLayout: executive, agency, creator, minimal, growth, or board.
brandNamestring | nullWhite-label brand name. Max 80 characters.
brandAccentstring | nullWhite-label accent colour, #rrggbb.
accountIdsstring[]Saved account IDs to include.
workspaceIdstring | nullWorkspace ID.
platformsstring[]Repeatable platform filter: tiktok, instagram.
countriesstring[]Country codes.
querystring | nullFree-text filter over accounts, post text, URLs, and platform IDs. Max 120 characters.
fromstring | nullInclusive start date, YYYY-MM-DD.
tostring | nullInclusive 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 with INVALID_FIELD. It is not replaced by executive.
  • from / to — must be YYYY-MM-DD. A full ISO timestamp is accepted and truncated to its date; anything else is rejected with INVALID_FIELD rather than being treated as no filter at all, which used to widen the report to the account's entire history. from must not be after to.
  • brandAccent#rrggbb, or a #rgb short form which is expanded to six digits. Named colours (red), rgb() notation, and 8-digit hex are rejected with INVALID_FIELD.
  • Lengthstitle 120, brandName 80, query 120 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:

FieldDescription
applied.templateThe layout actually used.
applied.brand_nameThe brand name actually rendered.
applied.brand_accentThe accent colour actually used.
applied.filters.fromThe start date actually applied.
applied.filters.toThe 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 brandName and brandAccent are only applied on the full analytics tier with a Farmer plan. On every other plan the brand is reset to TokPortal, and applied.brand_name together with canBrand say 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:

QueryDescription
sourcebundle_social, apify, or manual.
limit1..30, default 5.
fromStart date or ISO timestamp.
toEnd 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: includeComments requires force Comment hydration only takes effect when force is true, includePosts is not false, and the workspace holds the full analytics tier. Sending includeComments: true without force is refused for strict callers (MCP by default) and reported back in applied for the rest — it is no longer dropped without a word.

The server dedupes repeated requests:

SourceDedupe window
Connected analytics6 hours
Public fallback analytics24 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.