Analytics

Tracking and authenticity

Watch a post's numbers for a set number of days, read every verified sample, and score whether its views look organic.

Regular analytics give you the latest numbers for every post. A tracking window goes further for the posts that matter: Pozy watches one post for a fixed period, keeps every reading it takes, does a final read when the period ends and tells you by webhook. On top of those readings it computes an authenticity score that flags views that do not look organic.

Typical uses are paying creators on verified views (see Creator campaigns), proving campaign results to a client, and spotting bought views before you reshare a post.

All numbers come from the platform through Pozy's own sync. Nothing is self-reported by the poster.

#Open a tracking window

Pass the Pozy postId, or an accountId plus the post's public url for a post published outside Pozy.

curl -X POST https://api.pozy.ai/v1/analytics/tracking \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "6650c1e2a3b4c5d6e7f80a22",
    "url": "https://www.tiktok.com/@acme/video/7431001122334455667",
    "trackingDays": 30
  }'
Response
{
  "window": {
    "id": "6650c1e2a3b4c5d6e7f81001",
    "postId": "6650c1e2a3b4c5d6e7f80e66",
    "accountId": "6650c1e2a3b4c5d6e7f80a22",
    "platform": "tiktok",
    "platformPostId": "7431001122334455667",
    "startsAt": "2026-10-30T09:00:00.000Z",
    "endsAt": "2026-11-29T09:00:00.000Z",
    "status": "open",
    "finalReadAt": null,
    "completionReason": null,
    "requestedBy": "api",
    "latest": null
  }
}

trackingDays defaults to 30 and goes up to 90. Opening a window on a post that already has one returns the existing window instead of a second one, so the call is safe to repeat.

#Follow the window

Status Meaning
open Collecting samples on every analytics sync
completing The period ended and the final read is running
completed Done. completionReason says how it ended
cancelled You cancelled it. There is no final read and no webhook
completionReason Meaning
final_read The final read succeeded. latest holds the closing numbers
unreachable The sync failed or no sample was ever taken
post_deleted The post disappeared from the platform
cancelled Cancelled with DELETE /v1/analytics/tracking/{windowId}

latest on a window holds the newest verified numbers: views, likes, comments, shares, saves and the time of that reading. List windows with GET /v1/analytics/tracking, filtered by accountId and status.

When the window ends, Pozy sends post.tracking_completed with the final numbers. Subscribe to it instead of polling the window.

#Read the samples

GET /v1/analytics/samples?postId=... returns every reading for a post, oldest first, one per analytics sync. Each sample holds the running totals the platform reported at that moment.

Field Notes
syncedAt When the reading was taken
views, likes, comments Running totals, including anything from before the window opened
shares, saves null (not zero) on platforms without that counter
watchSeconds, completionRate null when the platform gives no watch signal

Platform specifics worth knowing:

  • Threads: shares counts reposts and quotes, saves is null.
  • Pinterest: views are video views, so an image pin reads 0. shares is null.
  • Facebook: views come from the video or reel itself, saves is null, and only reels carry watch time.
  • X: views are impressions, because X's video view count is shared by every post that carries the same video.

Pass fromDate, toDate and limit (up to 2,000) to page through long histories.

#Authenticity score

GET /v1/posts/{postId}/authenticity returns a score from 0 to 100 computed from the verified samples. Higher looks more organic.

curl https://api.pozy.ai/v1/posts/6650c1e2a3b4c5d6e7f80e66/authenticity \
  -H "Authorization: Bearer $POZY_API_KEY"
Response
{
  "postId": "6650c1e2a3b4c5d6e7f80e66",
  "score": 62,
  "confidence": 0.8,
  "reasons": [{ "code": "late_block", "weight": 35 }],
  "version": "2026-10-29.1",
  "computedAt": "2026-10-30T03:00:00.000Z",
  "sampleCount": 14
}

Every reason subtracts its weight in points from 100:

Code What it means
late_block One large jump in views long after publishing, instead of gradual growth
flat_engagement Likes, comments and other counters are low for the number of views
view_follower_gap Views far above the follower count, with no shares to explain them
cap_seeking Views repeatedly land just under a payout cap
prior_flags Earlier posts from the same account were flagged
no_watch_signal No watch time or completion data. Weight 0; it only lowers confidence

confidence (0 to 1) tells you how much data backs the score: few samples or no watch data means low confidence. version names the scoring model, so you can tell when a score was computed under an older one.

Scores younger than 30 minutes are served as stored; older ones are recomputed on read. To review an account's posts in bulk, call GET /v1/analytics/authenticity?accountId=... with minScore or maxScore (for example maxScore=40 for the suspicious ones), plus from, to, limit and skip.

When the webhook fires

post.authenticity_changed fires when a tracked post's score crosses 40 in either direction while its window is open. It never fires for a post's first score. The payload carries the new and previous score, the confidence and the reasons.

#Treat the score as a signal

The score is evidence, not a verdict. Use it to hold a payout for review or to ask a creator a question, and read the reasons before you act. A small account with a genuinely viral post can trip view_follower_gap on day one.

#Endpoints

Endpoint What it does
POST /v1/analytics/tracking Open a tracking window
GET /v1/analytics/tracking List tracking windows
GET /v1/analytics/tracking/{windowId} Get a tracking window
DELETE /v1/analytics/tracking/{windowId} Cancel a tracking window
GET /v1/analytics/samples Get post samples
GET /v1/posts/{postId}/authenticity Get a post's authenticity score
GET /v1/analytics/authenticity List authenticity scores

#Webhook events

Event When it fires
post.tracking_completed Post tracking completed.
post.authenticity_changed Post authenticity changed.